:root {
  --bg0: #0b1020;
  --bg1: #141a2e;
  --ink: #eef1ff;
  --muted: #9aa3c7;
  --line: rgba(255,255,255,0.12);
  --gold: #f5c542;
  --warrior: #e07a3a;
  --mage: #8b5cf6;
  --ok: #34d399;
  --bad: #f87171;
  --hp: #22c55e;
  --hp-low: #ef4444;
  --monster: #f97316;
  --card: rgba(20, 26, 46, 0.92);
  --radius: 18px;
  --font: "Segoe UI", system-ui, -apple-system, sans-serif;
  --mono: ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace;
  --brick: #241a16;
  --brick-line: rgba(0,0,0,0.55);
}

*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background:
    radial-gradient(ellipse 80% 50% at 50% -10%, #2a1f55 0%, transparent 55%),
    radial-gradient(ellipse 50% 40% at 100% 100%, #1a3a2a 0%, transparent 45%),
    linear-gradient(180deg, var(--bg0), var(--bg1));
  min-height: 100vh;
  line-height: 1.45;
}

a { color: var(--gold); }
button, .btn {
  font: inherit;
  cursor: pointer;
  border: 0;
  border-radius: 999px;
  min-height: 44px;
  padding: 0.55rem 1.15rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.btn:disabled { opacity: .48; cursor: not-allowed; filter: saturate(.5); }

.asset-preload-overlay {
  position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center;
  padding: 1.25rem; background: radial-gradient(circle at 50% 30%, rgba(49,32,82,.92), rgba(6,8,14,.98) 68%);
  color: var(--ink); text-align: center;
}
.asset-preload-overlay.is-ready { display: none; }
.asset-preload-card { width: min(32rem, 100%); padding: clamp(1.5rem, 4vw, 2.5rem); border: 1px solid rgba(245,197,66,.42); border-radius: 20px; background: rgba(20,26,46,.94); box-shadow: 0 20px 70px rgba(0,0,0,.48), 0 0 36px rgba(139,92,246,.18); }
.asset-preload-kicker { color: var(--gold); font-size: .72rem; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; }
.asset-preload-card h1 { margin: .45rem 0 .55rem; font-size: clamp(1.35rem, 4vw, 2rem); }
.asset-preload-card p { margin: 0 0 1rem; color: var(--muted); }
.asset-preload-progress { height: 12px; margin: 1.25rem 0 .5rem; overflow: hidden; border: 1px solid var(--line); border-radius: 999px; background: rgba(0,0,0,.35); }
.asset-preload-progress span { display: block; width: 0; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--mage), var(--gold)); transition: width .18s ease; }
.asset-preload-card > strong { color: var(--gold); font-variant-numeric: tabular-nums; }
.asset-preload-error { margin-top: 1rem !important; color: var(--bad) !important; overflow-wrap: anywhere; }
.btn-primary { background: linear-gradient(135deg, var(--gold), #f59e0b); color: #1a1205; }
.btn-ghost { background: rgba(255,255,255,0.08); color: var(--ink); border: 1px solid var(--line); }
.btn-warrior { background: linear-gradient(135deg, #c2410c, var(--warrior)); color: #fff; width: 100%; }
.btn-mage { background: linear-gradient(135deg, #6d28d9, var(--mage)); color: #fff; width: 100%; }

.app { --fit-scale: 1; width: min(1920px, calc(100% - 1.25rem)); margin: 0 auto; padding: 1rem 0 2rem; }
/* Fit only the combat layout. Keep the chrome/header at its real CSS width
   so its picker and action buttons cannot collapse or overlap. */
.app.layout-combat .dungeon-layout { zoom: var(--fit-scale); }
@media (min-width: 641px) {
  body.fit-scaled:has(.app.layout-combat:not(.combat-side-by-side)) { overflow-y: auto; overflow-x: hidden; }
  body.fit-scaled:has(.app.layout-combat.combat-side-by-side) { overflow: hidden; }
  /* Keep the enlarged fight window centered inside its fixed-width card.
     All combat overlays remain descendants of #viewport, so their
     getBoundingClientRect() coordinates move with the viewport. */
  body.fit-scaled:has(.app.layout-combat) #screen-dungeon .viewport { margin-inline: auto; }
}

.topbar { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.85rem; flex-wrap: wrap; }
.topbar-actions { display: flex; align-items: center; gap: 0.4rem; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; min-width: 0; }
.bgm-picker { position: relative; z-index: 2; overflow: visible; display: inline-flex; align-items: center; gap: 0.45rem; min-height: 36px; padding: 0.2rem 0.5rem 0.2rem 0.65rem; border: 1px solid rgba(245,197,66,0.55); border-radius: 0.5rem; background: rgba(245,197,66,0.12); color: var(--gold); font-size: 0.8rem; font-weight: 800; letter-spacing: 0.01em; white-space: nowrap; }
.bgm-picker select { min-height: 30px; max-width: 13.5rem; padding: 0.2rem 1.75rem 0.2rem 0.5rem; border: 1px solid var(--line); border-radius: 0.35rem; background: var(--panel); color: var(--ink); color-scheme: dark; font: inherit; font-weight: 700; }
.bgm-picker option { background: #141a2e; color: #eef1ff; }
.player-menu { position: relative; }
#btn-player { max-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.player-panel {
  position: absolute; top: calc(100% + 0.35rem); right: 0; z-index: 40;
  width: min(16.5rem, calc(100vw - 1.5rem));
  padding: 0.65rem; border: 1px solid var(--line); border-radius: 12px;
  background: #141a2e; box-shadow: 0 16px 40px rgba(0,0,0,0.45);
}
.player-panel[hidden] { display: none; }
.player-panel-lead { margin: 0 0 0.4rem; color: var(--muted); font-size: 0.75rem; }
.player-list { list-style: none; margin: 0 0 0.5rem; padding: 0; display: grid; gap: 0.25rem; max-height: 11rem; overflow: auto; }
.player-list button {
  width: 100%; text-align: left; min-height: 32px; padding: 0.2rem 0.55rem;
  border-radius: 8px; border: 1px solid var(--line); background: transparent; color: var(--ink);
  font: inherit; font-size: 0.85rem;
}
.player-list button.is-current { border-color: var(--gold); }
.player-row { display: grid; grid-template-columns: minmax(0, 1fr) 32px 32px; gap: .25rem; align-items: center; }
.player-list .player-pick { min-width: 0; }
.player-list .player-icon { width: 32px; min-height: 32px; padding: 0; display: grid; place-items: center; text-align: center; font-size: .95rem; line-height: 1; }
.player-list .player-edit { color: #b9d9ff; }
.player-list .player-remove { color: #ffb4b4; }
.player-list .player-remove:hover, .player-list .player-remove:focus-visible { border-color: var(--bad); background: rgba(248,113,113,.12); }
.player-new { display: flex; gap: 0.35rem; }
.player-new input {
  flex: 1; min-width: 0; min-height: 32px; padding: 0.2rem 0.45rem;
  border-radius: 8px; border: 1px solid var(--line); background: #0e1424; color: var(--ink); font: inherit;
}
.player-new button { min-height: 32px; padding: 0.2rem 0.55rem; white-space: nowrap; }
.brand { display: flex; align-items: center; gap: 0.6rem; text-decoration: none; color: inherit; }
.brand-mark { width: 36px; height: 36px; flex: 0 0 36px; display: block; }
.brand-icon { border: 0; background: transparent; border-radius: 0; object-fit: contain; }
.brand strong { display: block; font-size: 0.98rem; }
.brand em { font-style: normal; color: var(--muted); font-size: 0.78rem; }
.app-version { align-self: center; color: var(--muted); font-family: var(--mono); font-size: 0.68rem; line-height: 1; white-space: nowrap; user-select: none; }
.app-version:has(.dev-badge) { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.12rem; font-size: 0.56rem; }
.app-version .dev-badge { display: block; font-size: 0.72em; }

.screen { display: none; }
.screen.active { display: block; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem 1.25rem 1.35rem;
  box-shadow: 0 18px 50px rgba(0,0,0,0.35);
  backdrop-filter: blur(8px);
}

.hero h1 { margin: 0 0 0.35rem; font-size: clamp(1.6rem, 4vw, 2.15rem); letter-spacing: -0.02em; }
.hero p { margin: 0 0 1.1rem; color: var(--muted); max-width: 38rem; }
.hero .over-flavor { font-style: italic; }

.theme-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.55rem 0.85rem;
  margin: 0 0 1rem; padding: 0.75rem 0.9rem; border: 1px solid var(--line);
  border-radius: 14px; background: rgba(255,255,255,0.04);
}
.theme-row select {
  flex: 1 1 220px; min-height: 44px; padding: 0.45rem 0.75rem; border-radius: 12px;
  border: 1px solid var(--line); background: #0f1528; color: var(--ink); font: inherit; font-weight: 600;
}
.theme-row select:focus { outline: 2px solid rgba(245,197,66,0.55); outline-offset: 2px; }

.class-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.85rem; margin-bottom: 1rem; }
@media (max-width: 640px) { .class-grid { grid-template-columns: 1fr; } }
.class-card {
  border: 1px solid var(--line); border-radius: 16px; padding: 1rem;
  background: rgba(255,255,255,0.03); display: flex; flex-direction: column; gap: 0.55rem; min-height: 180px;
}
.class-card .art {
  width: min(220px, 52vw); height: auto; aspect-ratio: 1; object-fit: contain; object-position: center center;
  border-radius: 14px; background: transparent; border: 1px solid var(--line); display: block; margin: 0 auto;
}
/* Tall idle sheet has empty canvas under the boots. Cover the square so the
   soles land on the frame bottom; the helmet stays inside. Mage art is already flush. */
#class-art-warrior { object-fit: cover; object-position: center center; }
.class-card h2 { margin: 0; font-size: 1.2rem; }
.class-card p { margin: 0; color: var(--muted); font-size: 0.92rem; flex: 1; }

.scoreboard-shell { margin: 1rem 0 0; }
.daily-entry { display:flex; align-items:center; justify-content:space-between; gap:.55rem; margin:0; padding:.4rem .55rem; border:1px solid rgba(245,197,66,.35); border-radius:12px; background:rgba(245,197,66,.08); flex: 1 1 28rem; min-width: 16rem; }
.daily-copy { min-width: 0; }
.daily-entry span { display:block; color:var(--muted); font-size:.72rem; margin-top:0; line-height: 1.45; } /* J-1002: room for g/y descenders (overflow is hidden for the ellipsis) */
.daily-entry .daily-theme { display: inline; }
.daily-actions { display:flex; flex-wrap:wrap; gap:.35rem; justify-content:flex-end; }
.daily-actions .btn { width: auto; min-height: 32px; padding: 0.15rem 0.7rem; font-size: 0.75rem; }
.daily-choice { display:flex; align-items:center; gap:.25rem; }
.daily-choice-label { font-size:.68rem; font-weight:700; color:var(--gold); white-space:nowrap; }
.daily-choice .btn { min-height: 32px; padding: 0.15rem 0.55rem; font-size: 0.75rem; }
.scoreboard-split { display:grid; gap:.7rem; }
/* The fit scaler adds .combat-side-by-side only when the height-limited game
   width plus a usable board column fits. The boards are never part of fit. */
.dungeon-layout { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; width: 100%; max-width: 100%; margin: 0 auto; }
.layout-combat:not(.combat-side-by-side) .dungeon-layout { width: min(100%, 960px); }
.play-card { order: 1; width: auto; }
.layout-combat .scoreboard-side { order: 2; margin-top: 0.85rem; }
.layout-combat.combat-side-by-side .dungeon-layout { grid-template-columns: minmax(0, 1fr) minmax(280px, 420px); gap: 0.85rem; align-items: start; width: 100%; }
.layout-combat.combat-side-by-side .scoreboard-side { grid-column: 2; grid-row: 1; width: auto; margin-top: 0; max-height: calc(100vh - 2rem); overflow: auto; z-index: 3; }
.combat-side-by-side .scoreboard-side .scoreboard-list { max-height: 200px; }
.fit-combat-below:has(#screen-dungeon.active) { overflow-y: auto !important; overflow-x: hidden !important; }
.dungeon-row { margin: 0; }
.scoreboard-card { border: 1px solid rgba(245,197,66,0.25); border-radius: 16px; background: rgba(5,9,20,0.58); padding: 0.85rem; }
.scoreboard-heading { display: flex; justify-content: space-between; gap: 0.5rem; align-items: flex-start; margin-bottom: 0.65rem; }
.scoreboard-heading h2 { margin: 0; font-size: 1.08rem; }
.scoreboard-heading p { color: var(--muted); font-size: 0.72rem; margin: 0.1rem 0 0; }
.scoreboard-heading p.scoreboard-since { font-size: 0.68rem; font-weight: 400; letter-spacing: 0.01em; margin-top: 0.16rem; text-transform: none; }
.scoreboard-badge { color: var(--gold); border: 1px solid rgba(245,197,66,0.4); border-radius: 999px; font: 0.62rem var(--mono); padding: 0.2rem 0.35rem; }
.scoreboard-badge.is-shared { color: #7ee0a0; border-color: rgba(126,224,160,0.45); }
.scoreboard-list { max-height: 420px; overflow-y: auto; padding-right: 0.25rem; }
.score-row { width: 100%; min-height: 38px; display: grid; grid-template-columns: 1.6rem minmax(0, 1fr) auto auto auto; gap: 0.35rem; align-items: center; padding: 0.35rem 0.4rem; border-radius: 9px; background: transparent; color: var(--ink); text-align: left; border-bottom: 1px solid rgba(255,255,255,0.06); font-size: 0.78rem; }
.score-row:hover, .score-row:focus-visible { background: rgba(245,197,66,0.12); outline: none; }
.score-row.is-current { background: rgba(52,211,153,0.14); box-shadow: inset 2px 0 var(--ok); }
.score-rank { color: var(--gold); font: 0.75rem var(--mono); }
.score-name { overflow: hidden; font-weight: 700; min-width: 0; }
.score-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.score-glyphs { display: flex; flex-wrap: wrap; gap: 0.15rem; font-weight: 600; }
.score-glyph {
  font-size: 0.62rem; line-height: 1.25; color: var(--muted);
  border: 1px solid rgba(245,197,66,0.35); border-radius: 999px;
  padding: 0.05rem 0.35rem; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.score-words, .score-misses, .score-time, .score-accuracy { color: var(--muted); white-space: nowrap; font: 0.7rem var(--mono); }
.scoreboard-empty { color: var(--muted); font-size: 0.8rem; margin: 0.5rem 0; }
.score-entry { margin: 1rem 0; padding: 0.8rem; border: 1px solid rgba(245,197,66,0.3); border-radius: 14px; background: rgba(0,0,0,0.2); }
.score-entry label { display: block; font-weight: 700; margin-bottom: 0.45rem; }
.score-entry label span, .score-entry p { color: var(--muted); font-size: 0.78rem; font-weight: 400; }
.score-entry > div { display: flex; gap: 0.5rem; }
.score-entry input { min-width: 0; flex: 1; min-height: 44px; border: 1px solid var(--line); border-radius: 10px; background: #0f1528; color: var(--ink); padding: 0 0.75rem; font: inherit; }
.score-entry p { margin: 0.4rem 0 0; }
.score-saved { color: var(--ok); font-weight: 700; margin: 1rem 0; }
.score-detail-backdrop { position: fixed; inset: 0; z-index: 20; display: grid; place-items: center; padding: 1rem; background: rgba(3,5,12,0.72); }
.score-detail-backdrop[hidden] { display: none; }
.score-detail-card { width: min(560px, 100%); max-height: min(86vh, 760px); overflow: auto; position: relative; border: 1px solid rgba(245,197,66,0.4); border-radius: 16px; padding: 1.15rem 1.2rem 1.25rem; background: linear-gradient(180deg, #1a2238, #12182c); box-shadow: 0 20px 70px #000, inset 0 1px 0 rgba(255,235,190,.08); }
.score-detail-close { position: absolute; top: 0.45rem; right: 0.5rem; min-height: 32px; padding: 0 0.55rem; background: transparent; color: var(--ink); font-size: 1.35rem; z-index: 1; }
.score-detail-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.75rem; margin: 0 1.8rem 0.85rem 0; }
.score-detail-rank { color: var(--gold); font: 700 0.95rem/1 var(--mono); }
.score-detail-name { font: 600 1.28rem/1.15 "Cinzel Lore", Georgia, serif; color: var(--ink); min-width: 0; }
.score-detail-score { margin-left: auto; color: var(--gold); font: 700 1.15rem/1 var(--mono); }
.score-detail-result { flex: 1 0 100%; color: var(--muted); font-size: 0.82rem; }
.score-stat-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.45rem; }
.score-stat { padding: 0.45rem 0.5rem 0.4rem; border: 1px solid rgba(245,197,66,0.28); border-radius: 10px; background: rgba(0,0,0,0.22); }
.score-stat span { display: block; color: var(--muted); font: 700 0.62rem/1.2 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; }
.score-stat strong { display: block; margin-top: 0.2rem; font-size: 1.02rem; font-variant-numeric: tabular-nums; }
.score-detail-meta { margin: 0.75rem 0 0.45rem; color: var(--muted); font-size: 0.82rem; }
.score-detail-glyphs { margin: 0 0 0.35rem; }
.score-detail-glyphs .score-glyph { font-size: 0.68rem; }
.score-coins-heading { margin: 0.85rem 0 0.45rem; color: var(--gold); font: 600 0.72rem/1.2 "Cinzel Lore", Georgia, serif; letter-spacing: 0.08em; text-transform: uppercase; }
.score-coins { display: grid; grid-template-columns: repeat(auto-fill, minmax(46px, 1fr)); gap: 0.4rem; overflow: visible; padding: 0 0 0.15rem; }
.score-coin-thumb { display: block; width: 100%; aspect-ratio: 1; height: auto; border: 1px solid rgba(245,197,66,0.35); border-radius: 8px; background: rgba(0,0,0,0.2); cursor: help; }
.score-coin-thumb svg { display: block; width: 100%; height: 100%; }
@media (max-width: 520px) { .score-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.score-coins-empty { margin: 0; color: var(--muted); font-size: 0.78rem; }
@media (max-width: 1759px) {
  .scoreboard-side .scoreboard-list { max-height: 220px; }
}

.howto ol { margin: 0.4rem 0 1rem; padding-left: 1.2rem; color: var(--muted); }
.howto li { margin: 0.35rem 0; }
kbd {
  display: inline-block; padding: 0.1rem 0.4rem; border-radius: 6px; border: 1px solid var(--line);
  background: rgba(255,255,255,0.08); font-family: var(--mono); font-size: 0.85em;
}

/* ---- HUD ---- */
/* Default .hud grid kept for non-stage contexts; combat uses .stage-hud overlays. */
.hud { display: grid; grid-template-columns: 1fr 1fr; gap: 0.65rem; margin-bottom: 0.75rem; }
@media (max-width: 640px) { .hud { grid-template-columns: 1fr; } }
.hud-panel { background: rgba(0,0,0,0.25); border: 1px solid var(--line); border-radius: 14px; padding: 0.7rem 0.85rem; }
.hud-panel-player { border-color: rgba(180,120,60,0.4); position: relative; }
.stage-hud {
  display: contents; /* panels are absolute overlays; no grid strip above stage */
  margin: 0;
}
.hud-meta { display: flex; flex-wrap: wrap; gap: 0.45rem 0.75rem; font-size: 0.82rem; color: var(--muted); margin-bottom: 0.45rem; align-items: center; }
.hud-meta strong { color: var(--ink); font-weight: 700; }
.bar-label { display: flex; justify-content: space-between; font-size: 0.78rem; color: var(--muted); margin-bottom: 0.25rem; }
#player-hp-text, #monster-hp-text { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
.bar { height: 12px; border-radius: 999px; background: rgba(255,255,255,0.08); overflow: hidden; border: 1px solid var(--line); }
.hp-float-host { position: relative; height: 0; z-index: 6; }
.hp-float {
  position: absolute; left: 0.15rem; top: 0.05rem;
  font: 800 0.95rem var(--mono); letter-spacing: 0.02em;
  text-shadow: 0 1px 2px #000, 0 0 6px rgba(0,0,0,0.65);
  pointer-events: none; opacity: 0; white-space: nowrap;
}
.hp-float.dmg { color: #f87171; }
.hp-float.heal { color: #34d399; }
.hp-float.show { animation: hp-float-up 2400ms ease forwards; }
@keyframes hp-float-up {
  0% { opacity: 0; transform: translateY(3px); }
  5% { opacity: 1; transform: translateY(0); }
  68% { opacity: 1; transform: translateY(-6px); }
  100% { opacity: 0; transform: translateY(-16px); }
}
@media (prefers-reduced-motion: reduce) {
  .hp-float.show { animation: hp-float-fade 2400ms ease forwards; }
}
@keyframes hp-float-fade {
  0% { opacity: 0; }
  8% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; }
}
.bar.chip-bar { height: 16px; border-radius: 6px; }
.bar > span { display: block; height: 100%; width: 100%; border-radius: inherit; transition: width 0.18s ease; }
#player-hp-fill { background: linear-gradient(90deg, #16a34a, var(--hp)); }
#player-hp-fill.low { background: linear-gradient(90deg, #b91c1c, var(--hp-low)); }
#monster-hp-fill { background: linear-gradient(90deg, #ea580c, var(--monster)); }
#monster-hp-fill.low { background: linear-gradient(90deg, #9a3412, #ef4444); }

/* Chest loot colors (was the flair-tier chip ramp). One filled gem per hall. */
.treasure-tier-1 { background: #9aa3c7; }
.treasure-tier-2 { background: #7dd3fc; }
.treasure-tier-3 { background: #5eead4; }
.treasure-tier-4 { background: #86efac; }
.treasure-tier-5 { background: #d9f99d; }
.treasure-tier-6 { background: #fde68a; }
.treasure-tier-7 { background: #fbbf24; }
.treasure-tier-8 { background: #f97316; }
.treasure-tier-9 { background: #f87171; }
.treasure-tier-10 { background: linear-gradient(135deg, var(--gold), #fff7d6); box-shadow: 0 0 6px rgba(245,197,66,0.85); }

.topbar .btn-mute { min-height: 36px; padding: 0.2rem 0.7rem; font-size: 0.78rem; margin-left: 0; }
.topbar .btn-mute { position: relative; z-index: 2; width: 6.9rem; flex: 0 0 6.9rem; white-space: nowrap; overflow: visible; }

@keyframes attn-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 200, 60, 0.9); }
  50% { box-shadow: 0 0 12px 6px rgba(255, 200, 60, 0.9); }
}
.attn-pulse { animation: attn-pulse 1.2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .attn-pulse { animation: none; box-shadow: 0 0 0 3px rgba(255, 200, 60, 0.9), 0 0 12px 2px rgba(255, 200, 60, 0.9); transform: none; }
}

/* Keep the desktop header in one stable flex line. The daily copy may yield
   width, but the controls keep their measured widths in either audio state. */
@media (min-width: 1024px) {
  .topbar { flex-wrap: nowrap; }
  .daily-entry { min-width: 0; flex: 1 1 auto; }
  .daily-copy { min-width: 0; overflow: hidden; }
  .daily-copy strong, .daily-copy span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topbar-actions { flex-wrap: nowrap; flex: 0 1 auto; }
  .bgm-picker { flex: 0 1 auto; min-width: 0; }
  .bgm-picker select { width: clamp(9rem, 16vw, 13.5rem); }
}

/* Keep the combat header on one line at the smallest desktop proof width. */
@media (min-width: 641px) and (max-width: 1023px) {
  body:has(#screen-dungeon.active) .topbar { flex-wrap: nowrap; gap: 0.35rem; }
  body:has(#screen-dungeon.active) .brand { gap: 0.35rem; min-width: 0; }
  body:has(#screen-dungeon.active) .brand-mark { width: 30px; height: 30px; flex-basis: 30px; }
  body:has(#screen-dungeon.active) .brand strong { font-size: 0.78rem; }
  body:has(#screen-dungeon.active) .brand em { font-size: 0.6rem; }
  body:has(#screen-dungeon.active) .app-version { font-size: 0.42rem; }
  body:has(#screen-dungeon.active) .daily-entry { min-width: 0; flex: 1 1 8rem; gap: 0.2rem; padding: 0.25rem 0.35rem; }
  body:has(#screen-dungeon.active) .daily-copy strong,
  body:has(#screen-dungeon.active) .daily-copy span { font-size: 0.56rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body:has(#screen-dungeon.active) .daily-actions { gap: 0.15rem; flex-wrap: nowrap; }
  body:has(#screen-dungeon.active) .daily-actions .btn { min-height: 27px; padding: 0.1rem 0.35rem; font-size: 0.58rem; }
  body:has(#screen-dungeon.active) .topbar-actions { flex: 0 1 auto; flex-wrap: nowrap; gap: 0.2rem; }
  body:has(#screen-dungeon.active) .topbar-actions #btn-player { max-width: 4.2rem; padding-inline: 0.35rem; font-size: 0.66rem; }
  body:has(#screen-dungeon.active) .topbar-actions .bgm-picker { gap: 0.2rem; min-height: 30px; padding-inline: 0.3rem; font-size: 0.58rem; }
  body:has(#screen-dungeon.active) .topbar-actions .bgm-picker select { width: 7.1rem; min-height: 25px; padding-inline: 0.25rem; font-size: 0.58rem; }
  body:has(#screen-dungeon.active) .topbar .btn-mute { width: 4.8rem; flex-basis: 4.8rem; min-height: 30px; padding-inline: 0.25rem; font-size: 0.62rem; }
  body:has(#screen-dungeon.active) .topbar-actions #btn-developer { min-height: 30px; padding-inline: 0.35rem; font-size: 0.62rem; }
}

.developer-panel {
  position: absolute; top: 3.1rem; right: 0; z-index: 30; width: min(34rem, calc(100vw - 2rem));
  max-height: calc(100vh - 4.5rem); overflow: auto;
  padding: 1rem; border: 1px solid rgba(245,197,66,0.45); border-radius: 16px;
  background: #141a2e; box-shadow: 0 20px 70px rgba(0,0,0,0.55);
}
.developer-lists { margin-top: 0.75rem; padding-top: 0.7rem; border-top: 1px solid var(--line); }
.developer-lists-head { font-weight: 700; font-size: 0.85rem; }
.developer-lists-note { margin: 0.15rem 0 0.4rem; color: var(--muted); font-size: 0.72rem; }
.developer-list-cols, .developer-list-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 2.6rem 2.6rem 2.4rem;
  gap: 0.25rem; align-items: center;
}
.developer-list-cols { color: var(--muted); font-size: 0.68rem; margin-bottom: 0.2rem; }
.developer-list-cols span:not(:first-child), .developer-list-row label { text-align: center; }
.developer-lists-scroll { max-height: 14rem; overflow: auto; display: grid; gap: 0.15rem; }
.developer-list-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.78rem; }
.developer-list-row label { display: flex; justify-content: center; }
.developer-list-row input { width: 1rem; height: 1rem; accent-color: var(--ok); }
.developer-panel[hidden] { display: none; }
.developer-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.8rem; }
.developer-heading strong, .developer-heading span { display: block; }
.developer-heading span { color: var(--muted); font-size: 0.78rem; }
.developer-tools { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.55rem; margin-bottom: 0.9rem; }
.developer-tool-button { display: block; padding: 0.55rem 0.7rem; text-align: center; text-decoration: none; font-size: 0.78rem; }
.developer-close { min-height: 30px; padding: 0 0.45rem; background: transparent; color: var(--ink); font-size: 1.3rem; }
.developer-shortcuts { margin: 0; display: grid; gap: 0.32rem; }
.developer-shortcuts > div { display: grid; grid-template-columns: minmax(9.5rem, auto) 1fr; gap: 0.5rem; align-items: center; }
.developer-shortcuts dt { white-space: nowrap; }
.developer-shortcuts dd { margin: 0; color: var(--muted); font-size: 0.8rem; }
.developer-toggle { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.9rem; padding-top: 0.75rem; border-top: 1px solid var(--line); font-weight: 700; }
.developer-toggle input { width: 1.1rem; height: 1.1rem; accent-color: var(--ok); }
.developer-toggle strong { margin-left: auto; color: var(--ok); font: 0.75rem var(--mono); }
.developer-toggle.is-off strong { color: var(--bad); }
.developer-field {
  display: flex; align-items: center; gap: 0.6rem;
  margin-top: 0.55rem; font-weight: 700; font-size: 0.85rem;
}
.developer-field select {
  margin-left: auto; min-height: 32px; padding: 0.15rem 0.45rem;
  background: #0e1424; color: var(--ink); border: 1px solid var(--line);
  border-radius: 8px; font: 700 0.8rem var(--mono); font-variant-numeric: tabular-nums;
}

/* Potion HUD chip — assets/ui/potion_chip.png icon + live count text */
.potion-chip {
  display: flex; align-items: center; gap: 0.5rem; margin-top: 0.55rem;
  padding: 0.25rem 0.6rem 0.25rem 0.3rem; border-radius: 999px;
  background: rgba(0,0,0,0.3) url("../assets/ui/potion_chip.webp?v=assetplan1") left center / 28px 28px no-repeat;
  border: 1px solid var(--line); width: fit-content; padding-left: 2.1rem;
}
.potion-chip-count { font-weight: 700; font-size: 0.85rem; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- Dungeon viewport (over-shoulder hall) ---- */
.dungeon-row { margin-bottom: 0.85rem; }

.viewport {
  position: relative;
  border-radius: 16px;
  border: 1px solid var(--line);
  min-height: 460px;
  height: clamp(460px, 66vh, 680px);
  overflow: hidden;
  background: #14100d;
  width: min(960px, 100%);
}
.corridor-brick {
  position: absolute; inset: 0;
  background-color: #14100d;
  background-size: cover;
  background-position: center;
  filter: brightness(0.9);
  transition: filter 0.2s ease;
}
.corridor-brick.hall-bg-straight { background-image: url("../assets/dungeon/hall_straight.webp"); }
.corridor-brick.hall-bg-corner { background-image: url("../assets/dungeon/hall_corner.webp"); }
.corridor-brick.hall-bg-exit { background-image: url("../assets/dungeon/exit_gate_sunlight.webp?v=assetplan1"); }
.viewport.class-warrior .corridor-brick { box-shadow: inset 0 0 0 1px rgba(224,122,58,0.2); }
.viewport.class-mage .corridor-brick { box-shadow: inset 0 0 0 1px rgba(139,92,246,0.24); }
.viewport.shake { animation: shake 0.35s ease; }
.viewport.walk .corridor-brick { animation: walk-forward 0.5s ease; }
.viewport.turn-left .corridor-brick { animation: turn-left 0.5s ease; }
.viewport.turn-right .corridor-brick { animation: turn-right 0.5s ease; }
.viewport.gate-open .corridor-brick { animation: gate-flash 1.3s ease; }
.viewport.mode-escape .corridor-brick { filter: brightness(1.05) saturate(1.1); }

/* Fighters: absolute pose layout (Courtney V2 → 1280×720 hall, cover-mapped).
   JS COMBAT_POSE pins hero/foe on the hall floor. Extra letter-key board hidden;
   hands keyboard (keys drawn in hands art) sits bottom-left on the stage. */
.fighters {
  position: absolute; inset: 0;
  z-index: 2; pointer-events: none;
  /* no lift — JS COMBAT_POSE maps to hallway floor */
}

.ph-rect {
  position: absolute;
  display: flex; align-items: center; justify-content: center;
  overflow: visible;
  margin: 0;
  padding: 0;
  max-width: none;
  /* left/top/width/height set by layoutCombatPose() */
}
.ph-rect::after {
  /* White name chips under sprites showed through the translucent type row. HP bars keep the names. */
  content: none;
  display: none;
}
.ph-rect img {
  width: 100%; height: 100%;
  max-width: 100%; max-height: 100%;
  object-fit: contain; object-position: center center;
  border: 0; outline: none; background: transparent; border-radius: 0;
  /* contact shadow under cutouts */
  filter: drop-shadow(0 10px 12px rgba(0,0,0,0.55));
  transform: rotate(var(--pose-rot, 0deg));
  transform-origin: center center;
}

/* Hero: OTS warrior over kobold; size/pos from COMBAT_POSE V2 */
.hero-rect {
  z-index: 4; /* Hero above every monster sprite: front and rear queue. */
}
.hero-rect.swing-l { animation: swing-l 0.75s ease; }
.hero-rect.swing-r { animation: swing-r 0.75s ease; }
.hero-rect.kill-cleave { animation: kill-cleave 1.5s ease; }
.hero-rect.kill-fireball { animation: kill-fireball 1.5s ease; }
/* Mage sheet is the cast. The 14px swing / scale pulse read as a wiggle
   and hid zap_R / fireball_kill. Warrior slash keeps swing-r. */
.viewport.class-mage .hero-rect.swing-l,
.viewport.class-mage .hero-rect.swing-r,
.viewport.class-mage .hero-rect.kill-fireball { animation: none; }
/* TYPING-HERO-TWEEN: the tweened frames carry the warrior's motion; the old
   whole-box lurch/tilt made his planted feet slide. */
.viewport.class-warrior .hero-rect.swing-l,
.viewport.class-warrior .hero-rect.swing-r,
.viewport.class-warrior .hero-rect.kill-cleave { animation: none; }
.hero-rect.gore-blood::before, .hero-rect.gore-ash::before {
  content: ""; position: absolute; inset: -10px; border-radius: 14px; opacity: 0; pointer-events: none;
}
.hero-rect.gore-blood::before { background: radial-gradient(circle, rgba(180,20,20,0.55), transparent 70%); animation: gore-pop 0.6s ease; }
.hero-rect.gore-ash::before { background: radial-gradient(circle, rgba(120,120,120,0.5), transparent 70%); animation: gore-pop 0.6s ease; }

/* Monster: under warrior; size/pos from COMBAT_POSE V2 */
.monster-rect {
  z-index: 2; /* Front fighter above rear queue, under the hero. */
}
.monster-rect[class*="atk-"] { animation: monster-strike 0.4s ease; }
.monster-rect.atk-beholder { animation-name: beholder-blast; }
.monster-rect.atk-skeleton { animation: none !important; }
.monster-rect img {
  /* concept-wire: no photo-frame (was border-radius plate) */
  border-radius: 0;
  border: 0;
  outline: none;
  background: transparent;
  object-fit: contain;
  object-position: center center;
  /* contact shadow kept via .ph-rect img drop-shadow */
}
/* J-1011-TYPING-PERF-WINS item 7: dragon frames are stored cropped to their
   bottom 896 rows (full 1898 width). contain keeps the same scale; this y puts
   them exactly where the full 1898x2880 frame drew them in the 595x903 box. */
.ph-rect img[src*="monsters/dragon/"] { object-position: 50% 99.9876%; }
/* Goblin, kobold, tarrasque: stored as their art rows [y0, y1) of 595x903 (full width);
   y = y0 / (903 - (y1 - y0)) puts them where the full frame drew them.
   J-1012-KOBOLD-NEW-ART: kobold-v2 is 595x528 (feet row 520), goblin-v2 is
   595x624 (feet row 613), one scale per monster, so the dead frame needs no shrink. */
.ph-rect img[src*="monsters/goblin-v2/"] { object-position: 50% 94.6237%; }
.ph-rect img[src*="monsters/kobold-v2/"] { object-position: 50% 96.0000%; }
.ph-rect img[src*="monsters/tarrasque/"] { object-position: 50% 94.0270%; }
.monster-rect.boss img { filter: drop-shadow(0 0 18px rgba(245,197,66,0.5)) drop-shadow(0 8px 14px rgba(0,0,0,0.55)); }
/* Final foe of each ordinary hall: visibly red, dangerous, but still the
   same monster silhouette so players can read its attack art. */
.monster-rect.hall-boss img { filter: drop-shadow(0 0 6px #fff) drop-shadow(0 0 20px rgba(255,35,45,.98)) drop-shadow(0 0 42px rgba(190,0,16,.78)) drop-shadow(0 8px 14px rgba(0,0,0,.55)); animation: hall-boss-red 1.05s ease-in-out infinite alternate; }
@keyframes hall-boss-red { from { filter: drop-shadow(0 0 5px #fff) drop-shadow(0 0 15px rgba(255,30,40,.82)) drop-shadow(0 8px 14px rgba(0,0,0,.55)); } to { filter: brightness(1.16) saturate(1.7) drop-shadow(0 0 10px #fff) drop-shadow(0 0 28px rgba(255,25,35,1)) drop-shadow(0 0 52px rgba(180,0,12,.85)) drop-shadow(0 8px 14px rgba(0,0,0,.55)); } }
.monster-rect[class*="atk-"] { animation: monster-strike 1.05s ease; }

/* Beholder attack FX is a separate ray so the direction is real, even if a
   cached/legacy strike sheet has a baked beam aimed at the camera. JS places
   the right-hand origin at the central eye and points the ray at the hero. */
.beholder-ray {
  position: absolute;
  z-index: 3;
  display: none;
  height: 8px;
  width: 0;
  pointer-events: none;
  transform-origin: 0 50%;
  background: linear-gradient(180deg, rgba(242,190,255,0), rgba(196,92,255,.98) 28%, #fff 50%, rgba(167,54,255,.98) 72%, rgba(242,190,255,0));
  filter: drop-shadow(0 0 4px rgba(210,112,255,.98)) drop-shadow(0 0 12px rgba(152,48,255,.8));
  border-radius: 999px;
}
.beholder-ray::after {
  content: "";
  position: absolute;
  right: -5px;
  top: 50%;
  width: 12px;
  height: 12px;
  transform: translateY(-50%);
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 8px 3px #d47cff, 0 0 18px 6px rgba(152,48,255,.8);
}
.beholder-ray.live { display: block; animation: beholder-ray-pulse 0.84s ease both; }

/* Live depth queue: only the front fighter uses #monster-rect animation.
   Rear slots are idle billboards, painted far-to-near by DOM order. */
.monster-queue { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.monster-queue-slot { z-index: auto; }
.monster-queue-slot.queue-tell img {
  filter: hue-rotate(142deg) saturate(1.85) brightness(1.26)
    drop-shadow(0 0 12px rgba(116,70,255,.96))
    drop-shadow(0 0 4px rgba(210,174,255,.95));
}
.current-fight-label {
  position: absolute; z-index: 6; left: 50%; top: 0.55rem; transform: translateX(-50%);
  color: rgba(247,220,157,.88); font: 700 0.66rem/1 system-ui, sans-serif;
  letter-spacing: .12em; text-transform: uppercase; text-shadow: 0 2px 3px #000;
  pointer-events: none;
}

.escape-track {
  position: absolute; left: 1rem; right: 1rem; bottom: 0.85rem; height: 8px; border-radius: 999px;
  background: rgba(0,0,0,0.35); border: 1px solid var(--line); z-index: 3; display: none;
}
.viewport.mode-escape .escape-track { display: block; }
.escape-progress { display: block; height: 100%; width: 0; border-radius: inherit; background: linear-gradient(90deg, var(--gold), #fff); transition: width 0.3s ease; }

/* Pause sits above every in-game layer (word box 6, lore seal 7, combat
   popups 8-10). The viewport isolates its own stack so 100 never climbs over
   page-level modals. */
.viewport { isolation: isolate; }
.pause-overlay {
  position: absolute; inset: 0; display: none; align-items: flex-start; justify-content: center;
  background: rgba(3,5,10,0.82); backdrop-filter: blur(3px); z-index: 100; overflow-y: auto; padding: 1rem;
  pointer-events: auto;
}
.pause-overlay.show { display: flex; }
.pause-overlay { scrollbar-width: thin; scrollbar-color: rgba(245,197,66,0.45) transparent; }
/* margin:auto centers a short card but lets a long treasure list scroll from the top */
.pause-card {
  width: min(32rem, 100%); text-align: center; margin: auto 0;
  padding: 1rem 1.15rem 1.1rem; border-radius: 14px;
  background: linear-gradient(180deg, rgba(20,26,44,0.97), rgba(10,14,26,0.97));
  border: 1px solid rgba(245,197,66,0.35);
  box-shadow: 0 18px 50px rgba(0,0,0,0.65), inset 0 1px 0 rgba(255,255,255,0.06);
}
.pause-settings { margin: 0.15rem 0 0.85rem; padding: 0.7rem 0.75rem 0.8rem; text-align: left; border: 1px solid rgba(245,197,66,0.38); border-radius: 12px; background: rgba(0,0,0,0.22); box-shadow: inset 0 1px 0 rgba(255,235,190,0.08); }
.pause-settings h3 { margin: 0 0 0.5rem; color: var(--gold); font: 600 0.74rem/1 "Cinzel Lore", Georgia, serif; letter-spacing: 0.14em; text-transform: uppercase; }
.pause-audio { display: grid; gap: .4rem; margin: 0; max-width: none; text-align: left; }
.pause-audio label { display: grid; grid-template-columns: 1fr auto minmax(7rem, 11rem); align-items: center; gap: .55rem; padding: .42rem .55rem; border: 1px solid var(--line); border-radius: .5rem; background: rgba(5,10,22,.55); font-size: .8rem; }
.pause-audio input[type="range"] { width: 100%; accent-color: var(--gold); }
.pause-card #btn-resume { position: sticky; top: 0; z-index: 3; margin: 0 0 0.75rem; width: 100%; }
.tt-pause-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; text-align: left; }
button.tt-pause-row { display: grid; width: 100%; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: 0.55rem; min-height: 44px; margin: 0; padding: 0.2rem 0.65rem; border-radius: 10px; border: 1px solid rgba(245,197,66,0.22) !important; background: rgba(0,0,0,0.28) !important; box-shadow: none !important; color: var(--ink) !important; text-shadow: none; text-align: left; cursor: pointer; }
button.tt-pause-row:hover { border-color: rgba(245,197,66,0.55) !important; background: rgba(245,197,66,0.08) !important; }
.tt-pause-coin { width: 36px; height: 36px; display: block; }
.tt-pause-coin svg { width: 100%; height: 100%; display: block; }
.tt-pause-name { font-weight: 700; font-size: 0.86rem; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tt-pause-rarity { color: var(--muted); font: 700 0.66rem/1 var(--mono); letter-spacing: 0.05em; text-transform: uppercase; }
.pause-card h2 { margin: 0 0 0.35rem; }
.pause-card p { margin: 0 0 0.75rem; color: var(--muted); }

.combat-flash {
  position: absolute; top: 0.75rem; left: 50%; transform: translateX(-50%) translateY(-8px);
  opacity: 0; pointer-events: none; font-weight: 800; letter-spacing: 0.02em; padding: 0.35rem 0.75rem;
  border-radius: 999px; background: rgba(0,0,0,0.55); border: 1px solid var(--line);
  transition: opacity 0.15s ease, transform 0.15s ease; white-space: nowrap; z-index: 4;
}
.combat-flash.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.combat-flash.hit { color: var(--ok); }
.combat-flash.miss { color: var(--bad); }
.combat-flash.win, .combat-flash.level, .combat-flash.potion { color: var(--gold); }
.combat-flash.boss { color: #fff; border-color: rgba(255,72,80,.95); background: linear-gradient(120deg,rgba(105,0,10,.94),rgba(38,0,4,.94)); box-shadow: 0 0 14px rgba(255,35,45,.82), 0 0 36px rgba(175,0,16,.52); text-shadow: 0 0 9px #ff3440; animation: boss-alert .64s ease-in-out infinite alternate; }
@keyframes boss-alert { from { transform: translateX(-50%) translateY(0) scale(1); } to { transform: translateX(-50%) translateY(0) scale(1.08); } }
/* The hero yields a step as the defended strike lands, then recovers. */
.hero-rect.boss-defend { animation: boss-defend-step .52s ease-out; }
@keyframes boss-defend-step { 0% { transform: translateX(0); } 38% { transform: translateX(-28px); } 100% { transform: translateX(0); } }

.potion-found-popup {
  position: absolute; left: 50%; top: 42%; z-index: 8; transform: translate(-50%, -42%) scale(.82);
  opacity: 0; pointer-events: none; padding: .7rem 1.15rem; border: 2px solid var(--gold);
  border-radius: 16px; background: rgba(17, 12, 30, .94); box-shadow: 0 8px 30px rgba(0,0,0,.45), 0 0 24px rgba(245,197,66,.3);
  color: var(--gold); font-size: clamp(1.35rem, 3vw, 2.2rem); font-weight: 900; white-space: nowrap;
  transition: opacity .16s ease, transform .16s cubic-bezier(.2,1.4,.4,1);
}
.potion-found-popup.show { opacity: 1; transform: translate(-50%, -42%) scale(1); }

/* ---- Minimap: 10 halls + current position + turns (subtle L/R bars, no skew) ---- */
.minimap {
  display: flex; flex-direction: column; gap: 0.3rem; justify-content: center;
  padding: 0.6rem; border: 1px solid var(--line); border-radius: 14px; background: rgba(0,0,0,0.25);
}
.mm-pip[data-hall]::after, .mm-pip.mm-turn-left[data-hall]::after, .mm-pip.mm-turn-right[data-hall]::after {
  content: attr(data-hall);
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 0.62rem; font-weight: 700; color: rgba(255,255,255,0.75); pointer-events: none; z-index: 2;
}
.mm-pip {
  position: relative; height: 20px; border-radius: 6px; background: rgba(255,255,255,0.06);
  border: 1px solid var(--line); overflow: hidden;
}
.mm-pip.mm-cleared { background: rgba(52,211,153,0.35); border-color: rgba(52,211,153,0.5); }
.mm-pip.mm-current { background: rgba(245,197,66,0.18); border-color: var(--gold); }
.mm-pip.mm-locked { opacity: 0.55; }
.mm-pip.mm-boss { box-shadow: inset 0 0 0 1px rgba(248,113,113,0.6); }
.mm-pip.mm-final { box-shadow: inset 0 0 0 2px var(--gold); }
/* Soft turn markers: left/right gold edge bars (readable, not broken diagonals) */
.mm-pip.mm-turn-left::before, .mm-pip.mm-turn-right::before {
  content: ""; position: absolute; top: 2px; bottom: 2px; width: 5px;
  background: linear-gradient(180deg, rgba(245,197,66,0.95), rgba(245,197,66,0.45));
  border-radius: 2px; opacity: 0.85;
}
.mm-pip.mm-turn-left::before { left: 3px; }
.mm-pip.mm-turn-right::before { right: 3px; }
.mm-progress { display: block; height: 100%; background: var(--gold); opacity: 0.6; }

.prompt { text-align: center; margin-bottom: 0.65rem; }
.word-frame { border: 1px solid var(--line); border-radius: 10px; padding: 1rem 1.35rem 1.1rem; min-height: 96px; background: rgba(0,0,0,0.3); box-shadow: 0 8px 24px rgba(0,0,0,0.35); }
.prompt .label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); margin-bottom: 0.35rem; }
#word-display { font-family: var(--mono); font-size: clamp(1.55rem, 5vw, 2.25rem); font-weight: 700; letter-spacing: 0.08em; min-height: 1.35em; word-break: break-all; }
#word-display span.ok { color: var(--ok); }
#word-display span.bad { color: var(--bad); text-decoration: underline; }
#word-display span.next { color: #fff; border-bottom: 3px solid var(--gold); padding-bottom: 1px; }
#word-display span.pending { color: rgba(238,241,255,0.42); }
#word-display span.first-letter-flash { animation: first-letter-flash 0.8s ease-in-out infinite; }
@keyframes first-letter-flash {
  0%, 100% { color: #fff; text-shadow: 0 0 0 rgba(245,197,66,0); }
  50% { color: var(--gold); text-shadow: 0 0 14px rgba(245,197,66,0.95); }
}

/* lock: cyan -> purple gradient, reads as a distinct combat timer (not the
   generic HP-bar green/red palette) */
.timer { position: relative; height: 10px; border-radius: 999px; background: rgba(255,255,255,0.08); overflow: hidden; border: 1px solid var(--line); margin: 0.65rem 0 0.85rem; }
#timer-fill { position: relative; z-index: 1; display: block; height: 100%; width: 100%; background: linear-gradient(90deg, #22d3ee, #a855f7); transform: scaleX(1); transform-origin: left center; }
.timer-mark { position: absolute; top: 0; bottom: 0; width: 2px; background: #fff; opacity: 0.92; z-index: 2; pointer-events: none; }
.timer-mark.at-third { left: 33.333%; }
.timer-mark.at-two-thirds { left: 66.666%; }
#timer-fill.urgent { background: linear-gradient(90deg, #f59e0b, #ef4444); }
#viewport.typing-game-paused, #viewport.typing-game-paused *, #viewport.typing-game-paused *::before, #viewport.typing-game-paused *::after { animation-play-state: paused !important; }

#type-input {
  width: 100%; min-height: 34px; height: 36px; border-radius: 10px; border: 1px solid var(--line); background: rgba(0,0,0,0.35);
  color: var(--ink); font-family: var(--mono); font-size: 1.05rem; letter-spacing: 0.06em; padding: 0.22rem 0.75rem; outline: none;
  white-space: nowrap; overflow: hidden; direction: ltr;
}
#type-input:focus { border-color: rgba(245,197,66,0.65); box-shadow: 0 0 0 3px rgba(245,197,66,0.18); }

.hint { margin: 0.55rem 0 1rem; color: var(--muted); font-size: 0.82rem; text-align: center; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
#screen-dungeon .type-row { width: 100%; margin: 0.28rem 0 0; }
#screen-dungeon .hint { display: none; }

/* ---- Keyboard trainer ---- */
.keyboard-trainer { position: relative; padding: 0.75rem; border: 1px solid var(--line); border-radius: 14px; background: rgba(0,0,0,0.2); }
.kt-board { position: relative; display: flex; flex-direction: column; gap: 6px; align-items: center; }
.kt-row { display: flex; gap: 6px; }
.kt-row-1 { margin-left: 14px; }
.kt-row-2 { margin-left: 28px; }
.kt-key {
  display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  border-radius: 6px; background: rgba(255,255,255,0.06); border: 1px solid var(--line);
  font-family: var(--mono); font-size: 0.85rem; color: var(--muted); text-transform: uppercase;
  transition: background 0.12s ease, color 0.12s ease, transform 0.12s ease;
}
.kt-key.active { background: var(--ok); color: #1a1205; transform: scale(1.12); font-weight: 800; }
.kt-key.wrong { background: var(--bad); color: #2a0a0a; transform: scale(1.12); font-weight: 800; animation: kt-wrong-flash 0.3s ease; }
.kt-key-space { width: 160px; height: 26px; margin-top: 4px; }
.kt-row-space { justify-content: center; }

/* Desktop keyboard surface geometry lives in css/keyboard.css. */
.kt-board { position: relative; z-index: 1; }

/* ---- On-stage HUD overlays (kbstage1 — HP chips on stage corners; rail +
   word/timer stay on-stage; hands keyboard is a compact bottom-LEFT overlay
   on #viewport). Declared after .keyboard-trainer so absolute wins.
   pointer-events:none on stage overlays. Mute lives in the page heading.
   #type-input is a slim bar just under the stage. ---- */
.stage-overlay { position: absolute; z-index: 4; pointer-events: none; }

/* J-1004-TYPING-HPBARS: 28% each leaves a 44% top-middle band. 30% is the ceiling.
   J-1004-TYPING-HPBARS-C: height, padding, and type match live v2026.10.04.12. */
.stage-hud-player {
  top: 0.45rem; left: 0.45rem; right: auto; bottom: auto;
  width: 28%;
  max-width: 30%;
  margin: 0;
  padding: 0.28rem 0.42rem 0.32rem;
  background: rgba(6,8,14,0.62);
  backdrop-filter: blur(3px);
  border-color: rgba(180,120,60,0.55);
  z-index: 5;
}
.stage-hud-player .hud-meta {
  flex-wrap: nowrap;
  gap: 0.28rem 0.45rem;
  margin-bottom: 0.16rem;
  font-size: 0.74rem;
  white-space: nowrap;
  overflow: hidden;
  min-width: 0;
}
.stage-hud-player .hud-meta > span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stage-hud-monster {
  top: 0.45rem; right: 0.45rem; left: auto; bottom: auto;
  width: 28%;
  max-width: 30%;
  margin: 0;
  padding: 0.4rem 0.55rem 0.45rem;
  background: rgba(6,8,14,0.62);
  backdrop-filter: blur(3px);
  z-index: 5;
}
.potion-row {
  display: flex; align-items: center; gap: 0.28rem; margin-top: 0.22rem; flex-wrap: nowrap;
}
.potion-row .potion-chip { margin-top: 0; padding-top: 0.12rem; padding-bottom: 0.12rem; flex: none; white-space: nowrap; }
.keycaps { display: inline-flex; align-items: center; gap: 0.14rem; flex: none; }
.keycap {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.05rem; height: 1.15rem; padding: 0 0.22rem;
  border-radius: 4px; border: 1px solid #8a8172; border-bottom-width: 2px;
  background: linear-gradient(180deg, #f7f3ea 0%, #d9d1c2 100%);
  color: #1c140c; font: 700 0.58rem/1 Poppins, sans-serif;
  box-shadow: 0 1px 0 rgba(0,0,0,0.45);
  letter-spacing: 0;
}
.pause-tip {
  display: flex; align-items: center; justify-content: center; gap: 0.16rem;
  margin: 0.16rem 0 0; padding: 0;
  font-size: 0.62rem; font-weight: 700; letter-spacing: 0.02em;
  color: rgba(232,236,248,0.9); background: none; border: 0;
}

.stage-rail {
  top: 50%; left: 0.6rem; transform: translateY(-50%);
  width: 34px; padding: 0.4rem 0.3rem; background: rgba(6,8,14,0.55);
  backdrop-filter: blur(2px);
}
.stage-rail .mm-pip { height: 16px; }
.stage-rail .mm-pip[data-hall]::after { font-size: 0.56rem; }

/* Word + timer stay centered; keyboard is a separate BL overlay. */
.stage-bottom-cluster {
  left: 50%; bottom: 0.45rem; transform: translateX(-50%);
  width: min(52%, 20rem);
  display: flex; flex-direction: column; align-items: stretch; gap: 0.28rem;
  z-index: 6;
}

/* .stage-overlay is intentionally click-through for the HUD, but the
   combat word box and input are real controls and must remain clickable. */
.stage-bottom-cluster,
.stage-bottom-cluster .type-row,
.stage-bottom-cluster #type-input {
  pointer-events: auto;
}

.stage-prompt {
  width: 100%; min-height: 0; padding: 0.28rem 0.65rem 0.58rem;
  background: rgba(6,8,14,0.6); backdrop-filter: blur(2px);
  display: flex; flex-direction: column;
}
.potion-row.tip-lift { transform: translateY(-1.15rem); }
.stage-prompt #word-display {
  font-size: clamp(1.12rem, 3vw, 1.5rem); min-height: 1.2em;
  white-space: normal; overflow-wrap: anywhere; word-break: normal;
  padding-bottom: 0.2rem;
}
.stage-prompt .timer { margin: 0.22rem 0 0; height: 7px; }

/* Hands keyboard: compact overlay on the empty floor at bottom-LEFT of #viewport.
   Letter-key board stays hidden — the hands art already includes the keys. */
.stage-keyboard-bl {
  left: 0.4rem; right: auto; bottom: 0.28rem; top: auto;
  width: min(34%, 17.5rem);
  max-width: 280px;
  padding: 0.12rem 0.16rem 0.08rem;
  margin: 0;
  background: rgba(6,8,14,0.28);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 10px;
  overflow: visible;
  min-height: 0;
  z-index: 4;
  pointer-events: none;
  transform: none;
}
.stage-keyboard-bl .kt-board { display: flex !important; position: relative; z-index: 2; gap: 3px; }
.stage-keyboard-bl .kt-row { gap: 3px; }
.stage-keyboard-bl .kt-key { width: 18px; height: 18px; font-size: 0.62rem; }
.stage-keyboard-bl .kt-key-space { width: 88px; height: 14px; }
.stage-pause-tip { margin: 0 0 0.25rem; position: relative; z-index: 3; }
/* Legacy class: hide if an old DOM node is still below the stage. */
.below-stage-keyboard { display: none !important; }

/* Treasure + strike power: bottom-right column. Meter sits above the chest. */
.stage-loot-col {
  right: 0.4rem; bottom: 0.32rem; left: auto; top: auto;
  width: 8rem;
  z-index: 6;
  pointer-events: auto; /* parent .stage-overlay is none; the chest must take the click */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.18rem;
}
.stage-treasure {
  position: relative;
  right: auto; bottom: auto; left: auto; top: auto;
  width: 100%;
  display: block;
  filter: drop-shadow(0 6px 8px rgba(0,0,0,0.45));
}
.strike-power { display: block; }
.strike-power-label {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 0.62rem; font-weight: 800; letter-spacing: 0.04em;
  text-transform: uppercase; color: #f6e7b2;
}
.strike-power-label strong {
  font-variant-numeric: tabular-nums; color: #ffb020; font-size: 0.78rem;
}
.strike-power-track {
  height: 7px; border-radius: 999px; overflow: hidden;
  background: rgba(0,0,0,0.45); border: 1px solid rgba(255,176,32,0.45);
}
.strike-power { --power-charge: 0; position:relative; filter:drop-shadow(0 0 calc(3px + 12px * var(--power-charge)) rgba(245,197,66,calc(.18 + .45 * var(--power-charge)))); }
.strike-power-track { background:repeating-linear-gradient(90deg, rgba(255,255,255,.12) 0 calc(25% - 2px), rgba(8,10,20,.85) calc(25% - 2px) 25%); }
.strike-power-track span { background:linear-gradient(90deg,#f59e0b,#fde68a); box-shadow:0 0 calc(4px + 14px * var(--power-charge)) #f5c542; }
.strike-power.power-burst::after { content:'✦  ✧  ✦'; position:absolute; inset:-1.4rem -1rem auto; color:#fff3a3; font-size:1.3rem; letter-spacing:.5rem; pointer-events:none; animation:power-burst .7s ease-out forwards; }
@keyframes power-burst { from { opacity:1; transform:scale(.7) translateY(.3rem); } to { opacity:0; transform:scale(1.35) translateY(-1.2rem); } }
.strike-power-track span {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, #c2410c, #ffb020);
}
.power-popup {
  position: absolute; z-index: 7; left: 0; top: 0;
  transform: translate(-50%, -50%);
  font: 900 2.6rem/1 Impact, "Arial Black", sans-serif;
  letter-spacing: 0.02em;
  color: #ffe566;
  -webkit-text-stroke: 2px #7a1d00;
  paint-order: stroke fill;
  text-shadow: 3px 3px 0 #3a1200, 0 0 14px rgba(255, 180, 40, 0.9);
  pointer-events: none;
  opacity: 0;
}
.power-popup.show { animation: power-pop 1.3s ease forwards; } /* J-1011-KNIGHT-HIT-LABELS: was .7s */
.timer-third-popup, .hero-damage-popup {
  position: absolute; z-index: 8; left: 0; top: 0; transform: translate(-50%, -50%);
  font: 900 1.45rem/1 Impact, "Arial Black", sans-serif; letter-spacing: .04em;
  pointer-events: none; opacity: 0; white-space: nowrap; paint-order: stroke fill;
}
.timer-third-popup { -webkit-text-stroke: 1px #073b4c; text-shadow: 2px 2px 0 #073b4c, 0 0 10px rgba(34,211,238,.8); }
.timer-third-popup.full { color: #a7f3d0; }
.timer-third-popup.middle { color: #67e8f9; }
.timer-third-popup.last { color: #c4b5fd; }
.hero-damage-popup.show { animation: flair-pop 0.72s ease forwards; }
/* J-1011-KNIGHT-HIT-LABELS: 1/3 · 2/3 · FULL held ~1.8x longer (was flair-pop .72s). */
.timer-third-popup.show { animation: timer-third-pop 1.3s ease forwards; }
@keyframes timer-third-pop {
  0% { opacity: 0; transform: translate(-50%, -20%) scale(.35) rotate(-8deg); }
  14% { opacity: 1; transform: translate(-50%, -60%) scale(1.16) rotate(-3deg); }
  30% { opacity: 1; transform: translate(-50%, -75%) scale(1.08) rotate(-2deg); }
  100% { opacity: 0; transform: translate(-50%, -125%) scale(.94) rotate(5deg); }
}
.hero-damage-popup {
  z-index: 9; color: #ff4d5e; font-size: 2.15rem;
  -webkit-text-stroke: 2px #5b0711;
  text-shadow: 3px 3px 0 #5b0711, 0 0 12px rgba(255,45,65,.9);
}
/* TYPING-MONSTER-DMG-BIG: big cartoony red number over the monster sprite. */
.monster-damage-popup {
  position: absolute; z-index: 10; left: 0; top: 0; transform: translate(-50%, -50%);
  font: 900 3.1rem/1 Impact, "Arial Black", sans-serif; letter-spacing: .03em;
  color: #ff3347; -webkit-text-stroke: 2.5px #3d0209; paint-order: stroke fill;
  text-shadow: 3px 4px 0 #3d0209, -1px -1px 0 #3d0209, 0 0 14px rgba(255,40,60,.95), 0 0 3px #000;
  pointer-events: none; opacity: 0; white-space: nowrap;
}
.monster-damage-popup.show { animation: monster-dmg-pop 1.1s cubic-bezier(.2,.9,.3,1) forwards; }
@keyframes monster-dmg-pop {
  0% { opacity: 0; transform: translate(-50%, -30%) scale(.3) rotate(-10deg); }
  18% { opacity: 1; transform: translate(-50%, -70%) scale(1.28) rotate(-4deg); }
  32% { opacity: 1; transform: translate(-50%, -78%) scale(1) rotate(-2deg); }
  75% { opacity: 1; transform: translate(-50%, -110%) scale(1) rotate(0deg); }
  100% { opacity: 0; transform: translate(-50%, -150%) scale(.92) rotate(3deg); }
}
@media (prefers-reduced-motion: reduce) {
  .monster-damage-popup.show { animation: hp-float-fade 1.1s ease forwards; transform: translate(-50%, -80%); }
}
@keyframes flair-pop {
  0% { opacity: 0; transform: translate(-50%, -20%) scale(.35) rotate(-8deg); }
  25% { opacity: 1; transform: translate(-50%, -60%) scale(1.16) rotate(-3deg); }
  100% { opacity: 0; transform: translate(-50%, -125%) scale(.94) rotate(5deg); }
}
@keyframes power-pop {
  0% { opacity: 0; transform: translate(-50%, -30%) scale(0.35) rotate(-14deg); }
  15% { opacity: 1; transform: translate(-50%, -60%) scale(1.18) rotate(-6deg); }
  40% { opacity: 1; transform: translate(-50%, -75%) scale(1.08) rotate(-1deg); }
  100% { opacity: 0; transform: translate(-50%, -110%) scale(0.95) rotate(8deg); }
}
.treasure-chest-art { display: block; width: 100%; height: auto; }
.treasure-slots {
  position: absolute; left: 13%; right: 13%; top: 27%; height: 30%;
  display: flex; flex-wrap: wrap; align-content: center; justify-content: center; gap: 2px;
  overflow: hidden; pointer-events: none;
}
.treasure-item {
  display: block; width: 18%; max-height: 100%; height: auto; object-fit: contain;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,0.6));
}
.treasure-label {
  --treasure-charge: 0;
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  box-sizing: border-box;
  height: 1.15rem;
  min-height: 1.15rem;
  max-height: 1.15rem;
  margin-top: 2px;
  padding: 0 0.28rem;
  overflow: visible;
  border-radius: 4px;
  background: rgba(6, 12, 24, 0.62);
  border: 1px solid rgba(56, 189, 248, 0.35);
  box-shadow: 0 0 calc(8px * var(--treasure-charge)) rgba(34, 211, 238, calc(0.15 + 0.7 * var(--treasure-charge)));
  font-size: 0.62rem; font-weight: 800; letter-spacing: 0.04em;
  text-transform: uppercase; color: #f6e7b2;
}
.treasure-caption { display: contents; }
.treasure-label strong {
  grid-column: 2;
  justify-self: end;
  min-width: 2.4ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--gold);
  font-size: 0.78rem;
  z-index: 1;
}

.over-stats { list-style: none; padding: 0; margin: 0.75rem 0 1.1rem; color: var(--muted); }
.over-stats li { margin: 0.35rem 0; }
.over-stats strong { color: var(--ink); }
.loot-scroll {
  margin: 0.6rem 0 0; padding: 0.65rem 0.75rem; color: #3c2a16;
  background: #d8bd7d repeating-linear-gradient(0deg, rgba(100,60,18,0.05) 0 1px, transparent 1px 4px);
  border: 1px solid #8b6431; border-radius: 4px; box-shadow: inset 0 0 18px rgba(83,48,12,0.28);
}
.loot-scroll h2 { margin: 0 0 0.35rem; font-size: 0.9rem; color: #4b2910; }
.loot-scroll p { margin: 0; font-style: italic; }
.loot-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.35rem 0.7rem; }
.loot-entry { display: flex; align-items: center; gap: 0.4rem; min-width: 0; }
.loot-entry img { width: 34px; height: 34px; object-fit: contain; flex: none; }
.loot-entry strong, .loot-entry span { display: block; }
.loot-entry strong { font-size: 0.75rem; color: #3c210d; }
.loot-entry span { font-size: 0.66rem; line-height: 1.2; }

/* The escape payoff: the gate opens to a real landscape before the results. */
.screen-win { position: relative; }
.win-vista {
  position: relative; isolation: isolate; min-height: clamp(270px, 44vw, 510px); overflow: hidden;
  border: 1px solid rgba(255,219,135,.46); border-radius: 24px;
  background: #4b493b; box-shadow: 0 22px 75px rgba(245,197,66,.19), 0 22px 65px rgba(0,0,0,.45);
}
.win-vista::before {
  content: ""; position: absolute; inset: -3%;
  background: linear-gradient(180deg, rgba(10,13,27,.12), transparent 38%, rgba(10,13,27,.56)),
              url("../assets/win-sunlight-vista.webp") center 47% / cover no-repeat;
  animation: win-vista-reveal 4.5s ease-out both;
}
.win-vista::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 68% 24%, rgba(255,250,190,.65), rgba(255,227,126,.14) 19%, transparent 47%);
  mix-blend-mode: screen; animation: win-sun-pulse 5s ease-in-out infinite;
}
.win-vista-motes {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(circle at 14% 68%, #fff6c8 0 2px, transparent 4px),
              radial-gradient(circle at 27% 42%, #ffe49d 0 1px, transparent 3px),
              radial-gradient(circle at 38% 79%, #fff6c8 0 2px, transparent 4px),
              radial-gradient(circle at 54% 52%, #fff6c8 0 1px, transparent 3px),
              radial-gradient(circle at 72% 68%, #fff6c8 0 2px, transparent 4px),
              radial-gradient(circle at 87% 38%, #ffe49d 0 1px, transparent 3px);
  animation: win-motes-rise 7s ease-in-out infinite alternate;
}
.screen-win .win-card {
  position: relative; z-index: 2; width: min(1040px, calc(100% - 1.5rem));
  margin: -66px auto 0; padding: clamp(1.25rem, 3vw, 2.2rem);
  background: linear-gradient(160deg, rgba(53,43,32,.94), rgba(17,28,43,.96) 54%, rgba(16,24,39,.98));
  border-color: rgba(255,218,137,.65);
  box-shadow: 0 22px 72px rgba(0,0,0,.55), 0 0 45px rgba(255,204,92,.18);
  animation: win-card-arrive .9s .18s ease-out both;
}
.win-kicker { display: block; margin-bottom: .25rem; color: #ffe8a3; font-size: .72rem; font-weight: 900; letter-spacing: .23em; }
.screen-win h1 { margin-bottom: .2rem; color: #fff4cb; font-size: clamp(2.8rem, 8vw, 5.2rem); line-height: 1; text-shadow: 0 0 26px rgba(255,205,103,.68); }
.screen-win .over-flavor { color: #f2e7cf; font-size: clamp(1rem, 2vw, 1.2rem); font-style: normal; }
.screen-win .over-stats { display: grid; grid-template-columns: repeat(auto-fit,minmax(155px,1fr)); gap: .55rem; }
.screen-win .over-stats li { margin: 0; padding: .65rem .8rem; border: 1px solid rgba(255,226,159,.24); border-radius: 12px; background: rgba(255,236,187,.08); }
.screen-win .over-stats strong { display: block; color: #fff4ce; font-size: 1.05rem; }
@keyframes win-vista-reveal { from { opacity: .28; transform: scale(1.12); filter: brightness(.55); } to { opacity: 1; transform: scale(1); filter: brightness(1); } }
@keyframes win-sun-pulse { 0%,100% { opacity: .35; } 50% { opacity: .76; } }
@keyframes win-motes-rise { from { opacity: .28; transform: translateY(13px); } to { opacity: .85; transform: translateY(-16px); } }
@keyframes win-card-arrive { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 600px) {
  .win-vista { min-height: 300px; }
  .screen-win .win-card { margin-top: -46px; }
  .screen-win .over-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .screen-win .over-stats li:last-child { grid-column: 1 / -1; }
}
@media (prefers-reduced-motion: reduce) { .win-vista::before, .win-vista::after, .win-vista-motes, .screen-win .win-card { animation: none; } }
.screen-over .card { background: linear-gradient(180deg, rgba(60,10,10,0.4), rgba(20,26,46,0.92)); border-color: rgba(248,113,113,0.35); }
.screen-over h1 { color: var(--bad); }
/* J-1012-22: Play again + Return to Museum, centered at the card's top and bottom */
.end-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; width: 100%; }
.end-actions-top { margin: 0 0 1rem; }
.end-actions-bottom { margin: 1.25rem 0 0; }
.end-actions .btn { flex: 0 1 13rem; min-height: 44px; }
@media (max-width: 420px) { .end-actions .btn { flex: 1 1 0; min-width: 0; padding-left: 0.4rem; padding-right: 0.4rem; font-size: 0.9rem; white-space: nowrap; } }

.foot-note { margin-top: 0.9rem; color: var(--muted); font-size: 0.8rem; text-align: center; }

@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
@keyframes walk-forward { 0% { transform: scale(1); } 50% { transform: scale(1.04); } 100% { transform: scale(1); } }
@keyframes turn-left { 0% { transform: rotate(0); } 50% { transform: rotate(-2deg) scale(1.03); } 100% { transform: rotate(0); } }
@keyframes turn-right { 0% { transform: rotate(0); } 50% { transform: rotate(2deg) scale(1.03); } 100% { transform: rotate(0); } }
@keyframes gate-flash { 0%,100% { filter: brightness(0.9); } 50% { filter: brightness(1.6); } }
@keyframes swing-l { 0% { transform: translateX(0) rotate(0); } 40% { transform: translateX(-14px) rotate(-8deg); } 100% { transform: translateX(0) rotate(0); } }
@keyframes swing-r { 0% { transform: translateX(0) rotate(0); } 40% { transform: translateX(14px) rotate(8deg); } 100% { transform: translateX(0) rotate(0); } }
@keyframes kill-cleave { 0% { transform: translateY(0) rotate(0); } 30% { transform: translateY(-10px) rotate(-6deg); } 60% { transform: translateY(4px) rotate(10deg); } 100% { transform: translateY(0) rotate(0); } }
@keyframes kill-fireball { 0% { transform: scale(1); filter: brightness(1); } 40% { transform: scale(1.08); filter: brightness(1.6); } 100% { transform: scale(1); filter: brightness(1); } }
@keyframes gore-pop { 0% { opacity: 0; } 30% { opacity: 1; } 100% { opacity: 0; } }
/* lunge toward the hero (left), wind back first, then recover */
@keyframes monster-strike {
  0% { transform: translateX(0) rotate(0); filter: brightness(1); }
  18% { transform: translateX(8px) rotate(2deg); }
  42% { transform: translateX(-26px) rotate(-4deg) scale(1.04); filter: brightness(1.7); }
  100% { transform: translateX(0) rotate(0); filter: brightness(1); }
}
@keyframes beholder-blast { 0% { transform: translateX(0); filter: brightness(1); } 40% { transform: translateX(var(--beholder-blast-x, -24px)); filter: brightness(1.9); } 100% { transform: translateX(0); filter: brightness(1); } }
@keyframes beholder-ray-pulse { 0% { opacity: 0; transform: rotate(var(--ray-angle, 180deg)) scaleX(.86); } 22% { opacity: 1; } 60% { opacity: 1; transform: rotate(var(--ray-angle, 180deg)) scaleX(1); } 100% { opacity: 0; transform: rotate(var(--ray-angle, 180deg)) scaleX(1.03); } }
@keyframes kt-wrong-flash { 0%,100% { transform: scale(1.12); } 50% { transform: scale(1.24); } }

/* 1280×800 fold: class/hall HUD stays on screen with HP + potions. */
@media (max-height: 850px) {
  body:has(#screen-dungeon.active) .app { padding: 0.4rem 0 0.55rem; }
  body:has(#screen-dungeon.active) .topbar { margin-bottom: 0.35rem; }
  #screen-dungeon .card { padding: 0.55rem 0.85rem 0.65rem; }
  #screen-dungeon .stage-hud-player,
  #screen-dungeon .stage-hud-monster { padding: 0.28rem 0.45rem 0.32rem; border-radius: 10px; }
  #screen-dungeon .stage-hud-player { width: 28%; max-width: 30%; top: 0.3rem; left: 0.3rem; }
  #screen-dungeon .stage-hud-monster { width: 28%; max-width: 30%; top: 0.3rem; right: 0.3rem; }
  #screen-dungeon .hud-meta { margin-bottom: 0.12rem; font-size: 0.72rem; gap: 0.25rem 0.4rem; }
  #screen-dungeon .bar { height: 9px; }
  #screen-dungeon .bar.chip-bar { height: 11px; }
  #screen-dungeon .potion-row { margin-top: 0.12rem; }
  #screen-dungeon .potion-row .potion-chip { margin-top: 0; padding-top: 0.1rem; padding-bottom: 0.1rem; }
  #screen-dungeon .dungeon-row { margin-bottom: 0.2rem; }
  #screen-dungeon .stage-keyboard-bl { width: min(32%, 16rem); max-width: 250px; bottom: 0.2rem; left: 0.3rem; }
  #screen-dungeon .stage-loot-col { bottom: 0.2rem; right: 0.25rem; width: 7.2rem; }
  #screen-dungeon #type-input { min-height: 32px; height: 34px; padding: 0.18rem 0.65rem; font-size: 1rem; }
  #screen-dungeon .hint { display: none; }
  body:has(#screen-dungeon.active):not(.fit-combat-below) { overflow: hidden; }
}

@media (max-width: 640px) {
  /* Desktop 30% cap must not shrink the phone deck. Widths below stay as they were. */
  #screen-dungeon .stage-hud-player,
  #screen-dungeon .stage-hud-monster { max-width: none; }
  .viewport { min-height: 380px; height: clamp(380px, 58vh, 480px); }
  /* pose layout via JS; under-sprite name pills stay hidden */
  .kt-key { width: 24px; height: 24px; font-size: 0.72rem; }
  .stage-rail { width: 26px; left: 0.35rem; }
  .stage-rail .mm-pip { height: 13px; }
  .fighters { /* no compact lift */ }
  .stage-bottom-cluster {
    left: 0.28rem; right: auto; transform: none;
    width: calc(100% - 7.2rem); bottom: 6.6rem; gap: 0.22rem;
    z-index: 6;
  }
  .stage-hud-player { width: min(72%, 16.5rem); }
  .stage-hud-monster { width: min(40%, 11.5rem); }
  .stage-hud-player .hud-meta,
  .stage-hud-player .bar-label,
  .stage-hud-monster .bar-label { white-space: nowrap; }
  .stage-hud-player .bar-label,
  .stage-hud-monster .bar-label { font-size: 0.68rem; }
  .stage-hud-player .hud-meta { font-size: 0.64rem; }
  .stage-loot-col { width: 6.35rem; right: 0.18rem; bottom: 0.2rem; }
  .stage-treasure .treasure-label { font-size: 0.58rem; }
  .stage-keyboard-bl { width: min(42%, 14rem); max-width: 220px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* kbstage1: below-stage strip is gone. */
.below-stage-keyboard .kt-board { display: none !important; }
.below-stage-keyboard {
  display: none !important;
}
@media (max-width: 900px) {
}

/* ===== Typing Treasure (TYPING-TREASURE-BUILD Phase 1) ===== */
.tt-r-common   { color: #e8c39a; }
.tt-r-uncommon { color: #e5e7eb; }
.tt-r-rare     { color: #f5c542; }
.tt-r-epic     { color: #34d399; }
.tt-r-legendary{ color: #d8b4fe; }

.tt-chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font: 700 0.68rem var(--mono); letter-spacing: 0.02em;
  padding: 0.12rem 0.45rem; border-radius: 999px;
  background: rgba(0,0,0,0.35); border: 1px solid currentColor;
}
.tt-chip-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }

/* Streak charge sits behind Treasure and the count. It must not share their row. */
#treasure-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0%;
  height: 100%;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(90deg, #0369a1 0%, #22d3ee 46%, #4ade80 100%);
  box-shadow: inset 0 0 8px rgba(255,255,255,0.25), 0 0 calc(4px + 14px * var(--treasure-charge, 0)) rgba(74, 222, 128, calc(0.15 + 0.75 * var(--treasure-charge, 0)));
  opacity: calc(0.5 + 0.45 * var(--treasure-charge, 0));
  transition: width 0.28s ease, opacity 0.28s ease, box-shadow 0.28s ease;
}
#tt-nameplate {
  grid-column: 1;
  justify-self: start;
  position: relative;
  z-index: 1;
}
.treasure-burst {
  position: absolute;
  left: 50%; top: 50%;
  width: 6px; height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  pointer-events: none;
  z-index: 2;
  opacity: 0;
}
.treasure-label.tt-hot {
  animation: tt-charge-glow 0.75s ease-in-out infinite;
}
@keyframes tt-charge-glow {
  0%, 100% { box-shadow: 0 0 4px rgba(34, 211, 238, 0.35); }
  50% { box-shadow: 0 0 14px rgba(74, 222, 128, 0.9); }
}
.treasure-label.tt-burst .treasure-burst {
  animation: tt-bar-burst 0.55s ease-out forwards;
}
@keyframes tt-bar-burst {
  0% {
    opacity: 1;
    background: #fff;
    transform: scale(0.3);
    box-shadow: 0 0 0 0 #4ade80, 0 0 0 0 #22d3ee, 0 0 0 0 #fde68a;
  }
  40% {
    opacity: 1;
    background: #fff;
    transform: scale(1);
    box-shadow:
      -26px -12px 0 0 #4ade80,
      24px -10px 0 0 #22d3ee,
      -16px 12px 0 0 #fde68a,
      20px 11px 0 0 #fff,
      0 -20px 0 0 #67e8f9,
      0 16px 0 0 #86efac;
  }
  100% {
    opacity: 0;
    transform: scale(1.15);
    box-shadow:
      -38px -20px 0 0 transparent,
      36px -16px 0 0 transparent,
      -24px 18px 0 0 transparent,
      30px 16px 0 0 transparent,
      0 -30px 0 0 transparent,
      0 24px 0 0 transparent;
  }
}
@media (prefers-reduced-motion: reduce) {
  .treasure-label.tt-hot { animation: none; }
  .treasure-label.tt-burst .treasure-burst { animation: none; opacity: 0; }
}

#treasure-chest.tt-deposit .treasure-chest-art { animation: tt-chest-pop 0.9s ease; }
#treasure-chest.tt-opening::before { content: ""; position: absolute; left: 16%; right: 16%; top: 25%; height: 34%; z-index: 1; border-radius: 50%; background: radial-gradient(ellipse, rgba(255,248,174,.98) 0 12%, rgba(255,194,54,.82) 28%, rgba(245,150,20,.3) 49%, transparent 70%); filter: blur(2px); animation: tt-chest-shimmer 1.05s ease both; pointer-events: none; }
#treasure-chest.tt-opening .treasure-chest-art { animation: tt-chest-open 1.05s ease both; }
@keyframes tt-chest-open { 0% { transform: translateY(0) scale(1); } 24% { transform: translateY(-9px) scale(1.04); filter: drop-shadow(0 0 18px rgba(255,214,74,.95)); } 68% { transform: translateY(-3px) scale(1.015); filter: drop-shadow(0 0 25px rgba(255,240,152,.9)); } 100% { transform: translateY(0) scale(1); } }
@keyframes tt-chest-shimmer { 0% { opacity: 0; transform: scale(.45); } 26% { opacity: 1; transform: scale(1.15); } 72% { opacity: .85; transform: scale(.95); } 100% { opacity: 0; transform: scale(.65); } }
@keyframes tt-chest-pop {
  0% { transform: scale(1); filter: drop-shadow(0 6px 8px rgba(0,0,0,0.45)); }
  30% { transform: scale(1.08) translateY(-2px); filter: drop-shadow(0 0 14px rgba(245,197,66,0.85)); }
  60% { transform: scale(0.98); }
  100% { transform: scale(1); filter: drop-shadow(0 6px 8px rgba(0,0,0,0.45)); }
}
.tt-drop-coin {
  position: absolute; left: 50%; top: -0.4rem; width: 1.5rem; height: 1.5rem;
  transform: translateX(-50%); z-index: 5; pointer-events: none;
  animation: tt-coin-drop 0.9s ease forwards;
}
.tt-drop-coin svg { width: 100%; height: 100%; }
@keyframes tt-coin-drop {
  0% { top: -0.6rem; opacity: 0; transform: translateX(-50%) scale(0.6) rotate(0deg); }
  25% { opacity: 1; }
  70% { top: 46%; opacity: 1; transform: translateX(-50%) scale(1) rotate(200deg); }
  100% { top: 46%; opacity: 0; transform: translateX(-50%) scale(0.7) rotate(260deg); }
}
#treasure-count.tt-flash { display: inline-block; animation: tt-count-flash 0.7s ease; }
@keyframes tt-count-flash { 0% { color: #fff; transform: scale(1.7); text-shadow: 0 0 10px #fff; } 100% { color: var(--gold); transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  #treasure-chest.tt-deposit .treasure-chest-art { animation: none; }
  .tt-drop-coin { animation: tt-coin-fade 1s ease forwards; }
  #treasure-count.tt-flash { animation: none; }
}
@keyframes tt-coin-fade { 0% { opacity: 0; } 30% { opacity: 1; } 100% { opacity: 0; } }

/* Large fade toast on earn -- no modal, sits above the stage. */
.tt-toast {
  position: absolute; left: 50%; top: 14%; transform: translate(-50%, -8px);
  z-index: 9; min-width: 14rem; max-width: 88%;
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.9rem; border-radius: 12px;
  background: rgba(12,16,32,0.92); border: 1px solid rgba(245,197,66,0.5);
  box-shadow: 0 12px 30px rgba(0,0,0,0.45);
  color: var(--ink); font-weight: 700; font-size: 0.92rem;
  opacity: 0; pointer-events: none;
}
.tt-toast.show { animation: tt-toast-fade 3000ms ease; }
.tt-toast[data-rarity="rare"] { border-color: rgba(245,197,66,.85); box-shadow: 0 12px 30px rgba(0,0,0,.45), 0 0 14px rgba(245,197,66,.25); }
.tt-toast[data-rarity="epic"] { border-color: rgba(52,211,153,.85); box-shadow: 0 12px 30px rgba(0,0,0,.45), 0 0 20px rgba(52,211,153,.44); }
.tt-toast[data-rarity="legendary"] { border-color: rgba(216,180,254,.95); background: linear-gradient(125deg,rgba(40,19,68,.96),rgba(12,22,42,.96)); box-shadow: 0 12px 30px rgba(0,0,0,.45), 0 0 30px rgba(192,132,252,.68); }
.tt-toast.show[data-rarity="epic"] .tt-toast-coin svg { animation: tt-grid-epic 3.4s ease-in-out infinite; }
.tt-toast.show[data-rarity="legendary"] .tt-toast-coin svg { animation: tt-grid-legendary 2.7s ease-in-out infinite; }
@keyframes tt-toast-fade {
  0% { opacity: 0; transform: translate(-50%, -8px); }
  15% { opacity: 1; transform: translate(-50%, 0); }
  80% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -8px); }
}
@media (prefers-reduced-motion: reduce) {
  .tt-toast.show { animation: tt-toast-fade-simple 3000ms ease; }
  .tt-toast.show .tt-toast-coin svg { animation: none; }
}
@keyframes tt-toast-fade-simple { 0% { opacity: 0; } 15% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; } }
.tt-toast-coin { width: 2rem; height: 2rem; flex: none; }
.tt-toast-coin svg { width: 100%; height: 100%; }

/* Pause / death haul box -- this run's collected treasure, sorted by rarity. */
.tt-haul { margin: 0.6rem 0 0; }
.tt-haul h3 { margin: 0 0 0.4rem; font-size: 0.85rem; color: var(--ink); }
.tt-haul-empty { color: var(--muted); font-size: 0.82rem; font-style: italic; margin: 0; }
.tt-haul-group { margin-bottom: 0.5rem; }
.tt-haul-group-label { font: 700 0.68rem var(--mono); letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 0.3rem; }
.tt-rarity-count { font-variant-numeric: tabular-nums; letter-spacing: 0; }
.tt-haul-grid { display: flex; flex-wrap: wrap; gap: 0.45rem; }
.tt-haul-item {
  position: relative; width: 2.6rem; height: 2.6rem; border-radius: 50%;
  background: transparent; border: none; padding: 0; cursor: pointer;
}
.tt-haul-item svg { width: 100%; height: 100%; display: block; }
.tt-haul-item.tt-rarity-rare svg { filter: drop-shadow(0 0 3px rgba(245,197,66,.44)); }
.tt-haul-item.tt-rarity-epic svg { animation: tt-grid-epic 3.4s ease-in-out infinite; }
.tt-haul-item.tt-rarity-legendary svg { animation: tt-grid-legendary 2.7s ease-in-out infinite; }
@keyframes tt-grid-epic { 0%,100% { filter: brightness(1) drop-shadow(0 0 3px rgba(52,211,153,.35)); } 50% { filter: brightness(1.16) drop-shadow(0 0 7px rgba(52,211,153,.8)); } }
@keyframes tt-grid-legendary { 0%,100% { filter: brightness(1) saturate(1.05) drop-shadow(0 0 4px rgba(192,132,252,.5)); } 50% { filter: brightness(1.23) saturate(1.3) drop-shadow(0 0 10px rgba(216,180,254,.95)); } }
@media (prefers-reduced-motion: reduce) { .tt-haul-item.tt-rarity-epic svg, .tt-haul-item.tt-rarity-legendary svg { animation: none; } }
.tt-haul-item .tt-count {
  position: absolute; right: -0.25rem; bottom: -0.25rem; min-width: 1.1rem; height: 1.1rem;
  border-radius: 999px; background: #0b1020; border: 1px solid var(--line);
  font: 700 0.62rem var(--mono); color: var(--ink); display: flex; align-items: center; justify-content: center;
  padding: 0 0.2rem;
}
.tt-haul-item:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.tt-haul-name {
  background: none; border: 0; padding: 0.1rem 0; margin: 0;
  color: var(--ink); font: 600 0.82rem/1.3 inherit; cursor: pointer; text-align: left;
}
.tt-haul-flavor { margin: 0.1rem 0 0; color: var(--muted); font-size: 0.74rem; font-style: italic; }

/* J-1012-22: end-of-run haul = every coin with its name underneath, in a tidy grid. */
.tt-haul-grid-named { display: grid; grid-template-columns: repeat(auto-fill, minmax(4.6rem, 1fr)); gap: 0.4rem 0.3rem; }
.tt-haul-tile {
  display: flex; flex-direction: column; align-items: center; gap: 0.2rem; min-width: 0;
  background: none; border: 0; padding: 0.15rem 0.1rem; margin: 0; border-radius: 6px;
  color: var(--ink); cursor: pointer;
}
.tt-haul-tile .tt-haul-item { display: block; cursor: inherit; }
.tt-haul-tile:hover { background: rgba(255,255,255,0.05); }
.tt-haul-tile:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }
.tt-haul-label {
  max-width: 100%; font-size: 0.66rem; font-weight: 600; line-height: 1.2; text-align: center; color: var(--ink);
  overflow-wrap: break-word; hyphens: auto;
}
@media (max-width: 520px) {
  .tt-haul-grid-named { grid-template-columns: repeat(auto-fill, minmax(4.1rem, 1fr)); }
  .tt-haul-grid-named .tt-haul-item { width: 2.3rem; height: 2.3rem; }
}

.tt-open-chest {
  position: absolute; left: 0; right: 0; top: 0; bottom: 1.25rem;
  background: transparent; border: 0; color: transparent; cursor: pointer;
}
.tt-open-chest:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
#tt-nameplate {
  overflow: visible; text-overflow: clip; white-space: nowrap;
  max-width: none; display: inline; vertical-align: baseline;
}
.tt-relic {
  display: flex; align-items: center; gap: 0.25rem;
  background: rgba(8,10,18,0.9);
  border: 1px solid rgba(245,197,66,0.45);
  border-radius: 8px; padding: 0.08rem 0.15rem 0.08rem 0.35rem;
  font-size: 0.62rem; font-weight: 700; color: #f6e7b2;
}
.tt-relic[hidden] { display: none !important; }
.tt-relic strong { font-variant-numeric: tabular-nums; color: var(--gold); margin-right: auto; }
#tt-relic-use, .tt-sheet-use, #hall-exchange-confirm, #tt-sheet-close { min-height: 44px; }
#tt-relic-use { font-size: 0.72rem; padding: 0 0.55rem; }

.stage-treasure.tt-skin-uncommon { box-shadow: 0 0 0 1px #4ade80; }
.stage-treasure.tt-skin-rare { box-shadow: 0 0 0 1px #60a5fa; }
.stage-treasure.tt-skin-epic { box-shadow: 0 0 0 1px #c084fc; }
.stage-treasure.tt-skin-legendary { box-shadow: 0 0 0 1px #ffd76a; }
.strike-power.tt-trim-uncommon { outline: 1px solid rgba(74,222,128,0.8); outline-offset: 1px; }
.strike-power.tt-trim-rare { outline: 1px solid rgba(96,165,250,0.85); outline-offset: 1px; }
.strike-power.tt-trim-epic { outline: 1px solid rgba(192,132,252,0.85); outline-offset: 1px; }
.strike-power.tt-trim-legendary { outline: 1px solid rgba(255,215,106,0.9); outline-offset: 1px; }

.hall-exchange, .tt-sheet {
  position: fixed; inset: 0; z-index: 45;
  display: flex; align-items: center; justify-content: center;
  background: rgba(6,8,14,0.72); padding: 1rem;
}
.hall-exchange[hidden], .tt-sheet[hidden] { display: none !important; }
.hall-exchange-card, .tt-sheet-card {
  width: min(24rem, 100%);
  background: #16122a; color: var(--ink);
  border: 1px solid rgba(245,197,66,0.4);
  border-radius: 10px; padding: 0.7rem 0.8rem;
}
.hall-exchange-card h2, .tt-sheet-card h2 { margin: 0 0 0.2rem; font-size: 1.05rem; }
.hall-exchange-lead, .tt-sheet-foot, #tt-sheet-summary { margin: 0.15rem 0 0.45rem; color: var(--muted); font-size: 0.78rem; }
.hall-exchange fieldset {
  border: 1px solid rgba(255,255,255,0.12); border-radius: 8px;
  margin: 0.35rem 0; padding: 0.35rem 0.6rem 0.45rem;
}
.hall-exchange label { display: flex; gap: 0.45rem; align-items: center; min-height: 44px; font-size: 0.88rem; }
#hall-exchange-detail { margin: 0.3rem 0 0.55rem; font-size: 0.82rem; line-height: 1.35; }
.tt-sheet-list { list-style: none; margin: 0.3rem 0 0.6rem; padding: 0; max-height: 42vh; overflow: auto; }
.tt-sheet-row {
  display: flex; justify-content: space-between; gap: 0.5rem; align-items: center;
  padding: 0.35rem 0; border-bottom: 1px solid rgba(255,255,255,0.08);
}
.tt-sheet-row p { margin: 0.12rem 0 0; color: var(--muted); font-size: 0.75rem; }
.tt-sheet-name { background: none; border: 0; color: var(--ink); font-weight: 700; text-align: left; padding: 0; cursor: pointer; }

/* Full-screen coin detail with front/back flip. */
.tt-detail-overlay {
  position: fixed; inset: 0; z-index: 60; display: none;
  align-items: center; justify-content: center; flex-direction: column; gap: 1rem;
  background: rgba(6,8,18,0.86); backdrop-filter: blur(2px);
  overflow: hidden;
  isolation: isolate;
}
.tt-detail-overlay.show { display: flex; }
.tt-detail-close {
  position: absolute; top: 1rem; right: 1rem; min-height: 40px; min-width: 40px;
  border-radius: 999px; background: rgba(255,255,255,0.1); color: var(--ink); font-size: 1.4rem;
}
.tt-coin-stage { width: min(60vw, 260px); height: min(60vw, 260px); perspective: 900px; cursor: pointer; overflow: visible; position: relative; z-index: 1; }
.tt-coin-flip {
  position: relative; width: 100%; height: 100%; transform-style: preserve-3d; overflow: visible;
  transition: transform 0.6s cubic-bezier(0.4,0.2,0.2,1);
}
.tt-coin-flip.is-flipped { transform: rotateY(180deg); }
.tt-coin-face { position: absolute; inset: 0; backface-visibility: hidden; filter: drop-shadow(0 10px 24px rgba(0,0,0,0.5)); clip-path: circle(50% at 50% 50%); }
.tt-coin-face svg { display: block; width: 100%; height: 100%; overflow: visible; }
.tt-coin-face.tt-back { transform: rotateY(180deg); }
.tt-coin-stage[data-fx="charge"] .tt-coin-face svg { animation: tt-fx-rare 4.8s ease-in-out infinite; }
.tt-coin-stage[data-fx="arcane"] .tt-coin-face svg { animation: tt-fx-epic 3.4s ease-in-out infinite; }
.tt-coin-stage[data-fx="prism"] .tt-coin-face svg { animation: tt-fx-prism 2.7s ease-in-out infinite; }
.tt-coin-stage[data-fx]::before { content: ""; position: absolute; inset: -8%; border-radius: 50%; z-index: -1; pointer-events: none; animation: tt-fx-halo 3s ease-in-out infinite; }
.tt-coin-stage[data-fx="charge"]::before { background: radial-gradient(circle, rgba(255,196,72,0.32) 0%, transparent 69%); animation-duration: 4.8s; }
.tt-coin-stage[data-fx="arcane"]::before { background: radial-gradient(circle, rgba(42,245,159,0.52) 0%, transparent 70%); animation-duration: 3.4s; }
.tt-coin-stage[data-fx="prism"]::before { background: radial-gradient(circle, rgba(197,109,255,0.63) 0%, rgba(95,176,255,0.24) 48%, transparent 72%); animation-duration: 2.7s; }
.tt-coin-stage[data-fx="arcane"]::after,
.tt-coin-stage[data-fx="prism"]::after {
  content: ""; position: absolute; inset: -8%; pointer-events: none; z-index: 2;
  background: radial-gradient(circle at 14% 27%, #fff 0 1px, transparent 3px),
              radial-gradient(circle at 84% 18%, #fff 0 1.5px, transparent 4px),
              radial-gradient(circle at 75% 85%, #fff 0 1px, transparent 3px);
  animation: tt-fx-sparks 3.4s ease-in-out infinite;
}
.tt-coin-stage[data-fx="arcane"]::after { opacity: 0.42; }
.tt-coin-stage[data-fx="prism"]::after {
  background: radial-gradient(circle at 14% 27%, #fff 0 2px, transparent 5px),
              radial-gradient(circle at 84% 18%, #d8b4fe 0 2px, transparent 5px),
              radial-gradient(circle at 75% 85%, #a5f3fc 0 2px, transparent 5px),
              radial-gradient(circle at 19% 76%, #fff 0 1px, transparent 4px),
              radial-gradient(circle at 50% 8%, #fff 0 1px, transparent 4px);
  animation-duration: 2.7s;
}
@keyframes tt-fx-rare { 0%,100% { filter: brightness(1); } 50% { filter: brightness(1.12); } }
@keyframes tt-fx-epic { 0%,100% { filter: brightness(1) saturate(1); } 45% { filter: brightness(1.2) saturate(1.18); } }
@keyframes tt-fx-prism { 0%,100% { filter: brightness(1) saturate(1); } 30% { filter: brightness(1.24) saturate(1.2); } 65% { filter: brightness(1.08) saturate(1.32); } }
@keyframes tt-fx-halo { 0%,100% { opacity: 0.2; } 50% { opacity: 0.75; } }
@keyframes tt-fx-sparks { 0%,100% { opacity: 0.2; transform: scale(0.96); } 50% { opacity: 1; transform: scale(1.04); } }
@media (prefers-reduced-motion: reduce) { .tt-coin-stage[data-fx] .tt-coin-face svg, .tt-coin-stage[data-fx]::before, .tt-coin-stage[data-fx]::after { animation: none; } }
@media (prefers-reduced-motion: reduce) {
  .tt-coin-flip { transition: none; }
}
.tt-detail-name { color: var(--ink); font-weight: 800; font-size: 1.1rem; text-align: center; }
.tt-detail-tip { color: var(--muted); font-size: 0.78rem; }
.tt-coin-stage.tt-detail-egg { width: min(72vw, 320px); height: min(72vw, 320px); }

.tt-museum { margin: 0.8rem 0 0.4rem; text-align: left; }
.tt-museum h2 { margin: 0 0 0.2rem; font-size: 1.05rem; }
.tt-museum-lead, .tt-keep-note { margin: 0 0 0.45rem; color: var(--muted); font-size: 0.82rem; }
.tt-code-form, .tt-keep-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: end; margin-top: 0.45rem; }
.tt-code-form label, .tt-keep-actions label { display: flex; flex-direction: column; gap: 0.15rem; font-size: 0.75rem; color: var(--muted); }
.tt-code-form input, .tt-keep-actions input { min-height: 36px; min-width: 12rem; }
.tt-burn-bar { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; margin: 0.35rem 0; font-size: 0.75rem; }
.tt-armed-chip, .tt-burn-btn, .tt-unburn {
  min-height: 32px; border-radius: 999px; border: 1px solid rgba(245,197,66,0.45);
  background: rgba(0,0,0,0.25); color: var(--ink); font-size: 0.72rem; padding: 0 0.55rem;
}
.tt-museum-cell { display: flex; flex-direction: column; align-items: center; gap: 0.15rem; width: 3.1rem; }
.tt-haul-item.tt-egg, .tt-museum-cell.tt-egg .tt-haul-item { width: 3.3rem; height: 3.3rem; }
.tt-unburn { display: inline-flex; align-items: center; color: #f5c542; }
.tt-burn-choices { display: flex; flex-direction: column; gap: 0.35rem; margin: 0.4rem 0; font-size: 0.82rem; }
.tt-burn-choices label { display: flex; gap: 0.4rem; align-items: flex-start; }
.tt-restore-card { width: min(36rem, 100%); max-height: 80vh; overflow: auto; }
.tt-keep { margin-top: 0.7rem; }
.tt-keep h3 { margin: 0 0 0.3rem; font-size: 0.95rem; }
.tt-keep-qr { background: #fff; display: inline-block; padding: 6px; border-radius: 8px; }
.tt-keep-qr svg { display: block; }
.tt-keep-code { font: 0.72rem/1.35 ui-monospace, monospace; word-break: break-all; color: var(--muted); }
.tt-keep-status { min-height: 1.1rem; font-size: 0.78rem; color: var(--gold); }
.stage-treasure.tt-skin-uncommon { box-shadow: 0 0 0 1px #d5dde8; }
.stage-treasure.tt-skin-rare { box-shadow: 0 0 0 1px #f5c542; }
.stage-treasure.tt-skin-epic { box-shadow: 0 0 0 1px #34d399; }
.stage-treasure.tt-skin-legendary { box-shadow: 0 0 0 1px #d8b4fe; }

/* Live combat HUD: rarity skins must not draw a card-like trim around the
   power meter or chest, and the transparent chest hit target must not flash
   a browser focus ring over the art. */
.stage-loot-col #strike-power,
.stage-loot-col #treasure-chest {
  border: 0 !important;
  outline: none !important;
  box-shadow: none !important;
}
.stage-loot-col #strike-power.tt-trim-uncommon,
.stage-loot-col #strike-power.tt-trim-rare,
.stage-loot-col #strike-power.tt-trim-epic,
.stage-loot-col #strike-power.tt-trim-legendary,
.stage-loot-col #treasure-chest.tt-skin-uncommon,
.stage-loot-col #treasure-chest.tt-skin-rare,
.stage-loot-col #treasure-chest.tt-skin-epic,
.stage-loot-col #treasure-chest.tt-skin-legendary {
  border: 0 !important;
  outline: none !important;
  box-shadow: none !important;
}
.stage-loot-col #btn-open-chest:focus,
.stage-loot-col #btn-open-chest:focus-visible,
.stage-loot-col #strike-power:focus,
.stage-loot-col #treasure-chest:focus {
  outline: none !important;
  box-shadow: none !important;
}

/* ---- UI polish: button feedback, form fields, keep panel ---------------- */
.btn,
.player-list button,
.tt-armed-chip, .tt-burn-btn, .tt-unburn,
#tt-relic-use {
  transition: transform .12s ease, filter .15s ease, box-shadow .15s ease, background-color .15s ease, border-color .15s ease, color .15s ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:not(:disabled):hover { filter: brightness(1.08); transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0,0,0,.35); }
.btn:not(:disabled):active { filter: brightness(.94); transform: translateY(1px) scale(.98); box-shadow: 0 1px 4px rgba(0,0,0,.4); }
.btn-primary:not(:disabled):hover { box-shadow: 0 6px 20px rgba(245,158,11,.35); }
.btn-warrior:not(:disabled):hover { box-shadow: 0 8px 24px rgba(224,122,58,.4); }
.btn-mage:not(:disabled):hover { box-shadow: 0 8px 24px rgba(139,92,246,.45); }
.btn-ghost:not(:disabled):hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.28); filter: none; }
.btn:focus-visible,
.player-list button:focus-visible,
.tt-armed-chip:focus-visible, .tt-burn-btn:focus-visible, .tt-unburn:focus-visible,
#tt-relic-use:focus-visible {
  outline: 2px solid var(--gold); outline-offset: 2px;
}
/* A bare .btn with no variant used to fall back to the browser's grey. */
.btn:not(.btn-primary):not(.btn-ghost):not(.btn-warrior):not(.btn-mage) {
  background: rgba(255,255,255,.08); color: var(--ink); border: 1px solid var(--line);
}
.btn:not(.btn-primary):not(.btn-ghost):not(.btn-warrior):not(.btn-mage):not(:disabled):hover {
  background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.28); filter: none;
}
.btn.is-done { background: linear-gradient(135deg, #10b981, var(--ok)); color: #04130c; }

.player-list button:hover, .player-list button:focus-visible { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.26); }
.player-list button:active { transform: scale(.98); }
.tt-armed-chip:hover, .tt-burn-btn:hover, .tt-unburn:hover { background: rgba(245,197,66,.14); border-color: var(--gold); color: #fff; }
.tt-armed-chip:active, .tt-burn-btn:active, .tt-unburn:active { transform: scale(.95); }
#tt-relic-use:hover { filter: brightness(1.12); }
#tt-relic-use:active { transform: scale(.95); }

/* Shared text-field look (was the bright white browser default). */
.tt-code-form input, .tt-keep-send input, .player-new input {
  min-height: 42px; padding: 0 .8rem; border-radius: 10px;
  border: 1px solid var(--line); background: #0e1426; color: var(--ink); font: inherit; font-size: .9rem;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.player-new input { min-height: 32px; font-size: .85rem; padding: 0 .5rem; }
.tt-code-form input::placeholder, .tt-keep-send input::placeholder { color: rgba(154,163,199,.6); }
.tt-code-form input:hover, .tt-keep-send input:hover, .player-new input:hover { border-color: rgba(255,255,255,.24); }
.tt-code-form input:focus, .tt-keep-send input:focus, .player-new input:focus {
  outline: none; border-color: rgba(245,197,66,.7); box-shadow: 0 0 0 3px rgba(245,197,66,.18);
}
.tt-keep-send input:disabled { opacity: .6; }

/* Museum section reads as its own panel. */
.tt-museum { margin: 1.1rem 0 .6rem; padding: 1rem 1.1rem 1.1rem; border: 1px solid var(--line); border-radius: 14px; background: rgba(0,0,0,.18); }
.tt-museum h2 { font-size: 1.15rem; }

/* Keep panel: QR on the left, code + actions on the right. */
.tt-keep {
  display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 1.1rem; align-items: start;
  grid-template-areas: "qr title" "qr note" "qr code" "qr actions" "qr status";
  margin-top: 1rem; padding: 1rem; border: 1px solid rgba(245,197,66,.28); border-radius: 12px;
  background: linear-gradient(180deg, rgba(245,197,66,.06), rgba(245,197,66,.015));
}
.tt-keep[hidden] { display: none; }
.tt-keep > h3 { grid-area: title; margin: 0 0 .25rem; font-size: 1rem; }
.tt-keep > .tt-keep-note { grid-area: note; }
.tt-keep > .tt-keep-qr { grid-area: qr; }
.tt-keep > .tt-keep-code { grid-area: code; margin: .15rem 0 .1rem; padding: .45rem .6rem; border-radius: 8px; background: rgba(0,0,0,.28); color: #cdd3ee; letter-spacing: .02em; user-select: all; }
.tt-keep > .tt-keep-actions { grid-area: actions; align-items: center; }
.tt-keep > .tt-keep-status { grid-area: status; }
.tt-keep-qr svg { width: 150px; height: 150px; }
.tt-keep-send { display: flex; flex: 1 1 18rem; gap: .4rem; min-width: 0; }
.tt-keep-send input { flex: 1; min-width: 0; }
.tt-keep-actions .btn { min-height: 42px; }

/* Status line: a visible banner, not faint text. */
.tt-keep-status { margin: .5rem 0 0; font-size: .85rem; font-weight: 600; border-radius: 10px; min-height: 0; }
.tt-keep-status:empty { display: none; }
.tt-keep-status.is-ok, .tt-keep-status.is-error, .tt-keep-status.is-busy { padding: .55rem .8rem; border: 1px solid; animation: tt-status-in .2s ease-out; }
.tt-keep-status.is-ok { color: #a7f3d0; background: rgba(52,211,153,.12); border-color: rgba(52,211,153,.45); }
.tt-keep-status.is-error { color: #fecaca; background: rgba(248,113,113,.12); border-color: rgba(248,113,113,.45); }
.tt-keep-status.is-busy { color: var(--muted); background: rgba(255,255,255,.04); border-color: var(--line); }
@keyframes tt-status-in { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }

/* Code entry: label on top, field + button on one row. */
.tt-code-form { display: block; margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.tt-code-form > label { display: block; margin-bottom: .35rem; font-size: .8rem; font-weight: 600; color: var(--muted); }
.tt-code-row { display: flex; gap: .4rem; max-width: 34rem; }
.tt-code-row input { flex: 1; min-width: 0; }

#btn-howto { margin-top: .3rem; }

@media (max-width: 620px) {
  .tt-keep { grid-template-columns: minmax(0, 1fr); grid-template-areas: "title" "note" "qr" "code" "actions" "status"; }
  .tt-keep > .tt-keep-qr { justify-self: center; margin: .3rem 0 .5rem; }
  .tt-keep-actions > .btn { flex: 1 1 100%; }
  .tt-keep-send { flex-wrap: wrap; flex-basis: 100%; }
  .tt-keep-send input, .tt-keep-send .btn { flex: 1 1 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .btn, .player-list button, .tt-armed-chip, .tt-burn-btn, .tt-unburn, #tt-relic-use { transition: none; }
  .btn:not(:disabled):hover, .btn:not(:disabled):active { transform: none; }
  .tt-keep-status { animation: none !important; }
}
.tt-restore-warn { margin: .8rem 0 .2rem; padding: .6rem .8rem; border: 1px solid rgba(248,113,113,.45); border-radius: 10px; background: rgba(248,113,113,.12); color: #fecaca; font-size: .85rem; font-weight: 600; }
.tt-restore-warn[hidden] { display: none; }
.tt-keep > .tt-keep-note, .tt-keep > .tt-keep-code, .tt-keep > .tt-keep-status { max-width: none; }
#btn-howto + .foot-note { text-align: left; margin-top: .5rem; }

/* Daily theme names: top chips, scoreboard headings, in-run HUD. */
.daily-entry .daily-theme { display: inline; margin: 0; color: var(--gold); font-weight: 700; font-size: inherit; }
.scoreboard-theme { display: inline-block; margin-left: .35rem; padding: .05rem .5rem; border-radius: 999px; border: 1px solid rgba(245,197,66,.4); background: rgba(245,197,66,.1); color: var(--gold); font-size: .72rem; font-weight: 700; vertical-align: middle; }
.hud-daily { padding: .05rem .5rem; border-radius: 999px; border: 1px solid rgba(245,197,66,.45); background: rgba(245,197,66,.14); color: var(--gold); font-weight: 700; white-space: nowrap; }
.hud-daily[hidden] { display: none; }

/* ---- Coin-burn buffs: slot bar, picker, Next-run panel, in-run chips ---- */
.tt-burn-bar { gap: .55rem; margin: .5rem 0 .6rem; font-size: .8rem; color: var(--muted); }
.tt-slot-pips { display: inline-flex; gap: .25rem; }
.tt-slot-pips i { width: .8rem; height: .8rem; border-radius: 50%; border: 1.5px solid rgba(245,197,66,.55); background: transparent; }
.tt-slot-pips i.is-used { background: var(--gold); box-shadow: 0 0 8px rgba(245,197,66,.55); }
.tt-burn-btn:disabled { opacity: .4; cursor: not-allowed; }
.tt-burn-btn:disabled:hover { background: rgba(0,0,0,.25); border-color: rgba(245,197,66,.45); color: var(--ink); }

.tt-burn-choices .tt-burn-choice { padding: .5rem .6rem; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; transition: border-color .15s ease, background-color .15s ease; }
.tt-burn-choices .tt-burn-choice:hover { border-color: rgba(245,197,66,.5); background: rgba(245,197,66,.06); }
.tt-burn-choices .tt-burn-choice:has(input:checked) { border-color: var(--gold); background: rgba(245,197,66,.1); }
.tt-burn-choices .tt-burn-choice.is-blocked { opacity: .45; cursor: not-allowed; }
.tt-burn-choices .tt-burn-choice.is-blocked:hover { border-color: var(--line); background: none; }
.tt-burn-choices .tt-burn-choice em { display: block; margin-top: .15rem; font-style: normal; font-size: .75rem; color: var(--bad); font-weight: 700; }
.tt-burn-choices .tt-burn-choice strong { color: var(--ink); }

.tt-buff-panel {
  position: fixed; top: 12px; left: 12px; z-index: 60; width: min(19rem, calc(100vw - 24px));
  border: 1px solid rgba(245,197,66,.5); border-radius: 14px; background: rgba(16,20,38,.97);
  box-shadow: 0 16px 44px rgba(0,0,0,.55), 0 0 24px rgba(245,197,66,.12); color: var(--ink);
  animation: tt-panel-in .25s ease-out;
}
#tt-buff-panel[hidden], body[data-screen]:not([data-screen="title"]) #tt-buff-panel { display: none; }
@keyframes tt-panel-in { from { opacity: 0; transform: translateX(-10px); } to { opacity: 1; transform: none; } }
.tt-buff-head {
  display: flex; align-items: center; gap: .5rem; width: 100%; min-height: 0; padding: .6rem .8rem;
  border: 0; border-radius: 14px; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.tt-buff-head:hover { background: rgba(255,255,255,.04); }
.tt-buff-head:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.tt-buff-title { font-weight: 800; font-size: .9rem; }
.tt-buff-count { margin-left: auto; padding: .05rem .5rem; border-radius: 999px; background: var(--gold); color: #1a1205; font-size: .72rem; font-weight: 800; }
.tt-buff-caret { width: .5rem; height: .5rem; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg) translateY(-2px); transition: transform .15s ease; }
.tt-buff-panel.is-collapsed .tt-buff-caret { transform: rotate(-45deg); }
.tt-buff-panel.is-collapsed .tt-buff-body { display: none; }
.tt-buff-body { padding: 0 .8rem .75rem; }
.tt-buff-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.tt-buff-row { display: flex; align-items: flex-start; gap: .5rem; padding: .45rem .55rem; border: 1px solid var(--line); border-radius: 10px; background: rgba(255,255,255,.03); }
.tt-buff-text { display: flex; flex-direction: column; gap: .1rem; min-width: 0; flex: 1; font-size: .8rem; }
.tt-buff-eff { color: var(--ink); opacity: .85; font-size: .76rem; line-height: 1.3; }
.tt-buff-src { color: var(--muted); font-size: .7rem; }
.tt-buff-undo { min-height: 28px; padding: 0 .55rem; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--muted); font-size: .7rem; font-weight: 700; cursor: pointer; transition: color .15s ease, border-color .15s ease, background-color .15s ease; }
.tt-buff-undo:hover { color: #fecaca; border-color: rgba(248,113,113,.55); background: rgba(248,113,113,.1); }
.tt-buff-row.is-empty { padding: 0; border-style: dashed; background: none; }
.tt-buff-empty { width: 100%; min-height: 34px; padding: .35rem .55rem; border: 0; border-radius: 10px; background: none; color: var(--muted); font: inherit; font-size: .75rem; font-weight: 600; text-align: left; cursor: pointer; }
.tt-buff-empty:hover { color: var(--gold); background: rgba(245,197,66,.06); }
.tt-buff-total { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .65rem; padding-top: .6rem; border-top: 1px solid var(--line); }
.tt-buff-total-label { flex-basis: 100%; font-size: .7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.tt-buff-chip { padding: .12rem .5rem; border-radius: 999px; background: rgba(52,211,153,.12); border: 1px solid rgba(52,211,153,.4); color: #a7f3d0; font-size: .72rem; font-weight: 700; }
.tt-buff-foot { margin: .55rem 0 0; color: var(--muted); font-size: .7rem; line-height: 1.35; }
@media (max-width: 700px) {
  .tt-buff-panel { top: auto; bottom: 10px; left: 10px; right: 10px; width: auto; max-height: 60vh; overflow: auto; }
}

.hud-buffs { display: flex; flex-wrap: wrap; gap: .25rem; margin: .3rem 0 .15rem; }
.hud-buffs[hidden] { display: none; }
.hud-buff { padding: .05rem .45rem; border-radius: 999px; border: 1px solid rgba(245,197,66,.6); background: rgba(245,197,66,.16); color: var(--gold); font-size: .66rem; font-weight: 800; white-space: nowrap; box-shadow: 0 0 8px rgba(245,197,66,.25); }
.hud-buff.is-spent { border-color: rgba(255,255,255,.18); background: rgba(255,255,255,.05); color: var(--muted); box-shadow: none; }

/* ---- How to play ---- */
.howto h2 { margin: 1.4rem 0 .5rem; padding-top: 1rem; border-top: 1px solid var(--line); font-size: 1.15rem; color: var(--gold); }
.howto h1 + h2 { margin-top: .6rem; padding-top: 0; border-top: 0; }
.howto p { color: var(--muted); margin: .3rem 0 .6rem; }
.howto p strong, .howto li strong { color: var(--ink); }
.howto-keys { display: grid; gap: .35rem; margin: .2rem 0 0; }
.howto-keys div { display: flex; align-items: center; gap: .6rem; }
.howto-keys dt { display: flex; gap: .2rem; min-width: 11rem; }
.howto-keys dd { margin: 0; color: var(--muted); font-size: .88rem; }
.howto kbd { display: inline-block; min-width: 1.6rem; padding: .05rem .4rem; border: 1px solid rgba(255,255,255,.25); border-bottom-width: 2px; border-radius: 6px; background: rgba(255,255,255,.07); color: var(--ink); font: 700 .75rem/1.5 var(--mono); text-align: center; }
.howto-row { display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 1.2rem; align-items: start; }
.howto-row-buffs { grid-template-columns: minmax(0, 1fr) 19rem; }
.howto-chest { width: 100%; height: auto; filter: drop-shadow(0 8px 18px rgba(0,0,0,.5)); }
.howto-rarities { display: flex; flex-wrap: wrap; gap: .6rem 1rem; margin: .5rem 0 .7rem; }
.howto-rarity { display: inline-flex; align-items: center; gap: .35rem; font-size: .8rem; font-weight: 700; }
.howto-rarity svg, .howto-buff-group h3 svg { width: 34px; height: 34px; flex: none; }
.howto-rules { margin: .3rem 0 0; padding-left: 1.2rem; color: var(--muted); font-size: .9rem; }
.howto-rules li { margin: .3rem 0; }
.howto-mock { position: relative; }
.howto-panel.tt-buff-panel { position: static; width: 100%; animation: none; box-shadow: 0 10px 30px rgba(0,0,0,.45); }
.howto-panel .tt-buff-head { cursor: default; }
.howto-panel .tt-buff-head:hover { background: none; }
.howto .hud-buff { display: inline-block; font-size: .72rem; vertical-align: 1px; }
.howto-buffs { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: .7rem; }
.howto-buff-group { padding: .7rem .8rem; border: 1px solid var(--line); border-radius: 12px; background: rgba(0,0,0,.18); }
.howto-buff-group h3 { display: flex; align-items: center; gap: .45rem; margin: 0 0 .4rem; font-size: .92rem; }
.howto-buff-group ul { margin: 0; padding-left: 1rem; color: var(--muted); font-size: .82rem; }
.howto-buff-group li { margin: .25rem 0; }
.howto-dev { font-size: .75rem; margin-top: 1rem !important; }
@media (max-width: 720px) {
  .howto-row, .howto-row-buffs { grid-template-columns: minmax(0, 1fr); }
  .howto-chest { max-width: 10rem; }
  .howto-keys dt { min-width: 9rem; }
}
.howto .tt-buff-list { margin: 0; padding: 0; color: inherit; }

/* Daily run banner: sits between the page header and the combat card. */
.daily-banner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .3rem .55rem;
  margin: 0 0 .6rem; padding: .45rem 1rem; border: 1px solid rgba(245,197,66,.45); border-radius: 12px;
  background: linear-gradient(90deg, rgba(245,197,66,.05), rgba(245,197,66,.16), rgba(245,197,66,.05));
  font-size: .88rem; color: var(--ink);
}
.daily-banner[hidden] { display: none; }
.daily-banner-kicker { font-size: .68rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.daily-banner-sep { color: var(--muted); }
.daily-banner-theme { padding: .08rem .6rem; border-radius: 999px; background: var(--gold); color: #1a1205; font-weight: 800; font-size: .8rem; }
.daily-banner-theme[hidden] { display: none; }

/* ---- TYPING-WORD-LORE: theme seal on the word box + timed definition inscription ---- */
@font-face { font-family: "Cinzel Lore"; src: url("../assets/fonts/cinzel-600-latin.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Fell Lore"; src: url("../assets/fonts/imfell-english-italic-latin.woff2") format("woff2"); font-style: italic; font-display: swap; }

.stage-prompt { position: relative; }
.lore-seal {
  position: absolute; left: -1.35rem; top: -1.55rem; z-index: 7;
  display: flex; align-items: center; pointer-events: none;
  transform: rotate(var(--tilt, -12deg)); transform-origin: 1.3rem 1.3rem;
}
.lore-seal[hidden] { display: none; }
.lore-seal-wax {
  position: relative; z-index: 1; flex: none;
  width: 2.6rem; height: 2.6rem; border-radius: 50%;
  display: grid; place-items: center;
  background:
    radial-gradient(circle at 34% 30%, rgba(255,190,160,0.55), transparent 42%),
    radial-gradient(circle at 50% 55%, #a3202a 0 58%, #7a1119 72%, #5a0b12 100%);
  box-shadow: 0 0 0 2px rgba(90,11,18,0.9), 0 0 0 4px rgba(163,32,42,0.35), 0 4px 10px rgba(0,0,0,0.6),
    inset 0 -3px 6px rgba(0,0,0,0.35);
  /* slightly uneven wax edge */
  clip-path: polygon(50% 0, 62% 3%, 74% 2%, 83% 10%, 94% 17%, 97% 29%, 100% 41%, 98% 54%, 100% 66%, 93% 77%, 87% 88%, 75% 94%, 63% 100%, 50% 97%, 37% 100%, 25% 95%, 14% 88%, 7% 77%, 1% 65%, 3% 52%, 0 40%, 4% 28%, 9% 16%, 19% 8%, 30% 2%, 40% 3%);
}
.lore-seal-icon { font-size: 1.28rem; line-height: 1; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.55)); }
.lore-seal-ribbon {
  margin-left: -0.55rem; padding: 0.16rem 0.7rem 0.16rem 0.8rem;
  font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; font-size: 0.66rem; letter-spacing: 0.1em;
  text-transform: uppercase; white-space: nowrap; color: #2a1a08;
  background: linear-gradient(180deg, #f3dfae, #d9b56a 55%, #b88d3e);
  box-shadow: 0 2px 6px rgba(0,0,0,0.5);
  clip-path: polygon(0 0, 100% 0, calc(100% - 0.45rem) 50%, 100% 100%, 0 100%);
}
.lore-seal.pop { animation: lore-seal-pop 0.55s cubic-bezier(0.2, 1.6, 0.4, 1) both; }
.lore-seal.pop .lore-seal-ribbon { animation: lore-ribbon-unfurl 0.45s 0.18s ease-out both; }
@keyframes lore-seal-pop {
  0% { opacity: 0; transform: rotate(calc(var(--tilt, -12deg) - 40deg)) scale(2.1); }
  60% { opacity: 1; }
  100% { opacity: 1; transform: rotate(var(--tilt, -12deg)) scale(1); }
}
@keyframes lore-ribbon-unfurl { from { clip-path: polygon(0 0, 0 0, 0 50%, 0 100%, 0 100%); } }

/* Open grimoire: tilted back on the left wall, see-through enough to keep the
   hero readable. Outlines (torn edges, pages bowing into the binding) are
   clip-path polygons built in word-lore.js. */
.lore-book {
  --book-tilt: perspective(900px) rotateY(26deg) rotateX(14deg) rotateZ(-3deg);
  left: 4.1rem; top: 19%; width: min(43%, 28rem);   /* J-1002: +7% for the page stack */
  z-index: 1; /* behind .fighters (z 2): the hero stands in front of the book */
  transform-origin: 0% 50%;
  opacity: 0; transform: var(--book-tilt) translateY(8px) scale(0.96); transition: opacity 0.4s ease, transform 0.4s ease;
  filter: drop-shadow(0 12px 14px rgba(0,0,0,0.55));
}
.lore-book.show { opacity: 0.86; transform: var(--book-tilt); }
.lore-spread {
  position: relative; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: minmax(0, 1fr); height: 17.6rem;
  padding: 0.5rem 0.5rem 0.62rem;
  perspective: 1100px;
}
/* leather boards: outline from --cover-clip (word-lore.js) on their own layer */
.lore-spread::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; clip-path: var(--cover-clip, none);
  background:
    radial-gradient(ellipse at 50% 50%, rgba(0,0,0,0.35) 0 6%, transparent 7%),
    radial-gradient(circle at 18% 30%, rgba(255,210,150,0.08), transparent 30%),
    radial-gradient(circle at 80% 75%, rgba(0,0,0,0.25), transparent 35%),
    linear-gradient(90deg, rgba(52,24,12,0.9), rgba(88,44,22,0.88) 14%, rgba(66,31,15,0.9) 47%, rgba(30,12,5,0.95) 50%, rgba(66,31,15,0.9) 53%, rgba(88,44,22,0.88) 86%, rgba(52,24,12,0.9));
}
.lore-page { position: relative; padding: 1.05rem 0.62rem 1.05rem; color: #3a2410; }
/* paper layer: parchment + stains, torn outline from --page-clip (word-lore.js) */
.lore-page::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; clip-path: var(--page-clip, none);
  background-color: rgba(236,218,176,0.8);
  background-image:
    radial-gradient(circle at 22% 78%, rgba(140,90,30,0.16), transparent 22%),
    radial-gradient(circle at 70% 18%, rgba(120,75,25,0.12), transparent 18%),
    linear-gradient(180deg, rgba(255,250,235,0.18), rgba(150,105,45,0.14));
}
/* the curl: dark gutter at the binding, a lit crown where the page bows up,
   then a soft fall-off toward the fore-edge */
.lore-page::before { content: ""; position: absolute; inset: 0; pointer-events: none; clip-path: var(--page-clip, none); }
.lore-left::before {
  background: linear-gradient(90deg, rgba(90,55,20,0.22) 0%, transparent 10%, rgba(255,248,225,0.22) 52%, rgba(255,248,225,0.1) 72%, rgba(80,45,12,0.35) 91%, rgba(40,20,5,0.62) 100%);
}
.lore-right::before {
  background: linear-gradient(270deg, rgba(90,55,20,0.22) 0%, transparent 10%, rgba(255,248,225,0.22) 52%, rgba(255,248,225,0.1) 72%, rgba(80,45,12,0.35) 91%, rgba(40,20,5,0.62) 100%);
}
/* Pages lift into a shallow V at the binding, and the writing leans with each
   page's top edge as it bows down into the gutter. */
.lore-spread { transform-style: preserve-3d; }
.lore-left { transform-origin: 100% 50%; transform: rotateY(16deg); isolation: isolate; }
.lore-right { transform-origin: 0% 50%; transform: rotateY(-16deg); isolation: isolate; }
.lore-ink-wrap { position: relative; }
.lore-left .lore-ink-wrap, .lore-leaf-back > div { transform: skewY(3deg); transform-origin: 0 0; padding-right: 0.35rem; }
.lore-right .lore-ink-wrap, .lore-leaf-front > .lore-body { transform: skewY(-3deg); transform-origin: 100% 0; padding-left: 0.4rem; }

/* magic calligraphy quill: nib at the bottom-left corner of the box */
.lore-quill {
  position: absolute; width: 2.5rem; height: 4.2rem; margin-top: -4.2rem; z-index: 4; pointer-events: none;
  transition: left 0.32s cubic-bezier(0.3, 0.7, 0.3, 1), top 0.32s cubic-bezier(0.3, 0.7, 0.3, 1), opacity 0.7s ease, transform 0.7s ease;
  filter: drop-shadow(0 0 4px rgba(170,130,255,0.85)) drop-shadow(1px 3px 2px rgba(40,20,5,0.45));
}
.lore-quill svg { display: block; width: 100%; height: 100%; transform-origin: 0 100%; animation: lore-scribble 0.26s ease-in-out infinite alternate; }
.lore-quill-glow {
  position: absolute; left: -4px; bottom: -4px; width: 9px; height: 9px; border-radius: 50%;
  background: radial-gradient(circle, #fff 0 20%, rgba(200,170,255,0.9) 40%, transparent 70%);
  animation: lore-nib 0.5s ease-in-out infinite alternate;
}
.lore-quill.rest { opacity: 0; transform: translate(6px, -10px) rotate(8deg); }
.lore-quill.rest svg, .lore-quill.rest .lore-quill-glow { animation-play-state: paused; }
@keyframes lore-scribble {
  0% { transform: rotate(-5deg) translate(0, 0); }
  50% { transform: rotate(3deg) translate(1px, -1px); }
  100% { transform: rotate(-2deg) translate(-1px, 1px); }
}
@keyframes lore-nib { from { transform: scale(0.7); opacity: 0.7; } to { transform: scale(1.35); opacity: 1; } }
/* page-edge stack along the bottom */
.lore-spread::after {
  content: ""; position: absolute; left: 0.6rem; right: 0.6rem; bottom: 0.3rem; height: 4px; border-radius: 0 0 50% 50% / 0 0 100% 100%;
  background: repeating-linear-gradient(0deg, rgba(217,192,137,0.85) 0 1px, rgba(170,140,85,0.85) 1px 2px); pointer-events: none;
}
.lore-ink-wrap { height: 100%; }
.lore-head { font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; line-height: 1.12; text-align: center; margin-top: 0.35rem; }
.lore-word { display: flex; align-items: flex-end; justify-content: center; gap: 0.08em; overflow-wrap: anywhere; line-height: 1; }
/* illuminated initial: gilt letter on a quartered red/blue ground with vines */
.lore-initial {
  flex: none; display: grid; place-items: center; width: 3.3rem; height: 3.3rem; border-radius: 3px;
  background:
    radial-gradient(circle at 16% 20%, #5aa04a 0 6%, transparent 7%),
    radial-gradient(circle at 84% 82%, #5aa04a 0 6%, transparent 7%),
    radial-gradient(circle at 84% 18%, #f0d58a 0 4%, transparent 5%),
    radial-gradient(circle at 16% 84%, #f0d58a 0 4%, transparent 5%),
    conic-gradient(from 45deg, #8e1d14 0 25%, #1d3f8e 0 50%, #8e1d14 0 75%, #1d3f8e 0);
  box-shadow: inset 0 0 0 2px #d9a940, inset 0 0 0 4px #2a1406, inset 0 0 0 5px #b88a3a, 0 2px 4px rgba(40,20,5,0.5);
  animation: lore-gild 3.2s ease-in-out infinite;
}
.lore-initial-glyph {
  font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; font-size: 2.35rem; line-height: 1;
  background: linear-gradient(135deg, #fff6c9 0%, #f5c542 30%, #b3781d 55%, #ffe590 75%, #c98d22 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 1px 0 #2a1406);
}
.lore-word-rest {
  font-family: "Fell Lore", Georgia, serif; font-style: italic; font-size: 1.85rem; letter-spacing: 0.01em; padding-bottom: 0.1em;
  color: transparent;
  background: linear-gradient(100deg, #6b1a12 0%, #6b1a12 38%, #ffe7a0 47%, #b489ff 52%, #6b1a12 61%, #6b1a12 100%) 0 0 / 260% 100%;
  -webkit-background-clip: text; background-clip: text;
  animation: lore-shimmer 2.8s linear infinite;
}
@keyframes lore-shimmer { from { background-position: 100% 0; } to { background-position: -60% 0; } }
@keyframes lore-gild { 0%,100% { filter: brightness(1) drop-shadow(0 0 0 rgba(255,210,90,0)); } 50% { filter: brightness(1.18) drop-shadow(0 0 5px rgba(255,210,90,0.65)); } }
.lore-pos { display: block; margin-top: 0.3rem; font-family: "Fell Lore", Georgia, serif; font-style: italic; font-size: 1.25rem; color: #7a5a30; }
.lore-rule { text-align: center; font-size: 1.3rem; line-height: 1; margin: 0.45rem 0 0.4rem; color: #8a5a22; }
.lore-from { font-family: "Fell Lore", Georgia, serif; font-style: italic; font-size: 1.12rem; line-height: 1.15; text-align: center; color: #7a5a30; }
.lore-body { font-family: "Fell Lore", Georgia, serif; font-style: italic; font-size: 1.55rem; line-height: 1.18; hyphens: auto; }
.lore-sheet.wiping { animation: lore-wipe 0.44s ease-in forwards; }
@keyframes lore-wipe {
  0% { opacity: 1; filter: blur(0); -webkit-mask-image: linear-gradient(180deg, #000 100%, transparent 100%); }
  100% { opacity: 0; filter: blur(3px); transform: translateY(-6px); }
}
.lore-body .lore-sheet:first-child .lore-ink:first-child::first-letter { font-family: "Cinzel Lore", Georgia, serif; font-style: normal; font-size: 1.55em; color: #8e1d14; line-height: 0.8; }
.lore-blank { text-align: center; margin-top: 4rem; font-size: 2rem; color: rgba(138,90,34,0.5); }
.lore-folio { position: absolute; bottom: 0.25rem; font-family: "Fell Lore", Georgia, serif; font-style: italic; font-size: 0.9rem; color: #8a6a3a; }
.lore-folio-l { left: 0.55rem; }
.lore-folio-r { right: 0.55rem; }
.lore-ink { opacity: 0; filter: blur(3px); transition: opacity 0.55s ease, filter 0.7s ease, color 1.3s ease; color: #1d0f05; }
.lore-ink.in { opacity: 1; filter: none; color: #3a2410; }

/* The turning leaf sits on the right page and swings over the spine. */
.lore-leaf {
  position: absolute; top: 0.5rem; bottom: 0.62rem; left: 50%; width: calc(50% - 0.5rem);
  transform-origin: left center; transform-style: preserve-3d; z-index: 3;
}
.lore-leaf[hidden] { display: none; }
.lore-leaf.turning { animation: lore-turn 0.72s cubic-bezier(0.45, 0.05, 0.35, 1) both; }
/* shadow the leaf casts on the page it is leaving */
.lore-spread:has(.lore-leaf.turning) .lore-right::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(40,20,5,0.55), transparent 70%);
  animation: lore-cast 0.72s ease both;
}
@keyframes lore-cast { 0% { opacity: 0; } 40% { opacity: 1; } 100% { opacity: 0; } }
.lore-leaf-face {
  position: absolute; inset: 0; overflow: hidden; padding: 1.05rem 0.62rem 1.05rem 1.02rem; backface-visibility: hidden; color: #3a2410;
  background: linear-gradient(270deg, rgba(236,218,176,0.92) 0%, rgba(242,228,192,0.95) 55%, rgba(210,180,125,0.95) 100%);
}
.lore-leaf-back { transform: rotateY(180deg); }
.lore-leaf-face::after { content: ""; position: absolute; inset: 0; pointer-events: none; animation: lore-turn-shade 0.72s ease both; }
@keyframes lore-turn {
  0% { transform: rotateY(-16deg); }
  45% { transform: rotateY(-86deg) skewY(-2deg); }
  100% { transform: rotateY(-168deg); }
}
@keyframes lore-turn-shade {
  0% { background: linear-gradient(90deg, transparent, transparent); }
  45% { background: linear-gradient(90deg, rgba(40,20,5,0.7), rgba(40,20,5,0.25) 60%, rgba(255,255,255,0.2)); }
  100% { background: linear-gradient(90deg, transparent, transparent); }
}

@media (max-height: 850px) { .lore-book { top: 23%; } }
@media (max-width: 900px) { .lore-book { width: min(45%, 20.5rem); } .lore-spread { height: 13.9rem; } .lore-body { font-size: 1.15rem; } .lore-word-rest { font-size: 1.4rem; } .lore-initial { width: 2.6rem; height: 2.6rem; } .lore-initial-glyph { font-size: 1.8rem; } }
@media (max-width: 640px) {
  .lore-book { display: none; }
  .lore-seal { left: -0.4rem; top: -1.4rem; }
  .lore-seal-wax { width: 2.1rem; height: 2.1rem; }
  .lore-seal-icon { font-size: 1.05rem; }
}
@media (prefers-reduced-motion: reduce) {
  .lore-seal.pop, .lore-seal.pop .lore-seal-ribbon { animation: none; }
  .lore-ink { transition: none; filter: none; }
  .lore-leaf.turning, .lore-leaf-face::after { animation: none; }
  .lore-quill { display: none; }
}

/* ---- TYPING-CHEST-FX: flying coin, spark trail, +1 (game.js playChestDeposit) ---- */
.tt-fly-coin {
  position: absolute; width: 2.7rem; height: 2.7rem; z-index: 9; pointer-events: none;
  filter: drop-shadow(0 0 6px var(--tt-glow, #f5c542)) drop-shadow(0 0 14px var(--tt-glow, #f5c542));
}
.tt-fly-coin svg { width: 100%; height: 100%; display: block; }
.tt-spark {
  position: absolute; width: 7px; height: 7px; border-radius: 50%; z-index: 8; pointer-events: none;
  background: radial-gradient(circle, #fff 0 30%, var(--tt-glow, #f5c542) 55%, transparent 72%);
  animation: tt-spark 0.62s ease-out forwards;
}
@keyframes tt-spark {
  from { opacity: 1; transform: translate(-50%, -50%) scale(1.2); }
  to { opacity: 0; transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 12px))) scale(0.2); }
}
#treasure-chest.tt-opening::before { background: radial-gradient(ellipse, #fff 0 12%, var(--tt-glow, #ffc236) 32%, rgba(245,150,20,.3) 52%, transparent 72%); }
.tt-plus-one {
  position: absolute; left: 50%; top: 18%; z-index: 3; pointer-events: none;
  font-weight: 800; font-size: 1.15rem; text-shadow: 0 0 8px rgba(0,0,0,0.8), 0 0 12px currentColor;
  animation: tt-plus-rise 1.15s ease-out forwards;
}
@keyframes tt-plus-rise {
  0% { opacity: 0; transform: translate(-50%, 6px) scale(0.6); }
  20% { opacity: 1; transform: translate(-50%, -4px) scale(1.2); }
  100% { opacity: 0; transform: translate(-50%, -34px) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .tt-spark, .tt-fly-coin { display: none; } .tt-plus-one { animation-duration: 0.01s; } }

/* ==== TYPING-LANDING: the class-select screen as a living dungeon ==========
   Stone slabs, moss, carved gilt corners, drips, bats and magic flares.
   JS: js/landing.js (tags .land-panel, runs hero loops + ambience). */
body:has(#screen-title.active) {
  background:
    radial-gradient(ellipse 70% 55% at 50% 30%, transparent 0, rgba(5,4,3,.72) 70%, rgba(3,2,2,.94) 100%),
    linear-gradient(180deg, rgba(8,6,4,.55), rgba(8,6,4,.8)),
    url("../assets/dungeon/hall_straight.webp") center 20% / cover fixed,
    #0c0a08;
}
#screen-title.land .land-panel {
  position: relative; isolation: isolate;
  border: 1px solid #0d0b09 !important;
  border-radius: 10px !important;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='400'%3E%3Cg fill='none' stroke='rgba(0,0,0,.45)' stroke-width='1.2' stroke-linecap='round'%3E%3Cpath d='M40 0 L55 40 L48 80 L70 130 L64 170'/%3E%3Cpath d='M420 400 L405 350 L420 310 L398 262'/%3E%3Cpath d='M600 120 L560 132 L530 118 L492 140'/%3E%3C/g%3E%3Cg fill='none' stroke='rgba(255,235,200,.07)' stroke-width='1'%3E%3Cpath d='M41 1 L56 41 L49 81 L71 131 L65 171'/%3E%3Cpath d='M421 399 L406 351 L421 311 L399 263'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 600px 400px,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.62 0 0 0 0 0.56 0 0 0 0 0.47 0 0 0 0.42 0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='520' height='520'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='4' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.10 0 0 0 0 0.09 0 0 0 0 0.07 0 0 0 1.1 -0.35'/%3E%3C/filter%3E%3Crect width='520' height='520' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 520px 520px,
    linear-gradient(180deg, #3a342c 0%, #2a251f 45%, #1d1a16 100%) !important;
  box-shadow:
    inset 0 2px 0 rgba(255,236,200,.10), inset 0 -3px 0 rgba(0,0,0,.55),
    inset 3px 0 0 rgba(255,236,200,.04), inset -3px 0 0 rgba(0,0,0,.35),
    0 14px 30px rgba(0,0,0,.6) !important;
  backdrop-filter: none;
}
#screen-title.land .land-panel::after {
  content: ""; position: absolute; inset: 3px; pointer-events: none; z-index: -1;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cg transform='rotate(0 32 32)'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cpath d='M4 60 L4 14 Q4 4 14 4 L60 4' stroke='%231a120a' stroke-width='5'/%3E%3Cpath d='M4 60 L4 14 Q4 4 14 4 L60 4' stroke='%23c99a4b' stroke-width='2.2'/%3E%3Cpath d='M11 50 L11 20 Q11 11 20 11 L50 11' stroke='%238a6428' stroke-width='1.4'/%3E%3Cpath d='M18 18 m-7 0 a7 7 0 1 0 14 0 a7 7 0 1 0 -14 0' stroke='%23e2bb6a' stroke-width='1.6'/%3E%3Cpath d='M18 18 m-3 0 a3 3 0 1 0 6 0 a3 3 0 1 0 -6 0' stroke='%23c99a4b' stroke-width='1.2'/%3E%3Cpath d='M25 18 C 34 18, 36 26, 44 24 M18 25 C 18 34, 26 36, 24 44' stroke='%23c99a4b' stroke-width='1.3'/%3E%3C/g%3E%3Ccircle cx='18' cy='18' r='2' fill='%237fe0ff'/%3E%3C/g%3E%3C/svg%3E") top left / 44px 44px no-repeat, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cg transform='rotate(90 32 32)'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cpath d='M4 60 L4 14 Q4 4 14 4 L60 4' stroke='%231a120a' stroke-width='5'/%3E%3Cpath d='M4 60 L4 14 Q4 4 14 4 L60 4' stroke='%23c99a4b' stroke-width='2.2'/%3E%3Cpath d='M11 50 L11 20 Q11 11 20 11 L50 11' stroke='%238a6428' stroke-width='1.4'/%3E%3Cpath d='M18 18 m-7 0 a7 7 0 1 0 14 0 a7 7 0 1 0 -14 0' stroke='%23e2bb6a' stroke-width='1.6'/%3E%3Cpath d='M18 18 m-3 0 a3 3 0 1 0 6 0 a3 3 0 1 0 -6 0' stroke='%23c99a4b' stroke-width='1.2'/%3E%3Cpath d='M25 18 C 34 18, 36 26, 44 24 M18 25 C 18 34, 26 36, 24 44' stroke='%23c99a4b' stroke-width='1.3'/%3E%3C/g%3E%3Ccircle cx='18' cy='18' r='2' fill='%237fe0ff'/%3E%3C/g%3E%3C/svg%3E") top right / 44px 44px no-repeat, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cg transform='rotate(270 32 32)'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cpath d='M4 60 L4 14 Q4 4 14 4 L60 4' stroke='%231a120a' stroke-width='5'/%3E%3Cpath d='M4 60 L4 14 Q4 4 14 4 L60 4' stroke='%23c99a4b' stroke-width='2.2'/%3E%3Cpath d='M11 50 L11 20 Q11 11 20 11 L50 11' stroke='%238a6428' stroke-width='1.4'/%3E%3Cpath d='M18 18 m-7 0 a7 7 0 1 0 14 0 a7 7 0 1 0 -14 0' stroke='%23e2bb6a' stroke-width='1.6'/%3E%3Cpath d='M18 18 m-3 0 a3 3 0 1 0 6 0 a3 3 0 1 0 -6 0' stroke='%23c99a4b' stroke-width='1.2'/%3E%3Cpath d='M25 18 C 34 18, 36 26, 44 24 M18 25 C 18 34, 26 36, 24 44' stroke='%23c99a4b' stroke-width='1.3'/%3E%3C/g%3E%3Ccircle cx='18' cy='18' r='2' fill='%237fe0ff'/%3E%3C/g%3E%3C/svg%3E") bottom left / 44px 44px no-repeat, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cg transform='rotate(180 32 32)'%3E%3Cg fill='none' stroke-linecap='round'%3E%3Cpath d='M4 60 L4 14 Q4 4 14 4 L60 4' stroke='%231a120a' stroke-width='5'/%3E%3Cpath d='M4 60 L4 14 Q4 4 14 4 L60 4' stroke='%23c99a4b' stroke-width='2.2'/%3E%3Cpath d='M11 50 L11 20 Q11 11 20 11 L50 11' stroke='%238a6428' stroke-width='1.4'/%3E%3Cpath d='M18 18 m-7 0 a7 7 0 1 0 14 0 a7 7 0 1 0 -14 0' stroke='%23e2bb6a' stroke-width='1.6'/%3E%3Cpath d='M18 18 m-3 0 a3 3 0 1 0 6 0 a3 3 0 1 0 -6 0' stroke='%23c99a4b' stroke-width='1.2'/%3E%3Cpath d='M25 18 C 34 18, 36 26, 44 24 M18 25 C 18 34, 26 36, 24 44' stroke='%23c99a4b' stroke-width='1.3'/%3E%3C/g%3E%3Ccircle cx='18' cy='18' r='2' fill='%237fe0ff'/%3E%3C/g%3E%3C/svg%3E") bottom right / 44px 44px no-repeat;
  opacity: .92;
}
#screen-title.land > .card.hero::before,
#screen-title.land .class-card::before,
#screen-title.land .tt-museum::before {
  content: ""; position: absolute; left: 10px; right: 10px; top: -9px; height: 30px; pointer-events: none; z-index: -1;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='30'%3E%3Ccircle cx='77.7' cy='6.6' r='3.8' fill='%232f5a22' opacity='0.96'/%3E%3Ccircle cx='22.6' cy='8.4' r='5.9' fill='%233d7029' opacity='0.76'/%3E%3Ccircle cx='104.1' cy='2.6' r='3.3' fill='%2327481c' opacity='0.76'/%3E%3Ccircle cx='135.7' cy='6.4' r='7.7' fill='%235d9a3a' opacity='0.99'/%3E%3Ccircle cx='138.5' cy='8.8' r='5.0' fill='%232f5a22' opacity='0.89'/%3E%3Ccircle cx='32.0' cy='5.8' r='5.1' fill='%235d9a3a' opacity='0.83'/%3E%3Ccircle cx='195.9' cy='6.1' r='3.9' fill='%231f3a17' opacity='0.80'/%3E%3Ccircle cx='23.4' cy='6.0' r='6.6' fill='%235d9a3a' opacity='0.80'/%3E%3Ccircle cx='163.3' cy='4.2' r='5.1' fill='%235d9a3a' opacity='0.98'/%3E%3Ccircle cx='86.8' cy='3.3' r='4.2' fill='%233d7029' opacity='0.77'/%3E%3Ccircle cx='72.1' cy='4.4' r='5.5' fill='%2327481c' opacity='0.82'/%3E%3Ccircle cx='235.2' cy='4.9' r='3.6' fill='%234f8a31' opacity='0.79'/%3E%3Ccircle cx='117.4' cy='6.7' r='3.2' fill='%235d9a3a' opacity='0.89'/%3E%3Ccircle cx='210.1' cy='6.9' r='4.6' fill='%235d9a3a' opacity='0.87'/%3E%3Ccircle cx='191.3' cy='2.7' r='3.3' fill='%234f8a31' opacity='0.87'/%3E%3Ccircle cx='159.4' cy='6.9' r='3.3' fill='%231f3a17' opacity='0.89'/%3E%3Ccircle cx='163.5' cy='7.0' r='5.2' fill='%231f3a17' opacity='0.84'/%3E%3Ccircle cx='225.8' cy='6.3' r='4.8' fill='%2327481c' opacity='0.76'/%3E%3Ccircle cx='184.4' cy='3.7' r='3.6' fill='%2327481c' opacity='0.98'/%3E%3Ccircle cx='119.2' cy='4.8' r='3.8' fill='%234f8a31' opacity='0.97'/%3E%3Ccircle cx='196.6' cy='3.9' r='7.3' fill='%2327481c' opacity='1.00'/%3E%3Ccircle cx='163.9' cy='3.6' r='4.9' fill='%232f5a22' opacity='0.79'/%3E%3Ccircle cx='55.7' cy='5.4' r='4.2' fill='%235d9a3a' opacity='0.80'/%3E%3Ccircle cx='67.7' cy='5.7' r='3.7' fill='%235d9a3a' opacity='0.89'/%3E%3Ccircle cx='228.7' cy='5.6' r='6.5' fill='%235d9a3a' opacity='0.91'/%3E%3Ccircle cx='177.5' cy='8.1' r='5.3' fill='%231f3a17' opacity='0.95'/%3E%3Ccircle cx='94.2' cy='2.7' r='5.0' fill='%231f3a17' opacity='0.85'/%3E%3Ccircle cx='45.7' cy='5.1' r='7.9' fill='%232f5a22' opacity='0.84'/%3E%3Ccircle cx='12.6' cy='3.1' r='3.0' fill='%232f5a22' opacity='0.99'/%3E%3Ccircle cx='147.3' cy='3.5' r='3.4' fill='%2327481c' opacity='0.79'/%3E%3Ccircle cx='60.5' cy='4.5' r='4.7' fill='%232f5a22' opacity='0.78'/%3E%3Ccircle cx='117.1' cy='5.4' r='7.9' fill='%234f8a31' opacity='0.77'/%3E%3Ccircle cx='24.5' cy='3.9' r='4.7' fill='%231f3a17' opacity='0.79'/%3E%3Ccircle cx='5.5' cy='5.7' r='7.8' fill='%233d7029' opacity='0.92'/%3E%3Ccircle cx='219.4' cy='4.1' r='6.8' fill='%231f3a17' opacity='0.97'/%3E%3Ccircle cx='167.1' cy='4.6' r='4.3' fill='%233d7029' opacity='0.84'/%3E%3Ccircle cx='53.5' cy='5.5' r='5.7' fill='%231f3a17' opacity='0.81'/%3E%3Ccircle cx='194.8' cy='8.0' r='7.9' fill='%233d7029' opacity='0.95'/%3E%3Ccircle cx='177.6' cy='5.6' r='4.1' fill='%234f8a31' opacity='0.93'/%3E%3Ccircle cx='237.5' cy='5.3' r='7.0' fill='%233d7029' opacity='0.92'/%3E%3Ccircle cx='229.6' cy='8.6' r='5.2' fill='%234f8a31' opacity='0.99'/%3E%3Ccircle cx='87.5' cy='3.6' r='4.1' fill='%233d7029' opacity='0.83'/%3E%3Ccircle cx='115.8' cy='6.3' r='7.9' fill='%232f5a22' opacity='0.87'/%3E%3Ccircle cx='156.7' cy='2.6' r='7.0' fill='%231f3a17' opacity='0.78'/%3E%3Ccircle cx='93.2' cy='3.4' r='6.6' fill='%233d7029' opacity='0.86'/%3E%3Ccircle cx='152.6' cy='8.6' r='3.4' fill='%231f3a17' opacity='0.85'/%3E%3Cpath d='M97.1 8 q 1.3 9.7 -1.3 19.4' stroke='%233d7029' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Cpath d='M10.4 8 q -0.2 7.5 0.6 15.1' stroke='%235d9a3a' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Cpath d='M195.8 8 q 0.9 9.9 -0.6 19.8' stroke='%235d9a3a' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Cpath d='M131.2 8 q 1.8 4.1 0.9 8.3' stroke='%232f5a22' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Cpath d='M126.2 8 q -0.4 9.6 1.5 19.2' stroke='%233d7029' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Cpath d='M10.5 8 q 0.0 5.3 1.1 10.6' stroke='%234f8a31' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Cpath d='M64.2 8 q -2.2 6.5 1.6 13.0' stroke='%234f8a31' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Cpath d='M212.3 8 q 1.9 8.0 0.1 15.9' stroke='%235d9a3a' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Cpath d='M34.3 8 q 0.1 4.9 1.5 9.8' stroke='%233d7029' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3Ccircle cx='146.1' cy='5.7' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='36.0' cy='1.8' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='148.6' cy='1.7' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='14.8' cy='5.1' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='127.4' cy='3.9' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='186.4' cy='6.3' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='13.6' cy='2.1' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='10.1' cy='1.6' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='108.5' cy='1.2' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='214.6' cy='1.4' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='78.1' cy='6.8' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='145.5' cy='2.2' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='66.5' cy='4.0' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3Ccircle cx='193.8' cy='4.0' r='1.1' fill='%23a7d36a' opacity='.8'/%3E%3C/svg%3E") 0 0 / 240px 30px repeat-x;
  filter: drop-shadow(0 3px 2px rgba(0,0,0,.55));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 30%, transparent 42%, transparent 55%, #000 66%, #000 90%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 30%, transparent 42%, transparent 55%, #000 66%, #000 90%, transparent);
}
#screen-title.land .class-card::before { -webkit-mask-image: linear-gradient(90deg, #000, #000 24%, transparent 40%, transparent 70%, #000 82%); mask-image: linear-gradient(90deg, #000, #000 24%, transparent 40%, transparent 70%, #000 82%); }

/* carved title with torchlight */
#screen-title.land .hero > h1 {
  font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; letter-spacing: .04em;
  font-size: clamp(1.7rem, 4.6vw, 2.8rem); text-wrap: balance;
  background: linear-gradient(180deg, #fff3c4 0%, #f5c542 38%, #b27a1c 62%, #f0cf7a 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 0 #1a1008) drop-shadow(0 0 14px rgba(255,160,50,.35));
  animation: land-torch 3.2s ease-in-out infinite;
}
@keyframes land-torch {
  0%,100% { filter: drop-shadow(0 2px 0 #1a1008) drop-shadow(0 0 12px rgba(255,160,50,.30)); }
  37% { filter: drop-shadow(0 2px 0 #1a1008) drop-shadow(0 0 20px rgba(255,170,60,.55)); }
  41% { filter: drop-shadow(0 2px 0 #1a1008) drop-shadow(0 0 9px rgba(255,150,40,.25)); }
  70% { filter: drop-shadow(0 2px 0 #1a1008) drop-shadow(0 0 17px rgba(255,165,55,.45)); }
}
#screen-title.land .hero > p { color: #d8c9a6; }
#screen-title.land .class-card h2, #screen-title.land .tt-museum > h2 {
  font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; letter-spacing: .06em; color: #f0d58a;
  text-shadow: 0 2px 0 #120c06, 0 0 10px rgba(245,197,66,.25);
}
#screen-title.land .class-card p { color: #cbbd9b; }
#screen-title.land .theme-row select, #screen-title.land .tt-code-row input { background: #15120f; border-color: #4a3f31; }

/* hero alcoves */
.land-alcove { position: relative; width: min(250px, 62vw); max-width: 100%; margin: 1.3rem auto 0; }
.land-stage {
  position: relative; width: 100%; aspect-ratio: 5 / 6; overflow: hidden;
  border-radius: 48% 48% 10px 10px / 34% 34% 10px 10px;
  background:
    radial-gradient(ellipse 60% 45% at 50% 100%, rgba(255,170,70,.28), transparent 70%),
    radial-gradient(ellipse at 50% 40%, transparent 30%, rgba(0,0,0,.7) 100%),
    url("../assets/dungeon/hall_corner.webp") center 40% / cover;
  box-shadow: inset 0 0 0 3px #15110c, inset 0 0 0 5px #6d5530, inset 0 0 24px rgba(0,0,0,.85), 0 8px 18px rgba(0,0,0,.6);
}
.land-hero { position: absolute; left: 50%; height: 116%; width: auto; max-width: none; transform: translateX(-50%); pointer-events: none; filter: drop-shadow(0 6px 6px rgba(0,0,0,.6)); }
.land-stage-warrior .land-hero { bottom: -12%; }
/* normalized chop canvas is 1328 tall (vs 1208) with 120px headroom: same pixel scale, same feet */
.land-stage-warrior .land-hero.land-hero-chop { height: 127.5%; transform: translateX(-53.33%); } /* 1500-wide: original box centre sits 50px right of canvas centre */
.land-stage-mage .land-hero.land-hero-wide { transform: translateX(-30.47%); } /* 1500-wide fire3 canvas, padded on the right only */
.land-stage-mage .land-hero { bottom: -1%; }
.land-call {
  position: absolute; left: 50%; top: -1.1rem; z-index: 3; white-space: nowrap; pointer-events: none; opacity: 0;
  font: 600 1.35rem/1 "Cinzel Lore", Georgia, serif; letter-spacing: .05em; color: #fff3c4;
  text-shadow: 0 2px 0 #1a0e05, 0 0 10px rgba(255,190,80,.9), 0 0 22px rgba(255,120,30,.6);
  transform: translateX(-50%);
}
.land-call.show { animation: land-call 1.05s cubic-bezier(.2,1.4,.4,1) both; }
.land-call.big { font-size: 1.7rem; color: #ffe1c4; text-shadow: 0 2px 0 #1a0505, 0 0 12px rgba(255,90,40,.95), 0 0 28px rgba(255,40,20,.7); }
.land-alcove-mage .land-call { color: #e4f4ff; text-shadow: 0 2px 0 #050a1a, 0 0 10px rgba(120,190,255,.95), 0 0 24px rgba(90,120,255,.6); }
.land-alcove-mage .land-call.big { color: #ffe6c8; text-shadow: 0 2px 0 #1a0805, 0 0 12px rgba(255,140,40,.95), 0 0 28px rgba(255,70,20,.7); }
@keyframes land-call {
  0% { opacity: 0; transform: translateX(-50%) scale(.4) rotate(-8deg); }
  18% { opacity: 1; transform: translateX(-50%) scale(1.18) rotate(3deg); }
  32% { transform: translateX(-50%) scale(1) rotate(-2deg); }
  75% { opacity: 1; transform: translateX(-50%) translateY(-6px) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) translateY(-18px) scale(.96); }
}

/* drips, flares, bats */
.land-drip {
  position: absolute; top: 14px; width: 5px; height: 8px; z-index: 3; pointer-events: none;
  border-radius: 50% 50% 55% 55% / 35% 35% 65% 65%;
  background: radial-gradient(circle at 35% 35%, rgba(255,255,255,.9) 0 18%, rgba(150,200,230,.75) 40%, rgba(70,120,160,.55) 100%);
  box-shadow: 0 0 4px rgba(160,210,255,.45);
  animation: land-drip 2.4s ease-in forwards;
}
@keyframes land-drip {
  0% { transform: translateY(0) scale(.2, .3); opacity: 0; }
  12% { opacity: 1; }
  45% { transform: translateY(2px) scale(.9, 1.25); }
  55% { transform: translateY(4px) scale(.85, 1.4); }
  100% { transform: translateY(var(--fall, 120px)) scale(.7, 1.6); opacity: 0; }
}
.land-flare {
  position: absolute; width: 90px; height: 90px; margin: -45px 0 0 -45px; z-index: 3; pointer-events: none; border-radius: 50%;
  background: radial-gradient(circle, #fff 0 6%, rgba(190,150,255,.9) 14%, rgba(120,80,255,.35) 34%, transparent 62%);
  mix-blend-mode: screen;
  animation: land-flare 1.2s ease-out forwards;
}
.land-flare::before, .land-flare::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 120%; height: 2px; margin: -1px 0 0 -60%;
  background: linear-gradient(90deg, transparent, rgba(230,210,255,.95), transparent);
}
.land-flare::after { transform: rotate(90deg); }
.land-flare-fire { background: radial-gradient(circle, #fff 0 6%, rgba(255,200,90,.95) 16%, rgba(255,90,20,.45) 36%, transparent 64%); }
.land-flare-steel { background: radial-gradient(circle, #fff 0 6%, rgba(200,230,255,.9) 14%, rgba(120,170,255,.35) 34%, transparent 62%); }
@keyframes land-flare {
  0% { transform: scale(.2) rotate(0deg); opacity: 0; }
  20% { transform: scale(1.05) rotate(20deg); opacity: 1; }
  100% { transform: scale(.55) rotate(70deg); opacity: 0; }
}
.land-bat {
  position: fixed; top: var(--y0, 20vh); left: 0; width: var(--size, 34px); z-index: 30; pointer-events: none;
  animation: land-bat-cross var(--dur, 6s) linear forwards;
}
.land-bat svg { display: block; width: 100%; animation: land-bat-bob .5s ease-in-out infinite alternate; }
.land-bat .land-wing-l, .land-bat .land-wing-r { transform-origin: 32px 15px; animation: land-flap .16s ease-in-out infinite alternate; }
@keyframes land-flap { from { transform: scaleY(1); } to { transform: scaleY(-.45); } }
@keyframes land-bat-bob { from { transform: translateY(-5px); } to { transform: translateY(5px); } }
@keyframes land-bat-cross {
  from { transform: translate(calc(50vw - var(--dir, 1) * 60vw), 0) scaleX(var(--dir, 1)); }
  50% { transform: translate(50vw, calc(var(--y1, 20vh) - var(--y0, 20vh))) scaleX(var(--dir, 1)); }
  to { transform: translate(calc(50vw + var(--dir, 1) * 60vw), 0) scaleX(var(--dir, 1)); }
}
@media (prefers-reduced-motion: reduce) {
  #screen-title.land .hero > h1 { animation: none; }
  .land-drip, .land-flare, .land-bat { display: none; }
}

/* magic motes shed by the quill (word-lore.js sprinkle) */
.lore-mote {
  position: absolute; width: 5px; height: 5px; margin: -2px 0 0 -2px; border-radius: 50%; z-index: 5; pointer-events: none;
  background: radial-gradient(circle, #fff 0 25%, rgba(200,170,255,0.95) 50%, transparent 72%);
  box-shadow: 0 0 6px rgba(180,140,255,0.9);
  animation: lore-mote 1.05s ease-out forwards;
}
.lore-mote.gold { background: radial-gradient(circle, #fff 0 25%, rgba(255,215,110,0.95) 50%, transparent 72%); box-shadow: 0 0 6px rgba(255,200,90,0.9); }
@keyframes lore-mote {
  0% { opacity: 0; transform: translate(0, 0) scale(0.4); }
  15% { opacity: 1; transform: translate(calc(var(--mx) * 0.15), calc(var(--my) * 0.1)) scale(1.2); }
  100% { opacity: 0; transform: translate(var(--mx), var(--my)) scale(0.3); }
}
@media (prefers-reduced-motion: reduce) { .lore-mote { display: none; } .lore-word-rest, .lore-initial { animation: none; } }

/* ---- TYPING-CHEST-LADDER (game.js playChestDeposit / chestReaction) ---- */
.tt-toast-coin { position: relative; display: inline-block; }
.tt-toast-coin.tt-coin-charge svg {
  animation: tt-coin-charge var(--charge, 500ms) ease-in forwards !important;
}
@keyframes tt-coin-charge {
  0% { transform: scale(1); filter: drop-shadow(0 0 0 transparent) brightness(1); }
  60% { transform: scale(1.35); filter: drop-shadow(0 0 10px var(--tt-glow)) drop-shadow(0 0 18px var(--tt-glow)) brightness(1.5); }
  80% { transform: scale(1.25) rotate(-8deg); }
  100% { transform: scale(1.5); filter: drop-shadow(0 0 16px var(--tt-glow)) drop-shadow(0 0 30px #fff) brightness(2); }
}
.tt-toast-coin.tt-coin-gone svg { visibility: hidden; }
.tt-toast-coin.tt-coin-gone::after {
  content: ""; position: absolute; inset: -4px; border-radius: 50%;
  box-shadow: 0 0 0 2px var(--tt-glow), 0 0 12px var(--tt-glow); opacity: .7;
  animation: tt-slot-fade .9s ease-out forwards;
}
@keyframes tt-slot-fade { to { opacity: 0; transform: scale(1.6); } }

.tt-burst-spark {
  position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; z-index: 9; pointer-events: none;
  background: radial-gradient(circle, #fff 0 28%, var(--tt-glow, #f5c542) 55%, transparent 72%);
  box-shadow: 0 0 8px var(--tt-glow, #f5c542);
  animation: tt-burst-spark var(--dur, 800ms) cubic-bezier(.2,.7,.3,1) forwards;
}
@keyframes tt-burst-spark {
  0% { opacity: 1; transform: translate(0, 0) scale(1.4); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(.2); }
}
.tt-shock-ring {
  position: absolute; width: var(--ring, 120px); height: var(--ring, 120px); margin: calc(var(--ring, 120px) / -2) 0 0 calc(var(--ring, 120px) / -2);
  border-radius: 50%; z-index: 8; pointer-events: none;
  border: 3px solid var(--tt-glow); box-shadow: 0 0 18px var(--tt-glow), inset 0 0 14px var(--tt-glow);
  animation: tt-shock .85s ease-out forwards;
}
@keyframes tt-shock { from { opacity: 1; transform: scale(.15); } to { opacity: 0; transform: scale(1.25); } }
.tt-chest-rays {
  position: absolute; width: 260px; height: 260px; margin: -130px 0 0 -130px; z-index: 7; pointer-events: none; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, var(--tt-glow) 0 6deg, transparent 6deg 22deg);
  -webkit-mask-image: radial-gradient(circle, #000 0 18%, rgba(0,0,0,.6) 38%, transparent 68%);
          mask-image: radial-gradient(circle, #000 0 18%, rgba(0,0,0,.6) 38%, transparent 68%);
  mix-blend-mode: screen;
  animation: tt-rays var(--hold, 1500ms) ease-out forwards;
}
@keyframes tt-rays {
  0% { opacity: 0; transform: rotate(0) scale(.3); }
  15% { opacity: .95; transform: rotate(40deg) scale(1); }
  100% { opacity: 0; transform: rotate(200deg) scale(1.2); }
}
.tt-view-flash {
  position: absolute; inset: 0; z-index: 8; pointer-events: none; border-radius: inherit;
  background: radial-gradient(circle at var(--fx) var(--fy), rgba(255,255,255,.55), var(--tt-glow) 12%, transparent 60%);
  mix-blend-mode: screen;
  animation: tt-view-flash .85s ease-out forwards;
}
@keyframes tt-view-flash { 0% { opacity: 0; } 12% { opacity: .9; } 100% { opacity: 0; } }
.tt-bolt { position: absolute; z-index: 9; pointer-events: none; overflow: visible; filter: drop-shadow(0 0 6px #fff) drop-shadow(0 0 12px #c084fc); animation: tt-bolt .4s steps(3, end) forwards; }
@keyframes tt-bolt { 0% { opacity: 1; } 50% { opacity: .35; } 70% { opacity: 1; } 100% { opacity: 0; } }

/* chest ladder (later in the file than tt-opening, so these win on the art) */
#treasure-chest.tt-chest-glow .treasure-chest-art { filter: drop-shadow(0 0 10px var(--tt-glow)) drop-shadow(0 0 22px var(--tt-glow)) brightness(1.25); }
#treasure-chest.tt-chest-wiggle .treasure-chest-art { animation: tt-chest-wiggle var(--tt-hold, 800ms) ease-out both; }
#treasure-chest.tt-chest-bounce .treasure-chest-art { animation: tt-chest-bounce var(--tt-hold, 1100ms) cubic-bezier(.3,1.6,.5,1) both; }
#treasure-chest.tt-chest-shake .treasure-chest-art { animation: tt-chest-shake var(--tt-hold, 1500ms) ease-out both; }
#treasure-chest.tt-chest-spin .treasure-chest-art { animation: tt-chest-spin var(--tt-hold, 2400ms) cubic-bezier(.4,0,.2,1) both; }
@keyframes tt-chest-wiggle {
  0%,100% { transform: rotate(0); }
  15% { transform: rotate(-7deg) scale(1.05); } 35% { transform: rotate(6deg) scale(1.06); }
  55% { transform: rotate(-4deg); } 75% { transform: rotate(2deg); }
}
@keyframes tt-chest-bounce {
  0% { transform: translateY(0) scale(1); }
  18% { transform: translateY(-18px) scale(1.12, .94); }
  36% { transform: translateY(0) scale(.94, 1.08); }
  52% { transform: translateY(-8px) scale(1.05); }
  70%,100% { transform: translateY(0) scale(1); }
}
@keyframes tt-chest-shake {
  0% { transform: scale(1); }
  8% { transform: scale(1.18) rotate(-6deg); }
  14%,26%,38%,50% { transform: scale(1.12) translateX(-6px) rotate(-4deg); }
  20%,32%,44%,56% { transform: scale(1.12) translateX(6px) rotate(4deg); }
  75% { transform: scale(1.06); }
  100% { transform: scale(1); }
}
@keyframes tt-chest-spin {
  0% { transform: scale(1) rotateY(0); }
  12% { transform: translateY(-22px) scale(1.25) rotateY(0); }
  60% { transform: translateY(-26px) scale(1.3) rotateY(1080deg); }
  78% { transform: translateY(4px) scale(.95, 1.06) rotateY(1080deg); }
  90% { transform: translateY(-6px) scale(1.06) rotateY(1080deg); }
  100% { transform: translateY(0) scale(1) rotateY(1080deg); }
}
@media (prefers-reduced-motion: reduce) {
  .tt-burst-spark, .tt-shock-ring, .tt-chest-rays, .tt-view-flash, .tt-bolt { display: none; }
  #treasure-chest[class*="tt-chest-"] .treasure-chest-art { animation: none; }
}

/* Real-keyboard stagger for the combat board (was centred rows, which put the
   bottom row 1.33 keys right of home). Pitch 21px: home +0.25, bottom +0.75. */
.stage-keyboard-bl .kt-board { align-items: flex-start !important; }
.stage-keyboard-bl .kt-row-0 { margin-left: 0; }
.stage-keyboard-bl .kt-row-1 { margin-left: 5px; }
.stage-keyboard-bl .kt-row-2 { margin-left: 16px; }
.stage-keyboard-bl .kt-row-space { justify-content: flex-start; margin-left: 58px; }

/* ---- TYPING-POTION-FX (game.js showPotionFoundPopup) ---- */
.pf-drop {
  position: absolute; z-index: 9; pointer-events: none; display: flex; align-items: center; gap: .15rem;
  transform: translate(-50%, -50%);
  animation: pf-pop .5s cubic-bezier(.2,1.6,.4,1) both;
}
.pf-potion { width: 4.4rem; height: auto; filter: drop-shadow(0 0 10px rgba(255,70,90,.85)) drop-shadow(0 0 22px rgba(255,120,60,.5)); animation: pf-bob .6s ease-in-out infinite alternate; }
.pf-plus {
  font: 900 3.1rem/1 "Cinzel Lore", Georgia, serif; color: #ffe38a;
  text-shadow: 0 3px 0 #5a1208, 0 0 12px rgba(255,90,60,.9), 0 0 26px rgba(255,200,80,.6);
  -webkit-text-stroke: 1px #7a2a08;
}
@keyframes pf-pop { 0% { opacity: 0; transform: translate(-50%, -50%) scale(.2) rotate(-18deg); } 70% { opacity: 1; } 100% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0); } }
@keyframes pf-bob { from { transform: translateY(0) rotate(-4deg); } to { transform: translateY(-6px) rotate(4deg); } }
#potion-chip { position: relative; }
#potion-chip.pf-chip-bump { animation: pf-chip-bump .85s cubic-bezier(.3,1.6,.5,1); }
@keyframes pf-chip-bump {
  0% { transform: scale(1); box-shadow: none; }
  25% { transform: scale(1.28); box-shadow: 0 0 0 2px rgba(255,90,110,.9), 0 0 18px rgba(255,70,90,.9); }
  60% { transform: scale(.96); }
  100% { transform: scale(1); box-shadow: none; }
}
.pf-chip-plus { left: 70%; top: -10%; color: #ff8a96; font-size: 1rem; }

/* J-0926-1 narrow proof: make the combat controls a vertical deck below a
   compact scene. This intentionally does not alter the desktop stage. */
@media (max-width: 430px) {
  #screen-dungeon .viewport {
    min-height: 0;
    height: 430px;
    overflow: hidden;
  }
  #screen-dungeon .fighters { z-index: 2; height: 150px; }
  #screen-dungeon .current-fight-label {
    top: 130px;
    z-index: 12;
    font-size: 0.62rem;
    white-space: nowrap;
  }
  #screen-dungeon .stage-hud-player,
  #screen-dungeon .stage-hud-monster {
    top: 0.35rem;
    z-index: 12;
  }
  #screen-dungeon .stage-hud-player { width: calc(58% - 0.4rem); left: 0.35rem; }
  #screen-dungeon .stage-hud-monster { width: calc(39% - 0.35rem); right: 0.35rem; }
  #screen-dungeon .stage-hud-player .hud-meta { gap: 0.18rem; font-size: 0.58rem; }
  #screen-dungeon .stage-hud-player .bar-label,
  #screen-dungeon .stage-hud-monster .bar-label { font-size: 0.62rem; }
  #screen-dungeon .stage-bottom-cluster {
    top: 154px;
    bottom: auto;
    left: 0.5rem;
    right: 0.5rem;
    width: auto;
    transform: none;
    gap: 0.18rem;
    z-index: 18;
  }
  #screen-dungeon .stage-prompt { padding: 0.22rem 0.5rem 0.35rem; }
  #screen-dungeon .stage-prompt #word-display { font-size: 1.1rem; }
  #screen-dungeon .stage-prompt .timer { margin-top: 0.18rem; height: 8px; }
  #screen-dungeon .type-row { margin-top: 0.08rem; }
  #screen-dungeon #type-input { height: 36px; min-height: 36px; }
  #screen-dungeon .stage-keyboard-bl {
    top: 260px;
    bottom: auto;
    left: 0.45rem;
    right: 0.45rem;
    width: auto;
    max-width: none;
    padding: 0.22rem 0.3rem 0.28rem;
    z-index: 20;
    background: rgba(6,8,14,0.94);
    border-color: rgba(245,197,66,0.55);
  }
  #screen-dungeon .stage-keyboard-bl .kt-board { gap: 3px; width: 100%; }
  #screen-dungeon .stage-keyboard-bl .kt-row { gap: 3px; width: 100%; }
  #screen-dungeon .stage-keyboard-bl .kt-key {
    width: 27px;
    height: 19px;
    flex: 1 1 0;
    min-width: 0;
    font-size: 0.64rem;
    transform-origin: center;
  }
  #screen-dungeon .stage-keyboard-bl .kt-row-1 { margin-left: 4%; width: 92%; }
  #screen-dungeon .stage-keyboard-bl .kt-row-2 { margin-left: 9%; width: 82%; }
  #screen-dungeon .stage-keyboard-bl .kt-row-space { margin-left: 18%; width: 64%; }
  #screen-dungeon .stage-keyboard-bl .kt-key-space { width: auto; height: 18px; flex: 1 1 auto; }
  #screen-dungeon .stage-keyboard-bl .stage-pause-tip {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.22rem;
    margin: 0 0 0.18rem;
    font-size: 0.58rem;
    white-space: nowrap;
  }
  #screen-dungeon .stage-keyboard-bl .stage-pause-tip .keycap {
    min-width: 0;
    height: 1rem;
    padding: 0 0.28rem;
    font-size: 0.54rem;
  }
  #screen-dungeon .stage-loot-col {
    top: 380px;
    bottom: auto;
    left: 0.45rem;
    right: 0.45rem;
    width: auto;
    z-index: 21;
    display: grid;
    grid-template-columns: 1fr 1.2fr;
    align-items: end;
    gap: 0.4rem;
    height: 48px;
    padding: 0.18rem 0.35rem;
    border: 1px solid rgba(245,197,66,0.35);
    border-radius: 10px;
    background: rgba(6,8,14,0.92);
  }
  #screen-dungeon .stage-treasure { min-width: 0; }
  #screen-dungeon .stage-treasure .treasure-chest-art { max-height: 27px; width: auto; margin: 0 auto; }
  #screen-dungeon .stage-treasure .treasure-label { font-size: 0.58rem; }
  #screen-dungeon .stage-loot-col .strike-power-label { font-size: 0.62rem; }
  #screen-dungeon .stage-loot-col .strike-power-track { height: 8px; }
  #screen-dungeon .stage-loot-col .tt-open-chest { min-height: 28px; padding: 0.1rem 0.35rem; font-size: 0.62rem; }
}

/* J-0927-PHONE: phone-only combat deck. The desktop stage remains unchanged.
   Narrow touch layouts use a 540px viewport, hide the helper keyboard/book,
   and reserve separate bands for HUD, word input, and power/treasure. */
@media (max-width: 600px) and (pointer: coarse), (max-width: 600px) {
  body:has(#screen-dungeon.active) { overflow-y: auto; overflow-x: hidden; }
  #screen-dungeon .viewport {
    min-height: 0;
    height: 540px;
    overflow: hidden;
  }
  #screen-dungeon .stage-keyboard-bl,
  #screen-dungeon .lore-book { display: none !important; }
  #screen-dungeon .stage-hud-player,
  #screen-dungeon .stage-hud-monster {
    top: 0.45rem;
    z-index: 12;
    width: calc(50% - 0.7rem);
    padding: 0.35rem 0.45rem 0.42rem;
  }
  #screen-dungeon .stage-hud-player { left: 0.35rem; right: auto; }
  #screen-dungeon .stage-hud-monster { left: auto; right: 0.35rem; }
  #screen-dungeon .stage-hud-player .hud-meta { gap: 0.18rem; font-size: 0.62rem; }
  #screen-dungeon .stage-hud-player .bar-label,
  #screen-dungeon .stage-hud-monster .bar-label { font-size: 0.66rem; }
  #screen-dungeon .stage-hud-player .hud-meta,
  #screen-dungeon .stage-hud-player .bar-label,
  #screen-dungeon .stage-hud-monster .bar-label { white-space: nowrap; }
  #screen-dungeon .current-fight-label {
    top: 142px;
    z-index: 12;
    font-size: 0.7rem;
    white-space: nowrap;
  }
  #screen-dungeon .stage-rail {
    top: 178px;
    left: 0.35rem;
    transform: none;
    z-index: 10;
  }
  #screen-dungeon .stage-bottom-cluster {
    top: 250px;
    bottom: auto;
    left: 0.55rem;
    right: 0.55rem;
    width: auto;
    transform: none;
    gap: 0.25rem;
    z-index: 18;
  }
  #screen-dungeon .stage-prompt { padding: 0.28rem 0.55rem 0.42rem; }
  #screen-dungeon .stage-prompt #word-display { font-size: 1.15rem; }
  #screen-dungeon #type-input { height: 42px; min-height: 42px; font-size: 1.05rem; }
  #screen-dungeon .stage-loot-col {
    top: 405px;
    bottom: auto;
    left: 0.55rem;
    right: 0.55rem;
    width: auto;
    min-height: 92px;
    z-index: 21;
    display: grid;
    grid-template-columns: 1fr 1.25fr;
    align-items: center;
    gap: 0.55rem;
    padding: 0.3rem 0.45rem;
    border: 1px solid rgba(245,197,66,0.35);
    border-radius: 10px;
    background: rgba(6,8,14,0.92);
  }
  #screen-dungeon .stage-treasure { min-width: 0; }
  #screen-dungeon .stage-treasure .treasure-chest-art { max-height: 38px; width: auto; margin: 0 auto; }
  #screen-dungeon .stage-treasure .treasure-label { font-size: 0.62rem; }
  #screen-dungeon .stage-loot-col .strike-power-label { font-size: 0.68rem; }
  #screen-dungeon .stage-loot-col .strike-power-track { height: 9px; }
  #screen-dungeon .stage-loot-col .tt-open-chest { min-height: 30px; padding: 0.12rem 0.4rem; font-size: 0.66rem; }
}

/* J-0927-PHONE-DEV3: keep the phone combat bands inside the stage. The
   desktop composition above is intentionally left unchanged. */
@media (max-width: 600px) {
  #screen-dungeon .viewport {
    height: 430px;
    min-height: 430px;
  }
  #screen-dungeon .fighters { transform: translateY(4.2rem); }
  #screen-dungeon .stage-hud-player,
  #screen-dungeon .stage-hud-monster { top: 0.35rem; }
  #screen-dungeon .current-fight-label { top: 8.2rem; }
  #screen-dungeon .stage-rail {
    top: 8.5rem;
    width: 24px;
    padding: 0.22rem 0.18rem;
    gap: 0.16rem;
  }
  #screen-dungeon .stage-rail .mm-pip { height: 11px; }
  #screen-dungeon .stage-bottom-cluster { top: 13.6rem; }
  #screen-dungeon .stage-loot-col {
    top: 20.8rem;
    min-height: 5.25rem;
  }
}

/* ---- TYPING-LANDING-FRAME: the arch frame is drawn ON TOP of the hero
   (inset shadows paint under children, so swords used to cross the border) */
.land-stage { box-shadow: 0 8px 18px rgba(0,0,0,.6); }
.land-stage::after {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none; border-radius: inherit;
  box-shadow: inset 0 0 0 3px #15110c, inset 0 0 0 5px #6d5530, inset 0 0 0 6px rgba(240,200,120,.35), inset 0 0 22px rgba(0,0,0,.8);
}
.land-hero { z-index: 1; }

/* ---- TYPING-BTN-SURFACE: one clean, bevelled button face ----------------
   The former solid lower "lip" read as a second, older button behind the
   compact Daily and Resume controls. Keep depth in the face and soft shadow,
   but never paint a separate hard-edged layer below it. */
.btn {
  --btn-top: rgba(255,255,255,.14); --btn-face: #2a2621; --btn-bot: #1b1815; --btn-edge: #0d0b09; --btn-ink: #efe4c8;
  position: relative;
  background: linear-gradient(180deg, var(--btn-top) 0%, transparent 46%), linear-gradient(180deg, var(--btn-face), var(--btn-bot)) !important;
  color: var(--btn-ink) !important;
  border: 1px solid rgba(0,0,0,.55) !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), inset 0 -2px 0 rgba(0,0,0,.28), 0 4px 12px rgba(0,0,0,.38);
  text-shadow: 0 1px 0 rgba(0,0,0,.45);
  transform: translateY(0);
}
.btn-primary { --btn-top: rgba(255,255,255,.55); --btn-face: #ffd060; --btn-bot: #e0901a; --btn-edge: #8a5208; --btn-ink: #2a1804; text-shadow: 0 1px 0 rgba(255,240,190,.6) !important; }
.btn-warrior { --btn-top: rgba(255,255,255,.4); --btn-face: #f07a3a; --btn-bot: #b83a0c; --btn-edge: #6e2206; --btn-ink: #fff; }
.btn-mage { --btn-top: rgba(255,255,255,.35); --btn-face: #9a6cff; --btn-bot: #5b25c8; --btn-edge: #33137a; --btn-ink: #fff; }
.btn-ghost { --btn-top: rgba(255,255,255,.16); --btn-face: #34302a; --btn-bot: #221f1b; --btn-edge: #0e0c0a; --btn-ink: #f0e3c2; border-color: rgba(240,200,120,.28) !important; }
.btn.is-done { --btn-top: rgba(255,255,255,.4); --btn-face: #34d399; --btn-bot: #0f9d6c; --btn-edge: #065f46; --btn-ink: #04130c; }
.btn:not(:disabled):hover {
  filter: brightness(1.07); transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 -2px 0 rgba(0,0,0,.28), 0 6px 16px rgba(0,0,0,.42);
}
.btn:not(:disabled):active {
  filter: brightness(.95); transform: translateY(1px) scale(1);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25), inset 0 2px 4px rgba(0,0,0,.3), 0 2px 6px rgba(0,0,0,.35);
}
.btn:disabled { box-shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 2px 7px rgba(0,0,0,.3); }
/* small in-panel buttons get the same lip, scaled down */
.tt-burn-btn, .tt-unburn, #tt-relic-use {
  background: linear-gradient(180deg, rgba(255,255,255,.14), transparent 50%), linear-gradient(180deg, #34302a, #221f1b) !important;
  border: 1px solid rgba(240,200,120,.3) !important; color: #f0e3c2 !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 3px 0 #0e0c0a, 0 4px 8px rgba(0,0,0,.4) !important;
}
.tt-burn-btn:active, .tt-unburn:active, #tt-relic-use:active { transform: translateY(2px) !important; box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 0 #0e0c0a !important; }
@media (prefers-reduced-motion: reduce) { .btn:not(:disabled):hover, .btn:not(:disabled):active { transform: none; } }

/* Attention pulse is paint-only: its ring is a shadow, so it never changes
   flex sizing or the measured position of either landing control. */
.topbar .bgm-picker.attn-pulse, .topbar #btn-mute.attn-pulse {
  animation: attn-pulse 1.2s ease-in-out infinite;
  outline: none;
}
@media (prefers-reduced-motion: reduce) {
  .topbar .bgm-picker.attn-pulse, .topbar #btn-mute.attn-pulse {
    animation: none;
    box-shadow: 0 0 0 3px rgba(255, 200, 60, 0.9), 0 0 12px 2px rgba(255, 200, 60, 0.9);
    transform: none;
  }
}

/* ---- TYPING-SLASH-FX (game.js warriorSlashFx) ---- */
.slash-fx { position: absolute; z-index: 7; pointer-events: none; mix-blend-mode: screen;
  filter: drop-shadow(0 0 6px #fff) drop-shadow(0 0 16px rgba(255,210,120,.9)); }
.slash-fx svg { display: block; width: 100%; height: 100%; }
.slash-kill { animation: slash-down .62s cubic-bezier(.2,.8,.3,1) forwards; filter: drop-shadow(0 0 8px #fff) drop-shadow(0 0 22px rgba(255,200,100,1)) drop-shadow(0 0 40px rgba(255,160,60,.6)); }
.slash-strike { animation: slash-across .38s cubic-bezier(.2,.8,.3,1) forwards; filter: drop-shadow(0 0 5px #fff) drop-shadow(0 0 12px rgba(150,200,255,.9)); }
@keyframes slash-down {
  0% { clip-path: inset(0 0 100% 0); opacity: 1; transform: scaleX(.7); }
  30% { clip-path: inset(0 0 0 0); opacity: 1; transform: scaleX(1.15); }
  100% { clip-path: inset(0 0 0 0); opacity: 0; transform: scaleX(.6) translateY(10px); }
}
@keyframes slash-across {
  0% { clip-path: inset(0 100% 0 0); opacity: 1; }
  35% { clip-path: inset(0 0 0 0); opacity: 1; }
  100% { clip-path: inset(0 0 0 0); opacity: 0; }
}
/* J-1012-12: far-kill air strike: the crescent in flight (trail ghosts set their own
   blur) and the flash where it lands. */
.slash-fly { filter: drop-shadow(0 0 8px #fff) drop-shadow(0 0 22px rgba(255,200,100,1)); }
.slash-impact { position: absolute; z-index: 7; pointer-events: none; mix-blend-mode: screen; border-radius: 50%;
  background: radial-gradient(circle, #fff 0, rgba(255,240,200,.95) 18%, rgba(255,200,110,.6) 42%, rgba(255,160,60,0) 70%); }
#monster-rect.slash-hit img { animation: slash-hit .3s ease-out; }
@keyframes slash-hit { 0% { filter: brightness(3) saturate(0); } 100% { filter: brightness(1); } }

/* J-1001-TYPING-PLAY-ABOVE: Play button sits above the arch; leave room for the
   STRIKE!/LIGHTNING! callout. Daily buttons take the class colours but keep
   their own width. */
.class-card > .btn + .land-alcove { margin-top: 0.6rem; }
.btn-warrior[data-daily], .btn-mage[data-daily] { width: auto; }
/* J-1012-TYPING-DEV-REFINE: the bevel faded to a darker bottom, so a second
   strip showed along the lower edge of Warrior daily and Mage daily. */
.daily-actions .btn-warrior[data-daily],
.daily-actions .btn-mage[data-daily] {
  background: var(--btn-face) !important;
  border-color: rgba(0,0,0,.28) !important;
  box-shadow: 0 2px 6px rgba(0,0,0,.32) !important;
  overflow: hidden;
}
.daily-actions .btn-warrior[data-daily]:not(:disabled):hover,
.daily-actions .btn-mage[data-daily]:not(:disabled):hover {
  filter: brightness(1.08);
  transform: none;
  box-shadow: 0 2px 8px rgba(0,0,0,.4) !important;
}

/* J-1001-TYPING-PHONE-NOTE: the game is for keyboards and larger screens.
   Phones / touch-only tablets / narrow windows see this note over the page;
   "Play anyway" hides it for the tab session. */
.phone-note { display: none; }
@media (hover: none) and (pointer: coarse), (max-width: 700px) {
  html:not(.phone-note-off) .phone-note {
    display: flex; position: fixed; inset: 0; z-index: 100000; align-items: center; justify-content: center;
    padding: 1.25rem; overflow-y: auto;
    background: radial-gradient(ellipse at 50% 35%, #2a2116 0%, #0d0a07 75%);
  }
  html:not(.phone-note-off) body { overflow: hidden; }
}
.phone-note-card {
  width: min(26rem, 100%); text-align: center; padding: 1.6rem 1.3rem 1.3rem;
  border: 1px solid rgba(240,200,120,.35); border-radius: 18px;
  background: linear-gradient(180deg, rgba(60,48,32,.92), rgba(26,21,15,.95));
  box-shadow: 0 12px 40px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,230,170,.12);
  color: #eadfc4; display: flex; flex-direction: column; gap: .85rem; align-items: center;
}
.phone-note-art { width: 120px; height: 120px; object-fit: cover; border-radius: 50%; border: 2px solid #6d5530; background: #15110c; }
.phone-note-card h1 { margin: 0; font: 600 1.6rem/1.15 "Cinzel Lore", Georgia, serif; color: #f5c542; letter-spacing: .04em; }
.phone-note-card p { margin: 0; font-size: 1rem; line-height: 1.5; color: #d8ccb0; }
.phone-note-card strong { color: #fff3c4; }
.phone-note-card .btn { width: 100%; min-height: 2.9rem; }
.phone-note-anyway { background: none; border: 0; color: #b9a983; text-decoration: underline; font: inherit; font-size: .88rem; padding: .4rem; cursor: pointer; }

/* J-1001-TYPING-DAILY-NARROW: the daily box hugs its content; the spare width
   becomes a gap before Player 1 (topbar-actions has margin-left: auto). It can
   still shrink with ellipsis when the window is tight. */
@media (min-width: 1024px) {
  .daily-entry { flex: 0 1 auto; }
  .daily-actions { flex-direction: column; align-items: stretch; flex-wrap: nowrap; }
  .daily-actions .btn { white-space: nowrap; }
}

/* J-1001-TYPING-STICKY-HEADER: the header (daily, Player, Music, Mute) stays
   at the top while the landing or game page scrolls to the boards/museum.
   The full-width backing is a clipped box-shadow (ink overflow only, so no
   sideways scroll and no overflow rule on html/body, which the combat fit
   relies on). z-index 19 keeps it above page content but under every modal
   (score detail 20, exchange 45, overlays 60+). */
@media (min-width: 701px) {
  .topbar { position: sticky; top: 0; z-index: 19; padding-block: 0.15rem; }
  .topbar::before, .topbar::after {
    content: ""; position: absolute; z-index: -1; left: 0; right: 0; pointer-events: none;
    clip-path: inset(0 -100vmax);
  }
  .topbar::before { top: 0; bottom: 0; background: rgb(9, 8, 6); box-shadow: 0 0 0 100vmax rgb(9, 8, 6); }
  .topbar::after { bottom: 0; height: 1px; background: rgba(240, 200, 120, 0.22); box-shadow: 0 0 0 100vmax rgba(240, 200, 120, 0.22); }
  .app { padding-top: 0.75rem; }
}

/* J-1001-TYPING-CALLOUT-OVER: STRIKE! / KILLING SLASH! / LIGHTNING! sit on
   top of the hero inside the arch (top layer), larger, with a dark rim so
   they read over the art. No space is reserved above the arch any more. */
.land-call {
  top: 26%; z-index: 5;
  font-size: clamp(1.7rem, 2.5vw, 2.4rem);
  text-shadow: 0 0 2px #120a03, 0 2px 0 #120a03, 0 -1px 0 #120a03, 2px 0 0 #120a03, -2px 0 0 #120a03,
    0 0 12px rgba(255,190,80,.95), 0 0 26px rgba(255,120,30,.7);
}
.land-call.big {
  font-size: clamp(2.1rem, 3.2vw, 3rem);
  text-shadow: 0 0 2px #1a0505, 0 2px 0 #1a0505, 0 -1px 0 #1a0505, 2px 0 0 #1a0505, -2px 0 0 #1a0505,
    0 0 14px rgba(255,90,40,.95), 0 0 32px rgba(255,40,20,.75);
}
.land-alcove-mage .land-call {
  text-shadow: 0 0 2px #050a1a, 0 2px 0 #050a1a, 0 -1px 0 #050a1a, 2px 0 0 #050a1a, -2px 0 0 #050a1a,
    0 0 12px rgba(120,190,255,.95), 0 0 26px rgba(90,120,255,.7);
}
.land-alcove-mage .land-call.big {
  text-shadow: 0 0 2px #1a0805, 0 2px 0 #1a0805, 0 -1px 0 #1a0805, 2px 0 0 #1a0805, -2px 0 0 #1a0805,
    0 0 14px rgba(255,140,40,.95), 0 0 32px rgba(255,70,20,.75);
}

/* J-1001-TYPING-KB-TIGHT: the keyboard box hugs the keys (Q..P row is the
   widest) instead of a fixed share of the stage, so there is no dead space
   right of P. The ghost hands are placed from the F/J keys, not the box size;
   .kt-surface already clips them, so a hand reaching past P is cut off. */
@media (min-width: 641px) {
  #screen-dungeon .stage-keyboard-bl, .stage-keyboard-bl { width: max-content; max-width: none; }
}

/* J-1001-TYPING-DISPLACER-MIRROR: flip right-facing monster art toward the hero. */
.monster-rect.monster-mirror img, .monster-queue-slot.monster-mirror img { transform: scaleX(-1); }
/* the displacer's final death frame stays unflipped so its face reads */
.monster-rect.monster-mirror img[src*="displacer/death_f04"] { transform: none; }

/* J-1012-13: Goblin falls backward, so only the held ground pose faces away
   from the hero. Keep death_mid/deathhit/dead_mid untouched: this preserves
   the established fall and its lower corpse anchor in front of the next foe. */
.monster-rect img[src*="goblin-v2/dead.webp"] { transform: scaleX(-1); }

/* J-1001-TYPING-MAGE-ZAP: staff-to-foe bolt (mageZapFx). */
.zap-fx { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 6; overflow: visible; }
.zap-fx .zap-glow { fill: none; stroke: #5fb4ff; stroke-width: 14; stroke-linejoin: round; stroke-linecap: round; opacity: .55; filter: blur(5px); }
.zap-fx .zap-core { fill: none; stroke: #fff; stroke-width: 3.5; stroke-linejoin: round; stroke-linecap: round; filter: drop-shadow(0 0 4px #bfe6ff) drop-shadow(0 0 10px #4aa8ff); }
.zap-fx .zap-fork { fill: none; stroke: #dff2ff; stroke-width: 2; stroke-linejoin: round; opacity: .85; filter: drop-shadow(0 0 6px #4aa8ff); }
.zap-fx .zap-burst { fill: #e8f6ff; opacity: .55; filter: blur(10px); animation: zap-burst .34s ease-out forwards; }
@keyframes zap-burst { 0% { opacity: .85; transform-box: fill-box; transform-origin: center; transform: scale(.4); } 100% { opacity: 0; transform-box: fill-box; transform-origin: center; transform: scale(1.4); } }
.viewport.zap-shake { animation: zap-shake .26s linear; }
@keyframes zap-shake { 0%,100% { translate: 0 0; } 20% { translate: -5px 2px; } 40% { translate: 4px -3px; } 60% { translate: -3px 2px; } 80% { translate: 2px -1px; } }
@media (prefers-reduced-motion: reduce) { .viewport.zap-shake { animation: none; } }

/* J-1002-TYPING-DEFEND-QUIP: hero speech bubble after a successful boss defend.
   left/top = the hero's head top (game.js heroHeadPoint); the tail tip sits
   at 22% across the bubble, 12px above the head. */
.hero-quip {
  position: absolute; z-index: 5; pointer-events: none;
  --quip-x: -22%; --quip-y: calc(-100% - 22px);
  translate: var(--quip-x) var(--quip-y);
  padding: .3rem .75rem; border-radius: 1rem; background: #fffaf0; color: #2a1406;
  font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; font-size: clamp(1rem, 1.8vw, 1.45rem); white-space: nowrap;
  border: 2px solid #2a1406; box-shadow: 0 3px 0 rgba(0,0,0,.35), 0 0 14px rgba(255,220,140,.55);
  transform-origin: 22% 100%;
  animation: hero-quip-pop 1.35s cubic-bezier(.2,1.4,.4,1) both;
}
.hero-quip::after { content: ""; position: absolute; left: 22%; bottom: -9px; width: 14px; height: 14px; margin-left: -7px; background: #fffaf0;
  border-right: 2px solid #2a1406; border-bottom: 2px solid #2a1406; transform: rotate(45deg); }
@keyframes hero-quip-pop {
  0% { opacity: 0; scale: .4; rotate: -8deg; }
  14% { opacity: 1; scale: 1.08; rotate: 3deg; }
  24% { scale: 1; rotate: -2deg; }
  80% { opacity: 1; translate: var(--quip-x) var(--quip-y); }
  100% { opacity: 0; translate: var(--quip-x) calc(var(--quip-y) - 26px); }
}

/* J-1002-TYPING-BOOK-C: thick page block (word-lore.js builds the sheets and
   the gull-wing outlines). Sheets sit under the paper layer (z -1). */
.lore-stack-sheet { position: absolute; inset: 0; z-index: -2; pointer-events: none; }
.lore-stack-sheet.a { background: linear-gradient(180deg, #efdfb4, #d9bf86); }
.lore-stack-sheet.b { background: linear-gradient(180deg, #c9ab70, #9c7c45); }
.lore-spread::after { display: none; } /* old flat page-edge strip */
.lore-gutter { position: absolute; left: 50%; top: 4%; bottom: 6%; width: 9%; translate: -50% 0; z-index: 2; pointer-events: none;
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(30,14,4,.55), transparent 70%); }
/* text clears the page stack's fore-edge inset (8 sheets x 1.1% = 8.8% of the page) */
.lore-left .lore-ink-wrap { padding-left: 7%; }
.lore-right .lore-ink-wrap { padding-right: 7%; }

/* J-1002-TYPING-CHEST-LID: lid animation overlay (game.js chestLid). Behind
   the power meter; follows the same rarity wiggle/bounce/glow as the art. */
#treasure-chest { position: relative; }
.stage-loot-col #strike-power { position: relative; z-index: 2; }
.chest-lid-frame { position: absolute; z-index: 1; height: auto; pointer-events: none; display: block; }
.chest-lid-frame[hidden] { display: none; }
#treasure-chest.tt-chest-glow .chest-lid-frame { filter: drop-shadow(0 0 10px var(--tt-glow)) drop-shadow(0 0 22px var(--tt-glow)) brightness(1.25); }
#treasure-chest.tt-chest-wiggle .chest-lid-frame { animation: tt-chest-wiggle var(--tt-hold, 800ms) ease-out both; }
#treasure-chest.tt-chest-bounce .chest-lid-frame { animation: tt-chest-bounce var(--tt-hold, 1100ms) cubic-bezier(.3,1.6,.5,1) both; }
#treasure-chest.tt-chest-shake .chest-lid-frame { animation: tt-chest-shake var(--tt-hold, 1500ms) ease-out both; }
#treasure-chest.tt-chest-spin .chest-lid-frame { animation: tt-chest-spin var(--tt-hold, 2400ms) cubic-bezier(.4,0,.2,1) both; }
@media (prefers-reduced-motion: reduce) { .chest-lid-frame { display: none !important; } }

/* J-1002-TYPING-SCORE: live score under the monster HP box (game.js placeScoreHud
   sets top/right/width from #monster-panel). Game score, monsters vanquished,
   the current monster's average so far, and the current word's 10 counting
   down with its timer. */
.stage-hud-score {
  left: auto; bottom: auto; margin: 0; padding: 0.3rem 0.55rem 0.4rem;
  display: grid; gap: 0.08rem; font-size: 0.78rem; pointer-events: none;
}
.score-hud-row { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; color: var(--muted); line-height: 1.3; }
.score-hud-row strong { color: #f3e6c4; font-variant-numeric: tabular-nums; }
.score-hud-total strong { color: var(--gold); font-size: 1.15rem; }
#score-monster.neg, #score-word.neg { color: #ff6b6b; }
.score-word-bar { height: 5px; border-radius: 3px; background: rgba(255,255,255,.12); overflow: hidden; margin-top: 0.12rem; }
.score-word-bar span { display: block; height: 100%; width: 100%; background: linear-gradient(90deg, #f5c542, #7bdc8a); }
@media (max-width: 640px) { .stage-hud-score { display: none; } }

/* J-1002-TYPING-SCORE look: a little parchment scroll (rolled ends top and
   bottom) with the numbers inked as glowing runes. Fonts are the lore book's. */
.stage-hud-score.hud-panel {
  background:
    radial-gradient(circle at 20% 30%, rgba(140,90,30,.16), transparent 40%),
    radial-gradient(circle at 80% 75%, rgba(120,75,25,.14), transparent 35%),
    linear-gradient(180deg, #e8d3a2, #dcc28a 55%, #cfb175);
  border: 0; border-radius: 3px;
  box-shadow: inset 0 0 14px rgba(110,70,25,.45), 0 6px 14px rgba(0,0,0,.45);
  padding: 0.55rem 0.7rem 0.6rem; margin-top: 6px; overflow: visible;
  color: #3a2410;
}
.stage-hud-score.hud-panel::before, .stage-hud-score.hud-panel::after {
  content: ""; position: absolute; left: -6px; right: -6px; height: 10px; border-radius: 6px; pointer-events: none;
  background: linear-gradient(180deg, #f1e0b5 0%, #c9a866 45%, #8a6532 80%, #6b4a22 100%);
  box-shadow: 0 2px 4px rgba(0,0,0,.45);
}
.stage-hud-score.hud-panel::before { top: -6px; }
.stage-hud-score.hud-panel::after { bottom: -6px; }
.stage-hud-score .score-hud-row { color: #6b4520; font-family: "Fell Lore", Georgia, serif; font-style: italic; font-size: 0.95rem; line-height: 1.25; }
.stage-hud-score .score-hud-row strong {
  font-family: "Cinzel Lore", Georgia, serif; font-style: normal; font-weight: 600; letter-spacing: .06em;
  color: #ffd257;
  text-shadow: 0 0 1px #2a1200, 0 0 1px #2a1200, 0 1px 1px #2a1200, 0 0 7px rgba(255,150,30,.95), 0 0 14px rgba(255,110,0,.6);
  animation: score-rune-glow 2.6s ease-in-out infinite;
}
.stage-hud-score .score-hud-total { border-bottom: 1px solid rgba(110,70,25,.35); padding-bottom: .15rem; margin-bottom: .1rem; }
.stage-hud-score .score-hud-total span { font-family: "Cinzel Lore", Georgia, serif; font-style: normal; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; font-size: 0.82rem; }
.stage-hud-score .score-hud-total strong { font-size: 1.45rem; }
/* below-zero runes burn red */
.stage-hud-score #score-monster.neg, .stage-hud-score #score-word.neg {
  color: #ff8a6b; text-shadow: 0 0 1px #2a0400, 0 0 1px #2a0400, 0 1px 1px #2a0400, 0 0 7px rgba(255,60,30,.95), 0 0 14px rgba(200,20,10,.6);
}
.stage-hud-score .score-word-bar { background: rgba(90,55,20,.25); box-shadow: inset 0 1px 2px rgba(60,30,5,.4); }
.stage-hud-score .score-word-bar span { background: linear-gradient(90deg, #ffb52e, #fff1a8); box-shadow: 0 0 6px #ffb52e; }
@keyframes score-rune-glow {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.18); }
}
@media (prefers-reduced-motion: reduce) { .stage-hud-score .score-hud-row strong { animation: none; } }

/* J-1002-TYPING-FIRST-CUE: the giant first letter (game.js firstLetterCue) */
.first-letter-cue {
  position: absolute; z-index: 40; pointer-events: none; line-height: 1; font-weight: 800;
  color: #ffe08a;
  text-shadow: 0 0 2px #fff, 0 0 18px rgba(255,200,60,.95), 0 0 48px rgba(255,150,20,.7), 0 6px 0 rgba(60,30,0,.55);
  will-change: transform, opacity;
}
#word-display span.first-cue-hit { animation: first-cue-hit .7s ease-out; }
@keyframes first-cue-hit {
  0%, 30% { color: #fff; text-shadow: 0 0 4px #fff, 0 0 16px #ffd34d, 0 0 34px #ff9f1a, 0 0 54px #ff7a00; }
  100% { text-shadow: none; }
}

/* J-1002-TYPING-BOSS-SIZE: hall mini-bosses keep their red glow in the line
   (game.js marks the slot .queue-boss and sizes it 10% up). */
.monster-queue-slot.queue-boss img {
  filter: drop-shadow(0 0 5px rgba(255,90,90,.9)) drop-shadow(0 0 14px rgba(255,35,45,.85)) drop-shadow(0 0 28px rgba(190,0,16,.6));
  animation: queue-boss-red 1.05s ease-in-out infinite alternate;
}
@keyframes queue-boss-red {
  from { filter: drop-shadow(0 0 4px rgba(255,90,90,.75)) drop-shadow(0 0 10px rgba(255,30,40,.7)); }
  to { filter: brightness(1.1) saturate(1.4) drop-shadow(0 0 7px rgba(255,120,120,.95)) drop-shadow(0 0 20px rgba(255,25,35,.95)) drop-shadow(0 0 36px rgba(180,0,12,.7)); }
}
@media (prefers-reduced-motion: reduce) { .monster-queue-slot.queue-boss img { animation: none; } }

/* J-1002-TYPING-SCORE v3: the scroll art is 50% see-through on its own layer
   (.score-scroll-bg, swap in Courtney's scroll image here); the writing stays
   solid. Total = magical blue, monster = fiery orange, word = silver. */
.stage-hud-score.hud-panel { background: none; box-shadow: none; }
.stage-hud-score.hud-panel::before, .stage-hud-score.hud-panel::after { display: none; }
.stage-hud-score > :not(.score-scroll-bg) { position: relative; z-index: 1; }
.score-scroll-bg {
  position: absolute; inset: 0; z-index: 0; opacity: .5; border-radius: 3px; pointer-events: none;
  background:
    radial-gradient(circle at 20% 30%, rgba(140,90,30,.16), transparent 40%),
    radial-gradient(circle at 80% 75%, rgba(120,75,25,.14), transparent 35%),
    linear-gradient(180deg, #e8d3a2, #dcc28a 55%, #cfb175);
  box-shadow: inset 0 0 14px rgba(110,70,25,.45), 0 6px 14px rgba(0,0,0,.45);
}
.score-scroll-bg::before, .score-scroll-bg::after {
  content: ""; position: absolute; left: -6px; right: -6px; height: 10px; border-radius: 6px;
  background: linear-gradient(180deg, #f1e0b5 0%, #c9a866 45%, #8a6532 80%, #6b4a22 100%);
}
.score-scroll-bg::before { top: -6px; }
.score-scroll-bg::after { bottom: -6px; }
/* labels: dark ink with a pale halo so they read over the see-through scroll */
.stage-hud-score .score-hud-row { color: #2e1a08; text-shadow: 0 0 3px rgba(255,238,200,.95), 0 0 6px rgba(255,230,180,.6); }
.stage-hud-score .score-hud-row strong { display: inline-block; transform-origin: 100% 60%; }
#score-total {
  color: #cfeaff;
  text-shadow: 0 0 1px #001226, 0 0 1px #001226, 0 1px 1px #001226, 0 0 8px rgba(90,180,255,.95), 0 0 18px rgba(40,110,255,.75);
  animation: score-blue-glow 2.4s ease-in-out infinite;
}
#score-monster, #score-kills {
  color: #ffb347;
  text-shadow: 0 0 1px #2a0c00, 0 0 1px #2a0c00, 0 1px 1px #2a0c00, 0 0 7px rgba(255,110,0,.95), 0 0 14px rgba(255,50,0,.65);
  animation: score-fire 1.1s ease-in-out infinite alternate;
}
#score-word {
  color: #f4f7fb;
  text-shadow: 0 0 1px #1a1f26, 0 0 1px #1a1f26, 0 1px 1px #1a1f26, 0 0 6px rgba(225,235,255,.9), 0 0 12px rgba(160,185,220,.6);
  animation: none;
}
.stage-hud-score .score-word-bar span { background: linear-gradient(90deg, #aab6c6, #ffffff); box-shadow: 0 0 6px rgba(220,230,255,.9); }
@keyframes score-blue-glow { 0%,100% { filter: brightness(1); } 50% { filter: brightness(1.22); } }
@keyframes score-fire { 0% { filter: brightness(1); } 100% { filter: brightness(1.18) saturate(1.2); } }
/* word cleared: silver flash; it lands in the monster score (orange pulse) */
#score-word.score-word-done { animation: score-word-done .45s ease-out; }
@keyframes score-word-done { 0% { filter: brightness(2.2); transform: scale(1.25); } 100% { filter: none; transform: none; } }
#score-monster.score-monster-take { animation: score-monster-take .4s ease-out; }
@keyframes score-monster-take { 0% { transform: scale(1.3); filter: brightness(1.8); } 100% { transform: none; filter: none; } }
/* monster done: its final score flashes magical blue before flying to the total */
#score-monster.score-final { animation: score-final .9s ease-out; }
@keyframes score-final {
  0% { color: #fff; text-shadow: 0 0 2px #fff, 0 0 12px #6cc3ff, 0 0 26px #2a6bff; transform: scale(1.5); }
  45% { color: #cfeaff; text-shadow: 0 0 1px #001226, 0 0 10px #5ab4ff, 0 0 20px #2a6bff; transform: scale(1.15); }
  100% { transform: none; }
}
/* the total bounces and flashes as the gain lands */
#score-total.score-bump { animation: score-bump .7s cubic-bezier(.3,1.7,.5,1); }
@keyframes score-bump {
  0% { transform: scale(1); }
  25% { transform: scale(1.55); color: #fff; text-shadow: 0 0 3px #fff, 0 0 16px #8fd3ff, 0 0 34px #3a7bff, 0 0 50px #2a5bff; }
  55% { transform: scale(.92); }
  80% { transform: scale(1.06); }
  100% { transform: scale(1); }
}
.score-fly {
  position: fixed; z-index: 9999; pointer-events: none; white-space: nowrap;
  font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; font-size: 1.25rem; letter-spacing: .04em;
}
.score-fly-monster { color: #cfeaff; text-shadow: 0 0 2px #fff, 0 0 10px #5ab4ff, 0 0 22px #2a6bff; }
.score-fly-credit { color: #ffe9a8; text-shadow: 0 0 2px #fff, 0 0 10px #ffb347, 0 0 22px #5ab4ff; font-size: 1.05rem; }
.score-fly-word { color: #f4f7fb; font-size: .95rem; text-shadow: 0 0 2px #fff, 0 0 8px rgba(220,230,255,.95); }
@media (prefers-reduced-motion: reduce) { #score-total, #score-monster, #score-kills { animation: none; } }

/* J-1002-TYPING-SCORE v4: Courtney's scroll art (assets/ui/score-scroll.webp,
   cut from her Grok image, white fringe removed) at 50%; the box takes the
   art's shape and the writing sits inside the parchment (13-88% across,
   ~17-83% down). */
.stage-hud-score.hud-panel { align-content: center; border-radius: 0; box-sizing: border-box; bottom: auto; }   /* size + padding: game.js placeScoreHud */
.stage-hud-score .score-hud-row { font-size: 0.86rem; white-space: nowrap; }
.stage-hud-score .score-hud-total strong { font-size: 1.3rem; }
.score-scroll-bg { background: url("../assets/ui/score-scroll.webp?v=scroll1") center / 100% 100% no-repeat; box-shadow: none; border-radius: 0; }
.score-scroll-bg::before, .score-scroll-bg::after { display: none; }

/* J-1002-TYPING-BOOK-IMG: painted grimoire. The spread is the art's shape
   (1553 x 997 before export); text boxes sit inside each page's parchment,
   clear of the torn edges and the gutter ornaments (fractions measured from
   the rectified art, ~/claude-work/typing-1002/book/GEOM.md). Flat pages: the
   art carries the curl, so no V-fold and no slanted ink. */
.lore-book.lore-img { width: min(48%, 31rem); }
.lore-img .lore-spread {
  display: block; height: auto; aspect-ratio: 1553 / 997; padding: 0; perspective: none; transform-style: flat;
  background: url("../assets/lore/book.webp?v=bookimg1") center / 100% 100% no-repeat;
}
.lore-img .lore-spread::before, .lore-img .lore-spread::after, .lore-img .lore-gutter, .lore-img .lore-stack-sheet { display: none; }
.lore-img .lore-page { position: absolute; padding: 0; transform: none; isolation: auto; }
.lore-img .lore-page::before, .lore-img .lore-page::after { display: none; }
.lore-img .lore-left  { left: 14.49%; top: 7.52%; width: 30.58%; height: 71.72%; }
.lore-img .lore-right { left: 56.99%; top: 8.02%; width: 29.94%; height: 71.72%; }
.lore-img .lore-left .lore-ink-wrap, .lore-img .lore-right .lore-ink-wrap,
.lore-img .lore-leaf-back > div, .lore-img .lore-leaf-front > .lore-body { transform: none; padding-left: 0; padding-right: 0; }
.lore-img .lore-folio { bottom: -1.1rem; }
/* the turning leaf is the right page's own parchment (814,23 - 1391,865 of 1553 x 997) */
.lore-img .lore-leaf { left: 52.41%; top: 2.31%; width: 37.15%; height: 84.45%; bottom: auto; }
.lore-img .lore-leaf-face { padding: 6.7% 7.4% 6.7% 9%; background: url("../assets/lore/book.webp?v=bookimg1") 83.4% 14.8% / 269.2% 118.4% no-repeat; }
.lore-img .lore-leaf-back { background-position: 18.3% 13.2%; background-size: 273.4% 119%; }
@media (max-width: 900px) { .lore-book.lore-img { width: min(50%, 22rem); } }
/* painted page turn frames: taller canvas (1555 x 1219) whose book area is
   x 1..1554, y 220..1217 -- laid over the spread so the covers coincide */
.lore-img .lore-turnart { position: absolute; left: -0.06%; top: -22.07%; width: 100.13%; height: 122.27%; z-index: 3; pointer-events: none; }
.lore-img .lore-turnart[hidden] { display: none; }
.lore-img.turning-img .lore-ink-wrap, .lore-img.turning-img .lore-folio, .lore-img.turning-img .lore-quill { visibility: hidden; }

/* J-1002: the painted book floats up-left, more see-through, with a slow
   sway (translate/rotate compose with the wall tilt in transform) and the
   odd rising sparkle.
   J-1004-TYPING-BOOK-DOWN: top was 10% (13% under 850px tall windows), which
   put the cover behind the player HUD. 6.6rem sits the cover just under that
   rem-sized panel, and the same rem scales with the fit zoom at every width.
   The 8px float still clears the panel. */
.lore-book.lore-img { left: 2.2rem; top: 6.6rem; }
.lore-book.lore-img.show { opacity: 0.66; animation: lore-book-float 7s ease-in-out infinite; }
@keyframes lore-book-float {
  0%, 100% { translate: 0 0; rotate: 0deg; }
  25% { translate: 2px -5px; rotate: 0.5deg; }
  50% { translate: 0 -8px; rotate: 0deg; }
  75% { translate: -2px -4px; rotate: -0.5deg; }
}
@media (max-height: 850px) { .lore-book.lore-img { top: 6.6rem; } }
.lore-sparkle {
  position: absolute; z-index: 4; width: var(--size, 4px); height: var(--size, 4px); border-radius: 50%; pointer-events: none; opacity: 0;
  background: radial-gradient(circle, #fff 0 30%, rgba(190,225,255,.95) 55%, transparent 75%);
  box-shadow: 0 0 6px rgba(170,215,255,.95);
  animation: lore-sparkle-rise 2s ease-out forwards;
}
.lore-sparkle.gold { background: radial-gradient(circle, #fff 0 30%, rgba(255,215,110,.95) 55%, transparent 75%); box-shadow: 0 0 6px rgba(255,200,90,.95); }
.lore-sparkle.violet { background: radial-gradient(circle, #fff 0 30%, rgba(200,170,255,.95) 55%, transparent 75%); box-shadow: 0 0 6px rgba(180,140,255,.95); }
@keyframes lore-sparkle-rise {
  0% { opacity: 0; transform: translate(0, 0) scale(.6); }
  15% { opacity: 1; }
  70% { opacity: .85; }
  100% { opacity: 0; transform: translate(var(--drift, 0), var(--rise, -60px)) scale(.3); }
}
@media (prefers-reduced-motion: reduce) { .lore-book.lore-img.show { animation: none; } .lore-sparkle { display: none; } }

/* J-1002-TYPING-TRADE-SCROLL: hall 3/6/9 exchange as an ancient scroll.
   Rods + parchment cut from Courtney's scroll art. Closed: rods together;
   .unrolling drops the bottom rod while the parchment unrolls, then the
   writing fades in. */
.hall-exchange .hall-exchange-card.ex-scroll {
  position: relative; width: min(36rem, 94vw); max-width: none; padding: 0; background: none; border: 0; box-shadow: none;
  filter: drop-shadow(0 18px 26px rgba(0,0,0,.6));
}
.ex-rod { position: relative; z-index: 2; display: block; width: 100%; height: auto; pointer-events: none; }
.ex-rod-top { margin-bottom: -3.2%; }
.ex-rod-bottom { margin-top: -3.2%; }
.ex-parchment {
  position: relative; z-index: 1; margin: 0 12.4% 0 12.2%;   /* the paper's span under the rods */
  background: url("../assets/ui/scroll-parchment.webp?v=trade2") center / 100% 100% no-repeat;
  overflow: hidden; max-height: 60rem;
}
.ex-content { min-height: 0; padding: 1.5rem 1.3rem 1.2rem; color: #3a2410; text-align: center; }
.ex-scroll h2 {
  margin: 0 0 .25rem; font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; font-size: 1.45rem; letter-spacing: .08em; color: #5a1a0c;
  text-shadow: 0 1px 0 rgba(255,240,200,.7);
}
.ex-scroll .hall-exchange-lead, .ex-scroll #hall-exchange-meta, .ex-scroll #hall-exchange-detail {
  font-family: "Fell Lore", Georgia, serif; font-style: italic; font-size: 1.05rem; color: #4a2c12; margin: .15rem 0 .35rem;
}
.ex-scroll fieldset { min-width: 0; border: 0; border-top: 1px solid rgba(110,70,25,.45); border-bottom: 1px solid rgba(110,70,25,.45); margin: .5rem 0; padding: .45rem .2rem; text-align: left; }
.ex-scroll legend { font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; font-size: .82rem; letter-spacing: .14em; text-transform: uppercase; color: #6b4520; padding: 0 .5rem; margin: 0 auto; }
.ex-scroll label { font-family: "Fell Lore", Georgia, serif; font-style: italic; font-size: 1.15rem; color: #2e1a08; cursor: pointer; min-height: 2.6rem; }
.ex-scroll label:has(input:disabled) { opacity: .45; cursor: not-allowed; }
/* wax-seal radios */
.ex-scroll input[type="radio"] { position: absolute; opacity: 0; width: 1px; height: 1px; }
.ex-seal {
  flex: none; width: 1.55rem; height: 1.55rem; border-radius: 50%; position: relative;
  background: radial-gradient(circle at 35% 30%, #e9d2a0, #b89058 60%, #7a5a2c);
  box-shadow: inset 0 0 0 2px #5a3a14, inset 0 2px 3px rgba(255,240,200,.5), 0 1px 2px rgba(0,0,0,.4);
}
.ex-scroll input:checked + .ex-seal {
  background: radial-gradient(circle at 35% 30%, #e0504a, #9e1c16 55%, #5c0a06);
  box-shadow: inset 0 0 0 2px #4a0804, inset 0 2px 3px rgba(255,170,150,.45), 0 0 8px rgba(200,40,30,.55), 0 1px 2px rgba(0,0,0,.5);
}
.ex-scroll input:checked + .ex-seal::after {
  content: "\2726"; position: absolute; inset: 0; display: grid; place-items: center; color: #f3c9a8; font-size: .85rem; text-shadow: 0 0 2px #4a0804;
}
.ex-scroll input:focus-visible + .ex-seal { outline: 2px solid #f5c542; outline-offset: 3px; }
/* bronze plaque button */
.hall-exchange .ex-scroll .btn.ex-confirm {
  --btn-top: rgba(255,235,180,.55); --btn-face: #9a6a2e; --btn-bot: #5e3c14; --btn-edge: #2a1806; --btn-ink: #fff2cf;
  margin: .55rem auto 0; display: inline-flex; gap: .45rem; align-items: baseline; width: auto; padding: .45rem 1.4rem;
  font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; font-size: 1.05rem; letter-spacing: .1em; color: #fff2cf;
  background: linear-gradient(180deg, #b98a46, #8a5f26 45%, #5e3c14);
  border: 2px solid #3e260a; border-radius: 6px;
  box-shadow: inset 0 1px 0 rgba(255,235,180,.55), inset 0 -2px 0 rgba(0,0,0,.35), 0 3px 0 #2a1806, 0 5px 10px rgba(0,0,0,.4);
  text-shadow: 0 1px 1px #2a1606;
}
.hall-exchange .ex-scroll .btn.ex-confirm:hover { filter: brightness(1.12); background: linear-gradient(180deg, #c99a56, #9a6f36 45%, #6e4c24); }
.ex-scroll .ex-key { font-family: "Fell Lore", Georgia, serif; font-style: italic; font-weight: 400; font-size: .85rem; letter-spacing: 0; opacity: .85; }
/* unroll */
.ex-scroll.unrolling .ex-parchment { animation: ex-unroll .75s cubic-bezier(.3,.6,.25,1) both; }
.ex-scroll.unrolling .ex-content { animation: ex-ink .5s ease .7s both; }
.ex-scroll.unrolling .ex-rod-top { animation: ex-appear .25s ease both; }
.ex-scroll.unrolling .ex-rod-bottom { animation: ex-appear .25s ease both, ex-rod-spin .75s linear both; }
@keyframes ex-unroll { from { max-height: 0; } to { max-height: 34rem; } }
@keyframes ex-ink { from { opacity: 0; filter: blur(3px); } to { opacity: 1; filter: none; } }
@keyframes ex-appear { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@keyframes ex-rod-spin { 0%,100% { filter: brightness(1); } 25%,75% { filter: brightness(1.15); } 50% { filter: brightness(.9); } }
@media (prefers-reduced-motion: reduce) { .ex-scroll.unrolling .ex-parchment, .ex-scroll.unrolling .ex-content, .ex-scroll.unrolling .ex-rod-top, .ex-scroll.unrolling .ex-rod-bottom { animation: none; } }
.ex-scroll #hall-exchange-detail, .ex-scroll #hall-exchange-meta { white-space: normal; overflow-wrap: anywhere; max-width: 100%; }
.ex-scroll.unrolling .ex-parchment { max-height: 34rem; }

/* J-1005-TYPING-MUSIC-PICKER: checkbox menu. Labels stay whole at 1440 and 390. */
.bgm-picker { align-items: center; }
.bgm-picker-kicker { flex: 0 0 auto; }
.bgm-picker-toggle {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 0.45rem;
  min-height: 30px; width: auto; max-width: none; padding: 0.2rem 0.65rem;
  border: 1px solid var(--line); border-radius: 0.35rem;
  background: var(--panel); color: var(--ink); font: inherit; font-weight: 700;
  text-transform: none; letter-spacing: 0; white-space: nowrap; cursor: pointer;
}
.bgm-picker-toggle::after {
  content: ""; flex: 0 0 auto; width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid currentColor;
}
.bgm-picker-value { white-space: nowrap; overflow: visible; text-overflow: clip; text-transform: none; }
.bgm-picker.is-open { z-index: 60; }
.bgm-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 61;
  width: max(20rem, 100%); max-width: calc(100vw - 16px);
  max-height: min(70vh, 28rem); overflow: auto;
  padding: 0.35rem; border: 1px solid rgba(245,197,66,0.55); border-radius: 12px;
  background: #141a2e; box-shadow: 0 16px 40px rgba(0,0,0,0.5);
  text-transform: none; letter-spacing: 0; font-weight: 700; white-space: normal;
}
.bgm-menu[hidden] { display: none; }
.bgm-random, .bgm-song {
  display: flex; align-items: flex-start; gap: 0.6rem; width: 100%;
  min-height: 44px; margin: 0; padding: 0.45rem 0.55rem; box-sizing: border-box;
  border: 1px solid transparent; border-radius: 8px;
  background: transparent; color: #eef1ff; text-align: left;
  font: inherit; font-weight: 700; font-size: 0.95rem; line-height: 1.35;
  text-transform: none; letter-spacing: 0; white-space: normal; overflow: visible;
  cursor: pointer;
}
.bgm-song span, .bgm-random { overflow: visible; text-overflow: clip; overflow-wrap: break-word; }
.bgm-song input {
  flex: 0 0 auto; width: 1.15rem; height: 1.15rem; margin: 0.15rem 0 0;
  accent-color: #f5c542;
}
.bgm-random[aria-checked="true"], .bgm-song:has(input:checked) {
  border-color: rgba(245,197,66,0.7); background: rgba(245,197,66,0.12);
}
.bgm-picker-toggle:focus-visible, .bgm-random:focus-visible, .bgm-song input:focus-visible {
  outline: 2px solid #f5c542; outline-offset: 2px;
}
@media (min-width: 1024px) {
  .bgm-picker { flex: 0 0 auto; min-width: max-content; }
  .bgm-picker-toggle { width: auto; max-width: none; }
}
@media (min-width: 641px) and (max-width: 1023px) {
  body:has(#screen-dungeon.active) .topbar-actions .bgm-picker-toggle {
    width: auto; max-width: none; min-height: 30px; font-size: 0.72rem;
  }
}
@media (max-width: 700px) {
  .bgm-picker { max-width: 100%; }
  .bgm-picker-toggle { max-width: 100%; }
  .bgm-menu { font-size: 1rem; }
}

/* J-1009-DEV3D-FIX-PASSES: in combat the controls were allowed to shrink
   below their content, and justify-content:flex-end pushed the overflow left
   over the daily buttons (Player 1 on Warrior/Mage daily at 800px and 1280px
   with Developer shown). The controls keep their width; the daily copy yields. */
@media (min-width: 641px) {
  body:has(#screen-dungeon.active) .topbar-actions { flex-shrink: 0; }
  body:has(#screen-dungeon.active) .daily-entry { min-width: 0; flex: 0 1 auto; }
  body:has(#screen-dungeon.active) .daily-actions { flex-shrink: 0; }
  body:has(#screen-dungeon.active) .daily-copy { min-width: 0; overflow: hidden; }
}
/* Stacked daily buttons: never let the box shrink under its button column. */
@media (min-width: 1024px) {
  body:has(#screen-dungeon.active) .daily-entry { min-width: calc(115px + 1.1rem + 2px); }
}
/* 1024-1279: the full-size music toggle ran the row ~30px past the edge;
   use the same compact toggle as the 641-1023 combat header. */
@media (min-width: 1024px) and (max-width: 1279px) {
  body:has(#screen-dungeon.active) .topbar-actions .bgm-picker-toggle { min-height: 30px; font-size: 0.72rem; }
  body:has(#screen-dungeon.active) .topbar { gap: 0.4rem; }
  body:has(#screen-dungeon.active) .topbar-actions #btn-player { max-width: 6.5rem; padding-inline: 0.5rem; }
}
/* Side-by-side daily buttons: the caption was a few px of ellipsis here, so
   it goes (as on the narrow landing header) and the box hugs the buttons. */
@media (min-width: 641px) and (max-width: 1023px) {
  body:has(#screen-dungeon.active) .daily-copy { display: none; }
  body:has(#screen-dungeon.active) .daily-entry { min-width: auto; flex: 0 0 auto; }
}
/* Below 1440px the row is too narrow for every control, so Full Screen shows
   only its icon there (the button keeps aria-label/title "Fullscreen game"). */
@media (min-width: 641px) and (max-width: 1439px) {
  body:has(#screen-dungeon.active) .topbar #btn-fullscreen .fs-label { display: none; }
  body:has(#screen-dungeon.active) .topbar #btn-fullscreen:not([hidden]) { padding-inline: 0.5rem; }
}
/* J-1009-DEV3D-FIX-PASSES pass 2: at 641-1023 the brand was allowed to shrink
   to 66px, so "Typing RPG" and the URL ran under the version chip. The brand
   and chip keep their width; the URL line and the "Music" kicker go, and the
   song toggle is capped with an ellipsis to pay for it. */
@media (min-width: 641px) and (max-width: 1023px) {
  body:has(#screen-dungeon.active) .topbar .brand,
  body:has(#screen-dungeon.active) .topbar .app-version { flex-shrink: 0; }
  body:has(#screen-dungeon.active) .topbar .brand em,
  body:has(#screen-dungeon.active) .topbar-actions .bgm-picker-kicker { display: none; }
  body:has(#screen-dungeon.active) .topbar-actions .bgm-picker-toggle { max-width: 9rem; min-width: 0; }
  body:has(#screen-dungeon.active) .topbar-actions .bgm-picker-value { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
}

/* J-1011-KNIGHT-UNLOCKS: "Level Up! You have gained Attack: ..." banner. Fixed
   over everything in the game (coin celebrations and score flies are 9999);
   only the phone note (100000) sits higher. Never takes clicks or focus. */
.knight-unlock {
  position: fixed; inset: 0; z-index: 99990; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
}
.knight-unlock .ku-rays {
  position: absolute; left: 50%; top: 50%; width: 170vmax; height: 170vmax; margin: -85vmax 0 0 -85vmax;
  background: repeating-conic-gradient(from 0deg, rgba(255,214,110,.20) 0deg 6deg, transparent 6deg 18deg);
  -webkit-mask: radial-gradient(circle, #000 0, rgba(0,0,0,.6) 18%, transparent 46%);
          mask: radial-gradient(circle, #000 0, rgba(0,0,0,.6) 18%, transparent 46%);
}
.knight-unlock .ku-card {
  position: relative; text-align: center; padding: 1.1rem 2.6rem 1.35rem; min-width: min(34rem, 86vw); max-width: 92vw;
  background: radial-gradient(ellipse at 50% 0%, rgba(120,72,10,.96) 0%, rgba(38,22,6,.97) 70%);
  border: 3px solid #f5c542; border-radius: 14px;
  box-shadow: 0 0 0 2px #5a3a08, 0 0 28px 6px rgba(255,190,70,.75), 0 0 90px 20px rgba(255,150,30,.45), 0 18px 40px rgba(0,0,0,.7);
  font-family: "Cinzel Lore", Georgia, serif; font-weight: 600; color: #fff3cf;
}
.knight-unlock .ku-top {
  font-size: clamp(2.4rem, 6.5vw, 4.6rem); line-height: 1; letter-spacing: .05em; color: #ffe27a;
  text-shadow: 0 0 2px #fff, 0 0 14px #ffb020, 0 0 34px #ff7a00, 0 4px 0 #6b3a00;
}
.knight-unlock .ku-line { margin-top: .55rem; display: flex; flex-direction: column; align-items: center; gap: .1rem; }
.knight-unlock .ku-kind { font-size: clamp(1rem, 2.2vw, 1.45rem); letter-spacing: .06em; color: #f7dfa0; text-shadow: 0 2px 4px rgba(0,0,0,.8); }
.knight-unlock .ku-note { font-size: clamp(.85rem, 1.6vw, 1.1rem); letter-spacing: .08em; color: #d9c48f; font-style: italic; }
.knight-unlock.ku-plain .ku-card { padding: 1.2rem 3rem 1.4rem; }
.knight-unlock .ku-name {
  font-size: clamp(1.7rem, 4.4vw, 3rem); line-height: 1.1; color: #fff;
  text-shadow: 0 0 3px #fff, 0 0 16px #8fd3ff, 0 0 34px #3a7bff, 0 3px 0 #1a2a6b;
}
