:root {
  --bg: #0f1020;
  --panel: #1a1c33;
  --panel-2: #23264a;
  --text: #e8e9ff;
  --muted: #8d90b8;
  --accent: #ffcf5c;
  --danger: #ff5c6c;
  --good: #5cff9d;
  /* Colour tokens: a theme can re-ink any of these in its theme.css (:root { --rarity-rare: ... }). Effect colours
     (--fx-*) are also read by the game's particles and flashes (themeColor in js/theme.js), so they must be
     colours, not gradients. */
  --line: #3a3e70;            /* borders */
  --line-soft: #2c2f5a;       /* dividers */
  --well: #0c0d1c;            /* sunken backgrounds: bars, keys, inputs */
  --on-accent: #1a1400;       /* text on the accent colour */
  --chips: #7fc8ff;           /* chip values and letter levels */
  --rarity-common: #ffcf5c;   /* rewards, cards and chest glows by rarity (a chest of 1 / 3 / 5) */
  --rarity-uncommon: #5ca8ff;
  --rarity-rare: #b48cff;
  --hp-mid: linear-gradient(90deg, #ffb13d, #ffe06b); /* the base's HP bar at half and at a quarter */
  --hp-low: linear-gradient(90deg, #ff3b3b, #ff7a6b);
  --el-none: #777;            /* an enemy with no element, and (below) its shots */
  --shot-none: #fff;
  --fx-neutral: #e6cf9c;      /* sparks from a word with no element */
  --fx-flame: #f08a24;        /* fire: enemies burning away, the Pyre Wyrm */
  --fx-fire-hot: #ff6b3d;     /* burning letters, the enraged Wyrm */
  --fx-fire-deep: #b8462a;
  --fx-ember: #ffd35a;
  --fx-light: #ffe08a;        /* the Hollow's lit letters */
  --fx-air: #cfe8f2;          /* the Tempest */
  --fx-air-pale: #d6ecf4;
  --fx-air-edge: #93b3c8;
  --fx-dark: #05040a;         /* the lights out (the Hollow) */
  font-family: 'Segoe UI', system-ui, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); overflow: hidden; }
/* A game, not a page: no selecting text or dragging images out (the typing field still edits as usual). */
body { user-select: none; -webkit-user-select: none; }
input, textarea { user-select: text; -webkit-user-select: text; }
img { -webkit-user-drag: none; }
button {
  font: inherit; color: var(--text); background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 12px; cursor: pointer;
}
button:hover:not(:disabled) { background: #30346a; }
button:disabled { opacity: .5; cursor: default; }
.hidden { display: none !important; }
.muted { color: var(--muted); }

#app { display: grid; grid-template-rows: auto auto 1fr auto; grid-template-columns: minmax(0, 1fr); height: 100vh; max-width: 1200px; margin: 0 auto; position: relative; }

/* ---------- HUD ---------- */
#hud { display: flex; gap: 24px; align-items: center; padding: 12px 20px; background: var(--panel); border-bottom: 1px solid var(--line-soft); }
.hud-label { font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--muted); }
.hud-value { font-size: 22px; font-weight: 700; }
.hud-actions { margin-left: auto; display: flex; gap: 8px; }
/* Narrow windows: the HUD wraps instead of pushing the whole page wider than the window. */
@media (max-width: 900px) {
  #hud { flex-wrap: wrap; gap: 6px 16px; padding: 8px 12px; }
  .hud-value { font-size: 18px; }
  .base-bar { width: 140px; }
}
.bar { position: relative; height: 18px; background: var(--well); border-radius: 9px; overflow: hidden; border: 1px solid #333766; }
.base-bar { width: 220px; }
.bar > div { height: 100%; transition: width .25s ease, background .25s; }
#base-fill { width: 100%; background: linear-gradient(90deg, #3ddc84, #8cff6b); }
#base-fill[data-level=mid] { background: var(--hp-mid); }
#base-fill[data-level=low] { background: var(--hp-low); }
#base-text { position: absolute; inset: 0; text-align: center; font-size: 12px; line-height: 16px; font-weight: 700; }

/* ---------- Battlefield ---------- */
#field {
  position: relative; overflow: hidden;
  background:
    radial-gradient(ellipse at 50% 120%, #2b2f63 0%, transparent 60%),
    linear-gradient(#141633, #0f1020 70%);
}
#field::after { /* ground */
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 38%;
  background: linear-gradient(#1e2140, #15172e); border-top: 2px solid #2e3262;
}
#castle { position: absolute; left: 2%; bottom: 30%; z-index: 2; text-align: center; }
.castle-icon { font-size: 96px; filter: drop-shadow(0 0 20px #5c6cff55); transition: transform .1s; }
#castle.hit .castle-icon { animation: shake .35s; filter: drop-shadow(0 0 30px #ff3b3b); }
.hero-desk { display: none; } /* a theme draws the desk the character sits behind */
#lane { position: absolute; left: 14%; right: 2%; bottom: 30%; top: 8%; z-index: 3; }

.enemy {
  position: absolute; bottom: 0; transform: translateX(-50%);
  min-width: 170px; padding: 10px 14px 12px; border-radius: 14px;
  background: linear-gradient(160deg, #262a52, #191b36); border: 2px solid var(--el, #555);
  box-shadow: 0 0 24px -4px var(--el, #555), inset 0 0 18px -8px var(--el, #555);
  left: 0; text-align: center; will-change: translate;
}
.enemy.hurt { animation: hurt .3s; }
.enemy.dying { animation: die .5s forwards; }
.enemy.arrived { animation: explode .4s forwards; }
/* Killed by an element, it dies that element's way, with its particles (fx-elements.js's deaths, same timing). */
.enemy.dying.die-fire { animation: die-fire .7s linear forwards; }
.enemy.dying.die-water { animation: die-water .7s ease-in forwards; transform-origin: 50% 0; }
.enemy.dying.die-earth { animation: die-earth .7s ease-in forwards; }
.enemy.dying.die-air { animation: die-air .6s ease-in forwards; }
.enemy.dying.die-electric { animation: die-electric .6s steps(1, end) forwards; }
.enemy.dying.die-ice { animation: die-ice .8s linear forwards; }
.enemy.dying.die-nature { animation: die-nature .8s ease-in forwards; transform-origin: 50% 100%; }
.enemy.dying.die-beast { animation: die-beast .6s ease-out forwards; }
.enemy.dying.die-poison { animation: die-poison .9s ease-in-out forwards; transform-origin: 50% 100%; }
.enemy.dying.die-metal { animation: die-metal .6s ease-in forwards; }
.enemy.dying.die-light { animation: die-light .8s ease-in forwards; }
.enemy.dying.die-shadow { animation: die-shadow .8s ease-in forwards; }
.enemy.dying.die-mind { animation: die-mind .7s ease-in-out forwards; }
.enemy .word { font-size: 28px; font-weight: 800; letter-spacing: .02em; text-shadow: 0 0 12px var(--el); }
.enemy .elements { display: flex; gap: 4px; justify-content: center; margin: 6px 0; flex-wrap: wrap; }
.enemy .bar { height: 10px; margin-top: 6px; }
.enemy .hp-fill { background: linear-gradient(90deg, #ff5c6c, #ff9b5c); width: 100%; }
.enemy .meta { font-size: 11px; color: var(--muted); margin-top: 6px; display: flex; justify-content: space-between; gap: 8px; }
.enemy .hint { font-size: 12px; margin-top: 6px; color: #cfd2ff; display: flex; flex-wrap: wrap; justify-content: center; gap: 2px 10px; }
.enemy .hint > span { white-space: nowrap; }
.enemy .hint b { color: var(--good); font-weight: 600; }
.enemy .hint .res { color: var(--danger); }

.enemy.boss { min-width: 230px; padding: 12px 18px 14px; border-width: 3px; box-shadow: 0 0 40px 0 var(--el), inset 0 0 24px -6px var(--el); }
.enemy.boss .word { font-size: 36px; }
.enemy.fragment { transform: translateX(-50%) scale(.85); }

/* A boss's spawns: small cards that fly in from it. */
.enemy.minion { min-width: 0; padding: 5px 10px 7px; border-radius: 10px; }
.enemy.minion .word { font-size: 18px; }
.enemy.minion .elements { margin: 3px 0; }
.enemy.minion .elements .chip { font-size: 10px; padding: 1px 5px; }
.enemy.minion .bar { height: 6px; margin-top: 3px; }
.enemy.minion .meta { margin-top: 3px; }
.boss-tag { font-size: 11px; font-weight: 800; letter-spacing: .15em; color: var(--accent); }
.boss-tag.frag { color: var(--muted); }
.traits { display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; margin: 4px 0; }
.trait { font-size: 11px; padding: 2px 7px; border-radius: 6px; background: #2c1d3f; border: 1px solid #6a4a8a; color: #e6d4ff; cursor: help; }
.shield {
  font-size: 12px; margin: 6px 0 2px; padding: 4px 8px; border-radius: 8px; font-weight: 600;
  background: color-mix(in srgb, var(--el) 20%, #111); border: 1px dashed var(--el); animation: pulse 1.4s infinite;
}
.letter-bonus { color: var(--accent); }
.letter-bonus .reaction { color: #ffd166; }
.status-row { display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; margin: 3px 0; }
.status-row:empty { display: none; }
.status { font-size: 11px; padding: 2px 7px; border-radius: 6px; background: #1d2440; border: 1px solid #4a5a9a; animation: status-pop .25s; }
.status.s-burn { background: #4a1d12; border-color: var(--fx-fire-hot); }
.status.s-soaked { background: #122a4a; border-color: #3da5ff; }
.status.s-chilled { background: #16384a; border-color: #9be7ff; }
.status.s-charged { background: #4a4212; border-color: #ffe23d; }
.status.s-poisoned { background: #33124a; border-color: #b05cff; }
.status.s-rooted { background: #173d17; border-color: #5ccf5c; }
.status.s-stun { background: #3d3d3d; border-color: #ddd; }
.status.s-loot { background: #2e2616; border-color: #c9a24a; color: #ffd98a; }
.status.s-loot.q1, .status.s-loot.q0 { border-color: #a0522d; color: #e6a07a; }
.enemy.stunned { filter: saturate(.6) brightness(1.15); }
.enemy.targeted { outline: 3px solid var(--accent); outline-offset: 3px; }
.enemy.aimed { outline: 1px solid var(--accent); outline-offset: 3px; }
.float .lbl.reaction { font-size: 20px; font-weight: 900; color: #ffd166; text-shadow: 0 0 12px #ff9f1c; letter-spacing: .05em; }
@keyframes status-pop { from { transform: scale(1.4); } to { transform: scale(1); } }
.rx-list { margin: 4px 0 8px; padding-left: 18px; font-size: 13px; line-height: 1.6; }
#chart-table h3 { margin: 12px 0 2px; font-size: 15px; }
.chips-tag { color: var(--chips); font-weight: 700; }
.matchup.tier-super, .matchup.tier-good { color: var(--good); font-weight: 700; }
.matchup.tier-bad, .matchup.tier-awful { color: var(--danger); }
.float .lbl.score { font-size: 15px; color: var(--chips); }
.float .lbl.score b { color: #ff7a8a; }
.float .lbl.small { font-size: 13px; opacity: .9; }

.chip {
  display: inline-flex; align-items: center; gap: 4px; font-size: 12px; padding: 2px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--el) 22%, #111); border: 1px solid color-mix(in srgb, var(--el) 60%, transparent);
  white-space: nowrap;
}
.chip.neutral { --el: #777; }


#banner {
  position: absolute; inset: 0; display: grid; place-items: center; z-index: 6; pointer-events: none;
  font-size: 56px; font-weight: 900; letter-spacing: .08em; color: var(--accent); text-shadow: 0 0 30px #ffcf5c88;
  animation: banner 1.6s forwards;
  align-content: center; text-align: center;
}
/* A chapter's banner: its rule on a second line, and longer on screen to read it. */
#banner.long { animation-duration: 3.4s; padding-bottom: 180px; } /* above the middle, where the wave's supply drop shows */
#banner small { display: block; font-size: 22px; font-weight: 600; letter-spacing: 0; color: var(--text); }

/* ---------- Effects ---------- */
#fx { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
/* Floating text sits on the field's box but outside it, so it isn't clipped at the field's edge: text rising from
   an enemy near the top drifts over the HUD instead of vanishing behind it. */
#field, #floats { grid-area: 3 / 1; }
#floats { position: relative; pointer-events: none; z-index: 6; }
.projectile {
  position: absolute; font-weight: 800; font-size: 20px; white-space: nowrap; color: #fff;
  text-shadow: 0 0 10px var(--el), 0 0 20px var(--el); transform: translate(-50%, -50%);
}
/* A partial shot (the fraction left of the multiplier) is smaller and fainter. */
.projectile.partial { scale: var(--strength, 1); opacity: .75; }
.float {
  position: absolute; transform: translate(-50%, -50%); font-weight: 900; white-space: nowrap; text-align: center;
  animation: floatUp var(--float-time, 2.6s) ease-out forwards;
}
.float .dmg { font-size: 34px; }
.float .dmg.small { font-size: 24px; }
.float .lbl { font-size: 16px; }
.float.super { color: var(--accent); } .float.super .dmg { font-size: 46px; }
.float.good { color: var(--good); }
.float.neutral { color: #fff; }
.float.bad { color: #ffb3b3; }
.float.awful { color: #999; }
.float.base { color: var(--danger); }
.particle { position: absolute; font-size: 22px; transform: translate(-50%, -50%); animation: burst .7s ease-out forwards; }

/* ---------- Controls ---------- */
#controls { padding: 14px 20px 18px; background: var(--panel); border-top: 1px solid var(--line-soft); }
#attack-input {
  width: 100%; font-size: 26px; padding: 12px 18px; border-radius: 12px; outline: none;
  background: var(--well); color: var(--text); border: 2px solid var(--line); letter-spacing: .03em;
}
#attack-input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px #ffcf5c22; }
#attack-input.invalid { border-color: var(--danger); animation: shake .3s; }
/* The preview and history lines have fixed heights: if they grew, the field above would shrink mid-fight. */
#preview { height: 28px; margin-top: 8px; display: flex; gap: 6px; align-items: center; flex-wrap: nowrap; white-space: nowrap; overflow: hidden; font-size: 14px; }
#preview .bad { color: var(--danger); }
#history { display: flex; gap: 6px; flex-wrap: nowrap; margin-top: 6px; height: 22px; overflow: hidden; white-space: nowrap; font-size: 12px; }
#history .used { padding: 2px 8px; border-radius: 6px; background: var(--well); border: 1px solid var(--line-soft); color: var(--muted); }
#history .used.super { color: var(--accent); border-color: #6b5a2a; }
#history .used.good { color: var(--good); }

/* ---------- Towers ---------- */
#towers { position: absolute; left: 1%; bottom: 6%; z-index: 2; display: flex; gap: 8px; }
.tower {
  width: 46px; height: 58px; border-radius: 10px 10px 4px 4px; display: grid; place-items: center; align-content: center;
  background: linear-gradient(#2a2e5a, #1a1c36); border: 2px solid color-mix(in srgb, var(--el) 50%, #333); opacity: .55;
  transition: opacity .2s, box-shadow .2s;
}
.tower.active { opacity: 1; box-shadow: 0 0 16px -2px var(--el); border-color: var(--el); }
.tower .t-icon { font-size: 22px; }
.tower .t-lvl { font-size: 10px; color: var(--accent); letter-spacing: -1px; }
.tower-bolt { position: absolute; transform: translate(-50%, -50%); font-size: 16px; pointer-events: none; }
.float.tower { color: #cfd2ff; --float-time: 1.4s; } /* towers zap often: shorter, so they don't pile up */
.float.tower .lbl { font-size: 13px; }

/* ---------- Aids: a seal per aid, its meter filling from the bottom in its element's colour (--fill 0..1 of the
   most it holds), a mark at each whole power (--marks: how many), its power under the icon. Dim while empty, glowing from ×1. ---------- */
#aids { position: absolute; left: 1%; top: 3%; z-index: 4; display: flex; gap: 6px; }
.aid {
  position: relative; width: 48px; height: 56px; padding: 0 0 14px; display: grid; place-items: center; overflow: hidden;
  border: 2px solid var(--line); border-radius: 8px; background: var(--well); color: var(--text); cursor: pointer;
}
.aid-fill { position: absolute; left: 0; right: 0; bottom: 0; height: calc(var(--fill) * 100%); background: var(--el); opacity: .35; transition: height .25s; }
.aid-mark { position: absolute; inset: 0; opacity: .6;
  background: repeating-linear-gradient(to top, transparent 0 calc(100% / var(--marks) - 1px), var(--el) calc(100% / var(--marks) - 1px) calc(100% / var(--marks))); }
.aid-icon { position: relative; z-index: 1; font-size: 22px; }
.aid-power { position: absolute; z-index: 1; left: 0; right: 0; bottom: 2px; font-size: 11px; font-weight: 700; text-align: center; }
.aid.empty .aid-key, .aid.empty .aid-power { opacity: .5; }
.aid.slot-empty { cursor: default; border-style: dashed; background: transparent; opacity: .6; } /* no aid bought for it yet */
.aid.empty .aid-icon { filter: grayscale(1) brightness(.7); }
.aid-key { position: absolute; z-index: 1; top: 1px; left: 4px; font-size: 11px; color: var(--muted); }
.aid.ready { border-color: var(--el); animation: aid-glow 1.2s ease-in-out infinite alternate; }
.aid.ready .aid-fill { opacity: .55; }
.aid.ready .aid-key { color: var(--text); }
.aid.filled { animation: aid-filled .5s; }
.aid.invalid { animation: shake .3s; }
.aid.max { animation-duration: .6s; }
@keyframes aid-glow { from { box-shadow: 0 0 4px -2px var(--el); } to { box-shadow: 0 0 16px 0 var(--el); } }
@keyframes aid-filled { 0% { transform: scale(1.35); } 100% { transform: none; } }
.float.aid-call { color: var(--accent); }
.float.aid-heal { color: var(--good); } .float.aid-heal .dmg { font-size: 56px; }

/* An aid called (ui/aids.js). Its name slams onto the field on a band of its colour (--el)… */
.aid-title {
  position: absolute; left: 0; right: 0; top: 34%; z-index: 7; display: flex; align-items: center; justify-content: center; gap: 18px;
  padding: 18px 0; pointer-events: none; white-space: nowrap; font-size: 76px; font-weight: 900; letter-spacing: .06em;
  text-transform: uppercase; color: #fff; text-shadow: 0 0 28px var(--el), 0 5px 0 #000;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--el) 45%, #000c) 25%, color-mix(in srgb, var(--el) 45%, #000c) 75%, transparent);
  animation: aid-title 1.7s forwards;
}
.aid-title-icon { font-size: 84px; }
.aid-title-power { font-size: .6em; color: var(--accent); }
@keyframes aid-title {
  0% { opacity: 0; transform: scale(2.6); }
  10% { opacity: 1; transform: scale(.94); }
  16% { transform: scale(1); }
  78% { opacity: 1; transform: scale(1.04); }
  100% { opacity: 0; transform: scale(1.1) translateY(-20px); }
}
/* …a flash of its colour washes over the whole field (the room itself changes too, with a live backdrop: fx.aid)… */
.aid-wash { position: absolute; inset: 0; z-index: 6; pointer-events: none; animation: aid-wash 1s ease-out forwards; }
.aid-wash[data-aid=inferno] { background: linear-gradient(90deg, #ffd35acc, #ff6b3daa 45%, #b8462a55); animation-name: aid-sweep; }
.aid-wash[data-aid=tide] { background: linear-gradient(90deg, #a8e0ffcc, #3da5ffaa 45%, #2e5f9a55); animation-name: aid-sweep; animation-duration: 1.2s; }
.aid-wash[data-aid=frost] { background: radial-gradient(ellipse at center, #d8f6ff55 30%, #f4fdffee 100%); }
.aid-wash[data-aid=dawn] { background: linear-gradient(180deg, #fffbe8ee, #fff3b0aa 50%, #fff3b022); animation-duration: 1.4s; }
@keyframes aid-wash { 0% { opacity: 0; } 12% { opacity: 1; } 100% { opacity: 0; } }
@keyframes aid-sweep { 0% { opacity: 1; clip-path: inset(0 100% 0 0); } 60% { opacity: .9; clip-path: inset(0 0 0 0); } 100% { opacity: 0; clip-path: inset(0 0 0 0); } }
/* …the sweeping ones shake it hard, Dawn lights the base… */
#field.aid-quake { animation: aid-quake .8s steps(10); }
@keyframes aid-quake {
  0%, 100% { translate: 0 0; } 10% { translate: -14px 6px; } 20% { translate: 12px -8px; } 30% { translate: -12px -5px; }
  40% { translate: 10px 7px; } 50% { translate: -8px 4px; } 60% { translate: 7px -4px; } 75% { translate: -4px 2px; } 90% { translate: 2px -1px; }
}
#castle.aid-blessed .castle-icon { animation: aid-blessed 1.6s ease-out; }
@keyframes aid-blessed { 0% { filter: brightness(2.6) drop-shadow(0 0 30px #fff3b0); } 100% { filter: none; } }
/* …and Deep Frost locks each enemy in a block of ice until it can move again, then cracks off. */
.enemy .ice-block {
  position: absolute; inset: -8px; z-index: 3; pointer-events: none; border: 3px solid #e8fbff; border-radius: 6px;
  background: linear-gradient(160deg, #f4fdffd0, #9be7ff80 35%, #3f8aa880 70%, #d8f6ffb0);
  box-shadow: 0 0 22px #9be7ff, inset 0 0 0 2px #9be7ff; animation: ice-in .3s ease-out;
}
.enemy .ice-block.thaw { animation: ice-out .4s ease-in forwards; }
@keyframes ice-in { from { opacity: 0; transform: scale(1.3); } to { opacity: 1; transform: none; } }
@keyframes ice-out { to { opacity: 0; transform: scale(1.15); filter: blur(2px); } }
/* The other aids' washes, in their colours. */
.aid-wash[data-aid=rampart] { background: linear-gradient(0deg, #b08850ee, #8a5a2499 40%, #5a3a1a22); animation-duration: 1.2s; }
.aid-wash[data-aid=gale] { background: linear-gradient(90deg, #ffffffcc, #d8f4eeaa 45%, #6fa8a033); animation-name: aid-sweep; animation-duration: .9s; }
.aid-wash[data-aid=chain] { background: #fff6a0; animation: aid-strobe .9s steps(1) forwards; }
.aid-wash[data-aid=overgrowth] { background: linear-gradient(0deg, #5ccf5cdd, #3f7a3a88 45%, #c8f08022); animation-duration: 1.4s; }
.aid-wash[data-aid=hunt] { background: linear-gradient(90deg, #e8604acc, #9a2a1a99 50%, #4a141033); animation-name: aid-sweep; animation-duration: .9s; }
.aid-wash[data-aid=plague] { background: linear-gradient(0deg, #8ad040cc, #b05cff88 50%, #3a1f4a22); animation-name: aid-sweep; animation-duration: 1.4s; }
.aid-wash[data-aid=iron] { background: linear-gradient(180deg, #ffffffcc, #d0d8e0aa 40%, #5f667033); animation-duration: .8s; }
.aid-wash[data-aid=dread] { background: radial-gradient(ellipse at center, #2a203822 20%, #120c1cf0 85%); animation-duration: 2.4s; }
.aid-wash[data-aid=insight] { background: radial-gradient(circle at center, #ffffffcc, #ff7ac888 30%, #a83a6a00 70%); animation-duration: 1.2s; }
@keyframes aid-strobe { 0%, 22%, 50%, 70% { opacity: .9; } 11%, 36%, 60%, 80%, 100% { opacity: 0; } }
/* Overgrowth roots each enemy in a tangle of vines until it can move again; they wither off. */
.enemy .vine-block {
  position: absolute; inset: -6px; z-index: 3; pointer-events: none; border: 3px dashed #5ccf5c; border-radius: 6px;
  background: repeating-linear-gradient(60deg, #3f7a3a00 0 8px, #3f7a3acc 8px 11px), repeating-linear-gradient(-60deg, #5ccf5c00 0 10px, #5ccf5caa 10px 13px);
  animation: vine-in .4s ease-out;
}
.enemy .vine-block.thaw { animation: vine-out .4s ease-in forwards; }
@keyframes vine-in { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes vine-out { to { opacity: 0; clip-path: inset(100% 0 0 0); } }
/* Dread: a fleeing enemy trembles, in shadow. */
.enemy.feared { filter: brightness(.7) saturate(.5) drop-shadow(0 0 8px #7a5c99); animation: feared .25s steps(2) infinite; }
@keyframes feared { 0% { translate: -2px 0; } 100% { translate: 2px 0; } }
/* The Hunt: an enemy mauled is thrown about. */
.enemy.mauled { animation: mauled .45s; }
@keyframes mauled { 0% { rotate: 0deg; filter: brightness(2) sepia(1) hue-rotate(-40deg); } 30% { rotate: -9deg; translate: 10px -6px; }
  60% { rotate: 6deg; translate: 4px 0; } 100% { rotate: 0deg; translate: 0 0; } }
/* Rampart: a wall of stone before the base while it holds, its HP on it; it shakes when hit and crumbles when gone. */
#castle .rampart {
  position: absolute; left: 100%; bottom: 0; width: 34px; height: 92px; margin-left: 4px; z-index: 3;
  background: repeating-linear-gradient(0deg, #5a3a1a 0 2px, transparent 2px 16px), repeating-linear-gradient(90deg, #8a5a24 0 17px, #b08850 17px 34px);
  border: 2px solid #5a3a1a; border-radius: 4px 4px 0 0; animation: rampart-up .45s ease-out;
}
#castle .rampart.hit { animation: shake .3s; }
#castle .rampart.fall { animation: rampart-down .5s ease-in forwards; }
.rampart-hp { position: absolute; bottom: 100%; left: 50%; translate: -50% -4px; white-space: nowrap; font-size: 13px; font-weight: 700; color: #e0c08a; }
@keyframes rampart-up { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes rampart-down { to { clip-path: inset(100% 0 0 0); opacity: .3; } }
.float.aid-ward { color: #e0c08a; }
/* Insight: the field glows at its edges while it lasts, and its seconds left show under the seals. */
#field.insight::after { content: ''; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  box-shadow: inset 0 0 60px #ff7ac8aa; animation: insight-glow 1s ease-in-out infinite alternate; }
@keyframes insight-glow { from { opacity: .5; } to { opacity: 1; } }
.insight-left { position: absolute; left: 1%; top: calc(3% + 70px); z-index: 4; font-weight: 700; color: #ff7ac8; }

/* ---------- Shop ---------- */
.next-chapter { font-size: 18px; margin: -6px 0 12px; }
.next-chapter b { color: var(--accent); }
.shop-msg { min-height: 20px; color: var(--good); }
.shop-msg .bad { color: var(--danger); }
#xp-bar { position: relative; height: 18px; background: #14152b; border-bottom: 1px solid var(--line-soft); overflow: hidden; }
#xp-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: linear-gradient(90deg, #6a4cc9, #b48cff); transition: width .3s; }
#xp-bar span { position: relative; font-size: 11px; font-weight: 800; line-height: 18px; letter-spacing: .08em; text-shadow: 0 1px 2px #000; }
#xp-level { position: absolute !important; left: 10px; }
#xp-text { display: block; text-align: center; }
#xp-bar.burst { animation: xp-burst .4s ease-out 3; }
@keyframes xp-burst { 0% { box-shadow: 0 0 0 #ffcf5c00; } 50% { box-shadow: 0 0 24px #ffcf5c, 0 0 8px #b48cff inset; } 100% { box-shadow: 0 0 0 #ffcf5c00; } }
#xp-bar.ready #xp-fill { background: linear-gradient(90deg, #b48cff, #ffcf5c, #b48cff); animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .5; } }
.reward-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 12px; }
.reward { position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 16px 10px 12px; border-radius: 12px; border: 2px solid var(--line); }
.reward .r-key { position: absolute; left: 8px; top: 6px; font-size: 12px; font-weight: 800; color: var(--muted); }
.reward .r-icon { font-size: 34px; }
.reward small { color: var(--muted); font-size: 12px; }
.reward .r-tier { font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.reward.uncommon { border-color: var(--rarity-uncommon); } .reward.uncommon .r-tier { color: var(--rarity-uncommon); }
.reward.rare { border-color: var(--rarity-rare); box-shadow: 0 0 18px color-mix(in srgb, var(--rarity-rare) 33.3%, transparent); } .reward.rare .r-tier { color: var(--rarity-rare); }
@media (max-width: 600px) { .reward-grid { grid-template-columns: 1fr; } }
/* Boss chest: dropped on the field where the boss died. It rumbles with light leaking from the seam
   (--glow, --heat), then the lid slowly creaks back and a beam, rays and the loot come out. */
.field-chest {
  --glow: #ffcf5c; --heat: 0; --band: #d9a441;
  position: absolute; width: 132px; height: 104px; margin-left: -66px; scale: .7; transform-origin: 50% 100%;
  animation: chest-drop .7s cubic-bezier(.5, 0, .7, 1) both;
}
.field-chest.gone { transition: opacity .4s; opacity: 0; }
.chest {
  position: absolute; inset: 0; z-index: 2;
  animation: chest-idle 1.6s ease-in-out infinite;
  filter: drop-shadow(0 0 calc(8px + 22px * var(--heat)) color-mix(in srgb, var(--glow) calc(45% + 45% * var(--heat)), transparent));
  transition: filter .3s;
}
.field-chest.charging .chest { animation: chest-rumble .14s linear infinite; }
.field-chest.charging.hard .chest { animation-duration: .08s; }
.field-chest.open .chest { animation: chest-pop .5s .5s cubic-bezier(.3, 1.6, .5, 1); }
.chest-body, .chest-lid {
  position: absolute; border: 3px solid #2e1a0a;
  background:
    linear-gradient(90deg, transparent 18px, var(--band) 18px 28px, transparent 28px calc(100% - 28px), var(--band) calc(100% - 28px) calc(100% - 18px), transparent 0),
    linear-gradient(#9a5a27, #5c3214);
}
.chest-body { left: 0; right: 0; bottom: 0; height: 62px; border-radius: 4px 4px 12px 12px; box-shadow: inset 0 -10px 0 #0003; }
.chest-lid {
  left: -5px; right: -5px; top: 0; height: 46px; z-index: 2; transform-origin: 50% 100%;
  border-radius: 50% 50% 4px 4px / 60% 60% 4px 4px; box-shadow: inset 0 6px 0 #ffffff22;
  background:
    linear-gradient(90deg, transparent 23px, var(--band) 23px 33px, transparent 33px calc(100% - 33px), var(--band) calc(100% - 33px) calc(100% - 23px), transparent 0),
    linear-gradient(#b06a2f, #6e3c18);
}
/* Light leaking out of the seam between lid and body. */
.chest::after {
  content: ''; position: absolute; left: 4px; right: 4px; top: 40px; height: 5px; z-index: 3; border-radius: 3px;
  background: var(--glow); opacity: var(--heat); box-shadow: 0 0 calc(18px * var(--heat)) 3px var(--glow); transition: opacity .3s;
}
.chest-lock {
  position: absolute; left: 50%; top: -8px; width: 24px; height: 28px; transform: translateX(-50%); z-index: 4;
  background: linear-gradient(#ffe08a, #d9a441); border: 3px solid #2e1a0a; border-radius: 6px;
}
.chest-lock::after { content: ''; position: absolute; left: 50%; top: 6px; width: 6px; height: 10px; transform: translateX(-50%); background: #2e1a0a; border-radius: 3px 3px 1px 1px; }
/* The lid cracks, settles, then swings all the way back. */
.field-chest.open .chest-lid { z-index: 5; transform-origin: 6% 100%; animation: lid-open 1.3s cubic-bezier(.4, 0, .3, 1) forwards; }
.field-chest.open .chest-lock { animation: lock-fly .6s .45s ease-in forwards; }
.field-chest.open .chest::after { opacity: 1; height: 10px; top: 36px; box-shadow: 0 0 40px 12px var(--glow); transition-delay: .4s; }
.chest-rays {
  position: absolute; left: 50%; top: 30%; width: 380px; height: 380px; margin: -190px 0 0 -190px; opacity: 0; border-radius: 50%;
  background: repeating-conic-gradient(var(--glow) 0 8deg, transparent 8deg 24deg);
  -webkit-mask: radial-gradient(circle, #000 15%, transparent 68%); mask: radial-gradient(circle, #000 15%, transparent 68%);
}
.field-chest.open .chest-rays { animation: rays-in .8s .5s ease-out forwards, rays-spin 9s linear infinite; }
.chest-beam {
  position: absolute; left: 50%; bottom: 58px; width: 100px; height: 0; margin-left: -50px; z-index: 1; border-radius: 50% 50% 0 0;
  background: linear-gradient(to top, var(--glow), transparent); filter: blur(8px); opacity: .85;
}
.field-chest.open .chest-beam { animation: beam-up .9s .5s cubic-bezier(.2, .8, .3, 1) forwards; }
.field-chest.open::after {
  content: ''; position: absolute; inset: -80px -60px; z-index: 4; pointer-events: none; opacity: 0;
  background: radial-gradient(circle, #fff 0, color-mix(in srgb, var(--glow) 60%, transparent) 25%, transparent 60%);
  animation: chest-flash .7s .5s ease-out forwards;
}
.chest-count { font-size: 44px; font-weight: 900; color: var(--accent); line-height: 1; white-space: nowrap; }
.chest-count small { font-size: 16px; color: var(--muted); }
.field-chest .chest-count { position: absolute; left: 50%; bottom: 200px; translate: -50%; z-index: 5; opacity: 0; text-shadow: 0 2px 6px #000; }
.chest-count.shown { animation: count-pop .5s cubic-bezier(.2, 1.8, .4, 1) both; }
.chest-count.n3 { color: var(--rarity-uncommon); text-shadow: 0 0 18px color-mix(in srgb, var(--rarity-uncommon) 53.3%, transparent); }
.chest-count.n5 { color: var(--rarity-rare); text-shadow: 0 0 28px color-mix(in srgb, var(--rarity-rare) 80%, transparent); }
#field.jackpot { animation: shake .15s 3; }
.chest-grid { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.chest-reward { opacity: 0; animation: chest-in .45s cubic-bezier(.2, 1.4, .4, 1) forwards; }
@keyframes chest-in { from { opacity: 0; transform: translateY(-40px) scale(.4) rotate(-8deg); } to { opacity: 1; transform: none; } }
@keyframes chest-drop {
  0% { opacity: 0; translate: 0 var(--from); } 15% { opacity: 1; } 65% { translate: 0 0; scale: .8 .6; }
  80% { translate: 0 -16px; scale: .7; } 100% { translate: 0 0; }
}
@keyframes chest-idle { 50% { transform: translateY(-3px); } }
@keyframes chest-rumble { 25% { transform: rotate(-2.5deg) translateX(-2px); } 75% { transform: rotate(2.5deg) translateX(2px); } }
@keyframes chest-pop { 0% { transform: scale(1.12, .88); } 100% { transform: none; } }
@keyframes lid-open {
  0% { transform: none; } 25% { transform: translateY(-3px) rotate(-7deg); } 38% { transform: translateY(-1px) rotate(-3deg); }
  100% { transform: translate(-14px, -8px) rotate(-38deg); }
}
@keyframes lock-fly { to { opacity: 0; transform: translate(-50%, 60px) rotate(140deg); } }
@keyframes rays-in { to { opacity: .55; } }
@keyframes rays-spin { to { rotate: 360deg; } }
@keyframes beam-up { 0% { height: 0; } 100% { height: 420px; } }
@keyframes chest-flash { 0% { opacity: 1; transform: scale(.4); } 100% { opacity: 0; transform: scale(1.4); } }
@keyframes count-pop { from { opacity: 0; transform: scale(2.2); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .chest, .field-chest.charging .chest, .field-chest.open .chest-rays, #field.jackpot { animation: none; }
  .field-chest.open .chest-rays { opacity: .4; }
}
.shop-hint { font-size: 12px; margin: -8px 0 8px; }
/* The sell tray: what the player owns that the merchant buys back. A click asks (.armed), a second sells. */
.sell-tray { margin-bottom: 10px; padding: 8px 10px; border: 1px dashed var(--line); border-radius: 10px; }
.sell-title { margin: 0 0 6px; font-size: 13px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.sell-goods { display: flex; flex-wrap: wrap; gap: 6px; }
.sell-good { display: flex; align-items: center; gap: 8px; padding: 4px 10px 4px 6px; font-size: 13px; text-align: left; }
.sell-good .sg-icon { font-size: 20px; }
.sell-good .sg-name { display: flex; flex-direction: column; line-height: 1.1; }
.sell-good .sg-name small { font-size: 11px; color: var(--muted); }
.sell-good .sg-price { margin-left: 4px; font-weight: 700; color: var(--accent); white-space: nowrap; }
.sell-good.armed { border-color: var(--danger); animation: shake .25s; }
.sell-good.armed .sg-price { color: var(--danger); }
.sell-none { margin: 0; font-size: 13px; color: var(--muted); }
.shop-actions { display: flex; gap: 10px; justify-content: center; align-items: center; flex-wrap: wrap; }
#glyphs { display: flex; gap: 3px; }
.glyph { width: 26px; height: 26px; display: grid; place-items: center; font-size: 16px; border-radius: 6px; background: var(--well); border: 1px solid var(--line); }
.glyph.empty { border-style: dashed; opacity: .4; }
.glyph.fired { animation: gain .5s; border-color: var(--accent); }

/* ---------- Letter ammo ---------- */
#ammo { display: flex; flex-direction: column; align-items: center; gap: 4px; margin-bottom: 10px; }
.ammo-row { display: flex; gap: 4px; }
.key {
  position: relative; width: 40px; height: 38px; border-radius: 7px; background: var(--well); border: 1px solid var(--line);
  display: grid; place-items: center; transition: background .15s, border-color .15s, opacity .15s;
}
.key .ch { font-size: 17px; font-weight: 700; text-transform: uppercase; }
.key .v { position: absolute; left: 4px; top: 1px; font-size: 9px; color: var(--muted); }
.key .n { position: absolute; right: 4px; bottom: 1px; font-size: 11px; color: var(--accent); font-weight: 700; }
.key.empty { opacity: .35; }
.key.leveled .v { color: var(--chips); font-weight: 700; }
.key .lv { position: absolute; left: 4px; bottom: 0; font-size: 9px; line-height: 1; color: var(--chips); letter-spacing: -1px; }
.key.empty .n { color: var(--danger); }
/* A Lipogram's letter: no word may use it this chapter. */
.key.banned { opacity: .35; }
.key.banned .ch { text-decoration: line-through; text-decoration-thickness: 3px; text-decoration-color: var(--danger); }
.key.need { background: #1f3a5a; border-color: #5ca8ff; }
.key.short { background: #5a1f28; border-color: var(--danger); opacity: 1; animation: shake .25s; }
.key.gain { animation: gain .5s; }
.key.wild { background: #4a3f16; border-color: var(--accent); }
.key.wildcard { margin-left: 12px; border-style: dashed; border-color: var(--accent); }
.key.wildcard .ch { color: var(--accent); }

/* Kindling (the Pyre Wyrm): a key glows, then burns down; spend the letter before it's lost. */
.key .burn { position: absolute; top: -10px; left: 50%; transform: translateX(-50%); font-size: 11px; font-weight: 800;
  white-space: nowrap; color: #fff3b0; text-shadow: 0 0 6px var(--fx-fire-hot), 0 0 2px #000; pointer-events: none; }
.key.smoulder { border-color: #ff9b5c; box-shadow: 0 0 12px -2px #ff9b5c; }
.key.burning { background: #5a2410; border-color: var(--fx-fire-hot); box-shadow: 0 0 16px 0 var(--fx-fire-hot); animation: key-burn .6s ease-in-out infinite alternate; }
@keyframes key-burn { from { box-shadow: 0 0 10px -2px var(--fx-fire-hot); } to { box-shadow: 0 0 22px 2px #ffb13d; } }
.key.charred { animation: key-charred .7s; }
@keyframes key-charred { 0% { background: var(--fx-fire-hot); } 100% { background: inherit; } }
.letter-drop.kindle { font-size: 22px; background: none; border: 0; box-shadow: none; }
.letter-drop {
  position: absolute; transform: translate(-50%, -50%); font-weight: 900; font-size: 22px; color: var(--accent);
  text-shadow: 0 0 10px #ffcf5c; pointer-events: none;
}
.float.loot { color: var(--accent); }

/* ---------- Chart panel ---------- */
#chart-panel {
  position: absolute; top: 64px; right: 12px; z-index: 20; width: min(640px, 96vw); max-height: calc(100vh - 90px); overflow: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; box-shadow: 0 20px 60px #000a;
}
.panel-head { display: flex; justify-content: space-between; align-items: center; }
.panel-head h2 { margin: 0; font-size: 18px; }
#chart-table table { border-collapse: collapse; font-size: 13px; margin-top: 8px; }
#chart-table th, #chart-table td { width: 36px; height: 30px; text-align: center; border: 1px solid var(--line-soft); }
#chart-table th { font-size: 17px; font-weight: 400; }
#chart-table td.s { background: #1f5a36; color: #9dffc2; font-weight: 700; }
#chart-table td.w { background: #5a1f28; color: #ffb3bd; }

/* ---------- Overlay ---------- */
/* Screens fade in and their card pops, and level-up cards are dealt one by one. */
#overlay:not(.hidden) { animation: overlay-in .3s ease-out; }
#overlay:not(.hidden) .card { animation: card-in .38s cubic-bezier(.2, 1.3, .4, 1); }
@keyframes overlay-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes card-in { from { opacity: 0; transform: translateY(18px) scale(.92); } to { opacity: 1; transform: none; } }
.reward-grid .reward-wrap { animation: card-deal .35s cubic-bezier(.2, 1.3, .4, 1) both; }
.reward-grid .reward-wrap:nth-child(2) { animation-delay: .09s; }
.reward-grid .reward-wrap:nth-child(3) { animation-delay: .18s; }
.reward-grid .reward-wrap:nth-child(4) { animation-delay: .27s; }
@keyframes card-deal { from { opacity: 0; transform: translateY(24px) rotate(-3deg); } to { opacity: 1; transform: none; } }
#overlay { position: fixed; inset: 0; z-index: 30; display: grid; place-items: center; background: #080914cc; backdrop-filter: blur(4px); }
#overlay .card { max-height: 94vh; overflow: auto; width: min(580px, 92vw); background: var(--panel); border: 1px solid var(--line); border-radius: 18px; padding: 28px 32px; text-align: center; box-shadow: 0 30px 80px #000c; }
#overlay h1 { margin: 0 0 6px; font-size: 52px; letter-spacing: .12em; }
#overlay h1 span { color: var(--accent); }
#overlay .card:has(.pack-grid) h1 { font-size: 34px; }
#overlay .tagline { color: var(--muted); margin-top: 0; }
#overlay .howto { text-align: left; line-height: 1.7; padding-left: 20px; }
#overlay button#btn-menu, #overlay button#btn-quit { font-size: 16px; padding: 10px 22px; margin: 14px 0 8px; font-weight: 700; }
.badge { font-size: 10px; font-weight: 800; padding: 1px 6px; margin-left: 4px; border-radius: 6px; background: var(--accent); color: var(--on-accent); vertical-align: middle; text-transform: uppercase; }
#overlay p.small { font-size: 12px; }
.menu-actions { display: flex; gap: 10px; justify-content: center; align-items: center; flex-wrap: wrap; }
#overlay button#btn-upgrades { font-size: 16px; padding: 10px 22px; margin: 14px 0 8px; font-weight: 700; }
.ink-earned { font-size: 17px; margin: 4px 0 10px; }
.ink-earned b { color: var(--accent); }
#overlay button#btn-start { font-size: 20px; padding: 10px 40px; margin: 14px 0 8px; background: var(--accent); color: var(--on-accent); border: none; font-weight: 800; }
#overlay .stats { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 14px 0; text-align: left; }
#overlay .stats div { background: var(--panel-2); border-radius: 10px; padding: 8px 12px; }
#overlay .stats b { display: block; font-size: 20px; }

/* ---------- Animations ---------- */
@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
@keyframes hurt { 0% { filter: brightness(2.5); } 100% { filter: none; } }
@keyframes die { to { opacity: 0; transform: translateX(-50%) scale(1.4) rotate(8deg); filter: blur(4px); } }
@keyframes explode { to { opacity: 0; transform: translateX(-50%) scale(.3); } }
@keyframes die-fire {
  0% { clip-path: inset(0 0 0 0); filter: none; }
  25% { filter: sepia(1) saturate(2.5) brightness(1.1) hue-rotate(-20deg); }
  100% { clip-path: inset(0 0 100% 0); filter: sepia(1) saturate(2) brightness(.4); }
}
@keyframes die-water {
  0% { clip-path: inset(0 0 0 0); }
  30% { filter: hue-rotate(180deg) saturate(1.5) brightness(1.1); transform: translateX(-50%) scale(1.04, .96); }
  100% { clip-path: inset(70% 0 0 0); opacity: 0; filter: hue-rotate(200deg) saturate(1.2) blur(3px); transform: translateX(-50%) translateY(30px) scale(.9, 1.5); }
}
@keyframes die-earth {
  0% { clip-path: polygon(0 0, 20% 0, 40% 0, 60% 0, 80% 0, 100% 0, 100% 100%, 0 100%); }
  8% { transform: translateX(calc(-50% - 4px)); }
  16% { transform: translateX(calc(-50% + 4px)); }
  25% { transform: translateX(-50%); filter: sepia(.8) brightness(.8); clip-path: polygon(0 0, 20% 0, 40% 0, 60% 0, 80% 0, 100% 0, 100% 100%, 0 100%); }
  100% { opacity: 0; transform: translateX(-50%) translateY(50px) rotate(-6deg); filter: sepia(1) brightness(.5);
    clip-path: polygon(0 70%, 20% 95%, 40% 80%, 60% 100%, 80% 85%, 100% 100%, 100% 100%, 0 100%); }
}
@keyframes die-air {
  20% { transform: translateX(calc(-50% - 10px)) rotate(-4deg); }
  100% { opacity: 0; filter: blur(2px); transform: translateX(calc(-50% + 260px)) translateY(-60px) rotate(25deg) skewX(-20deg) scale(.6); }
}
@keyframes die-electric {
  0%, 20%, 40%, 60% { filter: brightness(3) saturate(0); }
  10%, 30%, 50% { filter: invert(1) brightness(1.5); }
  70% { filter: brightness(4); transform: translateX(-50%) scale(1.05); }
  85% { opacity: .8; filter: brightness(5) blur(1px); transform: translateX(-50%) scale(1.1, .3); }
  100% { opacity: 0; transform: translateX(-50%) scale(1.1, .05); }
}
@keyframes die-ice {
  0% { filter: none; }
  40%, 55% { filter: saturate(.3) brightness(1.5) hue-rotate(160deg) contrast(1.2); transform: translateX(-50%); }
  57% { transform: translateX(calc(-50% + 2px)); }
  59% { transform: translateX(calc(-50% - 2px)); opacity: 1; filter: saturate(0) brightness(2.2); }
  61%, 100% { opacity: 0; transform: translateX(-50%) scale(1.08); }
}
@keyframes die-nature {
  30% { filter: hue-rotate(60deg) saturate(1.6) brightness(.9); transform: translateX(-50%) rotate(-3deg); }
  50% { transform: translateX(-50%) rotate(3deg); }
  100% { opacity: .4; filter: hue-rotate(80deg) saturate(1.8) brightness(.5); transform: translateX(-50%) scale(.85, 0); }
}
@keyframes die-beast {
  0% { filter: none; }
  8% { transform: translateX(calc(-50% + 8px)) rotate(3deg); filter: brightness(1.8) sepia(1) hue-rotate(-40deg) saturate(3); }
  18% { transform: translateX(calc(-50% - 5px)) rotate(-2deg); }
  30% { transform: translateX(-50%); filter: sepia(1) hue-rotate(-40deg) saturate(2); }
  100% { opacity: 0; transform: translateX(calc(-50% + 60px)) translateY(20px) rotate(12deg); filter: sepia(1) hue-rotate(-40deg) saturate(2) brightness(.6); }
}
@keyframes die-poison {
  20% { filter: hue-rotate(230deg) saturate(1.5); }
  40% { transform: translateX(-50%) skewX(4deg) scale(1.02, .95); }
  60% { transform: translateX(-50%) skewX(-4deg) scale(1.08, .7); }
  100% { opacity: .3; filter: hue-rotate(240deg) saturate(1.5) brightness(.5) blur(1px); transform: translateX(-50%) scale(1.3, .05); }
}
@keyframes die-metal {
  0% { filter: none; }
  15% { filter: grayscale(1) brightness(2.5); transform: translateX(calc(-50% + 3px)); }
  25% { transform: translateX(calc(-50% - 3px)); }
  35% { filter: grayscale(1) brightness(1.2); transform: translateX(-50%); }
  100% { opacity: 0; filter: grayscale(1) brightness(.6); transform: translateX(-50%) translateY(40px) rotate(14deg); }
}
@keyframes die-light {
  40% { filter: brightness(2) saturate(.5); transform: translateX(-50%) translateY(-6px) scale(1.04); }
  100% { opacity: 0; filter: brightness(4) saturate(0) blur(3px); transform: translateX(-50%) translateY(-50px) scale(1.15, 1.3); }
}
@keyframes die-shadow {
  35% { filter: brightness(.15) saturate(0); transform: translateX(-50%) scale(1.05); }
  100% { opacity: .2; filter: brightness(0); transform: translateX(-50%) scale(0) rotate(-40deg); }
}
@keyframes die-mind {
  0% { filter: none; }
  15% { transform: translateX(calc(-50% + 6px)) skewX(12deg); filter: hue-rotate(90deg); }
  30% { transform: translateX(calc(-50% - 6px)) skewX(-12deg); filter: hue-rotate(180deg); }
  45% { transform: translateX(-50%) skewX(6deg) scale(1.1, .9); filter: hue-rotate(270deg) brightness(1.5); }
  100% { opacity: 0; transform: translateX(-50%) scale(1.6, 0); filter: hue-rotate(360deg) brightness(3) blur(2px); }
}
/* Floating text pops in, holds still to be read, then rises and fades away. */
@keyframes floatUp {
  0% { opacity: 0; transform: translate(-50%, -30%) scale(.6); }
  8% { opacity: 1; transform: translate(-50%, -60%) scale(1.1); }
  14%, 60% { opacity: 1; transform: translate(-50%, -70%) scale(1); }
  80% { opacity: 1; transform: translate(-50%, -130%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -180%) scale(1); }
}
@keyframes burst { to { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.4); } }
@keyframes pulse { 50% { box-shadow: 0 0 14px -2px var(--el); } }
@keyframes gain { 0% { background: #ffcf5c; transform: scale(1.25); } 100% { transform: scale(1); } }
@keyframes banner { 0% { opacity: 0; transform: scale(.6); } 20% { opacity: 1; transform: scale(1); } 80% { opacity: 1; } 100% { opacity: 0; transform: scale(1.1); } }

/* ---------- Title screen (its own page) ---------- */
#menu-screen {
  position: fixed; inset: 0; z-index: 100; overflow: hidden;
  background: radial-gradient(ellipse at 50% 110%, #3b2a7a 0%, #1a1440 35%, #0a0a18 75%);
}
.menu-glow {
  position: absolute; left: 50%; bottom: -30vh; width: 120vw; height: 60vh; transform: translateX(-50%); pointer-events: none;
  background: radial-gradient(ellipse at center, #ffcf5c33, transparent 65%); animation: glow 6s ease-in-out infinite alternate;
}
@keyframes glow { from { opacity: .6; } to { opacity: 1; } }
.menu-bg { position: absolute; inset: 0; pointer-events: none; }
.bg-word {
  position: absolute; bottom: -60px; font-weight: 900; letter-spacing: .04em; color: var(--el); opacity: 0;
  text-shadow: 0 0 18px var(--el); animation: drift linear infinite; white-space: nowrap;
}
@keyframes drift {
  0% { transform: translateY(0) rotate(-4deg); opacity: 0; }
  10% { opacity: .22; } 85% { opacity: .22; }
  100% { transform: translateY(-115vh) rotate(4deg); opacity: 0; }
}
.menu-version { position: absolute; left: 24px; bottom: 10px; z-index: 2; font-size: 12px; color: var(--muted); opacity: .7; pointer-events: none; }
.menu-top { position: absolute; top: 0; left: 0; right: 0; display: flex; justify-content: space-between; align-items: center; padding: 16px 24px; z-index: 2; }
.menu-ink {
  font-size: 22px; font-weight: 800; padding: 6px 18px; border-radius: 999px;
  background: color-mix(in srgb, var(--well) 80%, transparent); border: 2px solid var(--accent); box-shadow: 0 0 18px #ffcf5c44;
}
.menu-ink b { color: var(--accent); }

.menu-view { position: relative; z-index: 1; height: 100%; display: flex; flex-direction: column; align-items: center; padding: 56px 24px 24px; }
.menu-view.enter { animation: view-in .35s ease-out; }
@keyframes view-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
#view-title { justify-content: center; gap: 28px; }
#view-upgrades, #view-codex, #view-howto { justify-content: center; }

.logo { text-align: center; }
.logo-castle { font-size: 88px; line-height: 1; filter: drop-shadow(0 0 30px #7c6cffaa); animation: bob 3s ease-in-out infinite; }
.logo-castle.hero { animation: none; } /* the first character, drawn by its own idle (game.js) */
.logo-castle.hero canvas { display: block; margin: 0 auto; image-rendering: pixelated; }
@keyframes bob { 50% { transform: translateY(-8px); } }
.logo-text {
  margin: 6px 0 0; font-size: clamp(44px, 8vw, 88px); font-weight: 900; letter-spacing: .1em; line-height: 1; text-transform: uppercase;
  color: #fff; text-shadow: 0 4px 0 #5a3fd0, 0 8px 0 #2a1d70, 0 0 50px #7c6cff99;
}
.logo-text span { display: block; color: var(--accent); text-shadow: 0 4px 0 #c07a10, 0 8px 0 #6a3a00, 0 0 50px #ffcf5c88; }
.logo-sub { color: #b9b6e8; margin: 18px 0 0; font-size: 15px; }

.menu-nav { display: flex; flex-direction: column; gap: 12px; width: min(340px, 90vw); }
.menu-btn {
  position: relative; font-size: 22px; font-weight: 800; letter-spacing: .06em; padding: 14px 20px; border-radius: 12px;
  background: linear-gradient(#2f2a6e, #1e1a4a); border: 3px solid #6a5fd0; box-shadow: 0 5px 0 #120f33, 0 0 0 1px #000 inset;
  transition: transform .08s, border-color .15s, box-shadow .15s;
}
.menu-btn:hover:not(:disabled), .menu-btn:focus-visible { border-color: var(--accent); box-shadow: 0 5px 0 #120f33, 0 0 24px #ffcf5c66; outline: none; transform: translateY(-2px); background: linear-gradient(#3a3488, #252058); }
.menu-btn:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 2px 0 #120f33; }
.menu-btn.primary { text-transform: uppercase; font-size: 30px; padding: 18px 20px; color: var(--on-accent); background: linear-gradient(#ffe08a, #ffb82e); border-color: #fff3c4; box-shadow: 0 6px 0 #9a6200, 0 0 30px #ffcf5c55; }
.menu-btn.primary:hover:not(:disabled), .menu-btn.primary:focus-visible { background: linear-gradient(#fff0b8, #ffc84a); border-color: #fff; box-shadow: 0 6px 0 #9a6200, 0 0 40px #ffcf5caa; }
.menu-btn.small { font-size: 16px; padding: 10px 22px; }
.menu-btn.nudge { animation: pulse 1.4s infinite; border-color: var(--accent); }

.menu-foot { text-align: center; }
.menu-stats { display: flex; gap: 10px; justify-content: center; margin-bottom: 10px; flex-wrap: wrap; }
.menu-stats div { min-width: 120px; background: color-mix(in srgb, var(--well) 66.7%, transparent); border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; font-size: 12px; color: var(--muted); }
.menu-stats b { display: block; font-size: 22px; color: var(--text); margin-top: 2px; }

.page-title { margin: 0; font-size: clamp(36px, 6vw, 56px); letter-spacing: .1em; color: var(--accent); text-shadow: 0 4px 0 #6a3a00, 0 0 40px #ffcf5c66; }
.menu-view > .muted { margin: 8px 0 18px; }
.menu-panel { background: #12132acc; border: 2px solid var(--line); border-radius: 16px; box-shadow: 0 20px 60px #0008; }
.page-actions { display: flex; gap: 12px; margin-top: 18px; }

/* ---------- Settings: a page of the title screen, and an overlay screen from the pause menu ---------- */
#view-settings { justify-content: center; }
#settings-panel { width: min(620px, 100%); padding: 18px 26px; }
.settings { display: grid; gap: 10px; text-align: left; }
#overlay-card .settings-host { margin: 14px 0 18px; }
.set-head { margin: 8px 0 0; font-size: 13px; text-transform: uppercase; letter-spacing: .12em; color: var(--muted); }
.set-row { display: grid; grid-template-columns: 1fr 220px 56px; align-items: center; gap: 14px; cursor: pointer; }
.set-row input[type=range] { width: 100%; margin: 0; accent-color: var(--accent); cursor: pointer; }
.set-row input[type=checkbox] { width: 20px; height: 20px; margin: 0; accent-color: var(--accent); justify-self: start; cursor: pointer; }
.set-row select { font: inherit; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 4px 8px; }
.set-row output { text-align: right; font-variant-numeric: tabular-nums; }
.set-note { margin: 0; font-size: 12px; }

.up-layout { display: grid; grid-template-columns: 1fr 300px; gap: 18px; width: min(1180px, 100%); min-height: 0; flex: 0 1 auto; }
#up-grid, #cx-grid, #wj-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; align-content: start; max-height: 66vh; overflow: auto; padding: 4px; }
.up-tile {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 10px 6px 8px; border-radius: 14px;
  background: linear-gradient(#232058, #17153b); border: 3px solid var(--line); transition: transform .08s, border-color .15s;
}
.up-tile:hover, .up-tile:focus-visible { outline: none; transform: translateY(-2px); border-color: #8a7ff0; }
.up-tile.selected { border-color: var(--accent); box-shadow: 0 0 22px #ffcf5c55; }
.up-cost { font-size: 12px; font-weight: 700; color: var(--muted); }
.up-tile.affordable .up-cost { color: var(--good); }
.up-tile.maxed .up-cost { color: var(--accent); letter-spacing: .1em; }
.up-tile.maxed { background: linear-gradient(#3a3010, #1f1a08); }
.up-icon { font-size: 40px; line-height: 1.1; }
.up-name { font-size: 13px; font-weight: 700; }
.pips { font-size: 11px; letter-spacing: 2px; color: var(--accent); }
.pips.big { font-size: 18px; letter-spacing: 4px; }
#up-detail, #cx-detail, #wj-detail { padding: 22px 20px; text-align: center; display: flex; flex-direction: column; align-items: center; }
#up-detail h2, #cx-detail h2, #wj-detail h2 { margin: 6px 0 4px; font-size: 24px; }
#up-detail p, #cx-detail p, #wj-detail p { margin: 8px 0; line-height: 1.5; }
.up-detail-icon { font-size: 64px; line-height: 1; }
#btn-buy {
  margin-top: 8px; width: 100%; font-size: 20px; font-weight: 800; padding: 12px; border-radius: 12px;
  color: var(--on-accent); background: linear-gradient(#ffe08a, #ffb82e); border: 3px solid #fff3c4; box-shadow: 0 5px 0 #9a6200;
}
#btn-buy:disabled { color: var(--muted); background: #23264a; border-color: var(--line); box-shadow: none; }
.up-msg { color: var(--good); min-height: 1.5em; }
@media (max-width: 1100px) { #up-grid, #cx-grid, #wj-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 820px) { .up-layout { grid-template-columns: 1fr; } #up-grid, #cx-grid, #wj-grid { grid-template-columns: repeat(3, 1fr); } }

.howto-scroll { width: min(760px, 100%); overflow: auto; padding: 10px 24px; flex: 0 1 auto; min-height: 0; }
.howto-scroll .howto { line-height: 1.7; padding-left: 18px; }
/* How to play: numbered sections, in the order a player meets things */
.howto-step + .howto-step { margin-top: 14px; }
.howto-step h2 { display: flex; align-items: center; gap: 8px; margin: 0 0 2px; font-size: 18px; }
.howto-n { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; font-size: 14px;
  color: var(--on-accent, #000); background: var(--accent); }
.howto-step .howto { margin: 0; }

/* ---------- Hidden upgrades & secrets ---------- */
.up-icon { font-size: 30px; }
.up-tile.locked { background: repeating-linear-gradient(135deg, #111226, #111226 8px, #16172f 8px, #16172f 16px); border-style: dashed; }
.up-tile.locked .up-icon { filter: grayscale(1) brightness(.6); }
.up-tile.locked .up-name, .up-tile.locked .up-cost { color: #5a5d88; letter-spacing: .15em; }
.up-tile.cursed { background: linear-gradient(#4a1030, #1f0816); border-color: #b0306a; }
.up-tile .badge.new { position: absolute; top: -8px; right: -6px; margin: 0; }
.badge.new { background: var(--good); color: #002a12; }
.up-tile.reveal { animation: flip-in .8s ease-out both; }
@keyframes flip-in {
  0% { transform: rotateY(90deg) scale(.8); filter: brightness(3); }
  60% { transform: rotateY(-12deg) scale(1.08); filter: brightness(1.6); box-shadow: 0 0 40px var(--good); }
  100% { transform: none; filter: none; }
}
.up-detail-icon.locked { filter: grayscale(1) brightness(.7); }
#up-detail .riddle, #cx-detail .riddle { font-style: italic; color: #cfc8ff; font-size: 16px; }
#btn-secrets.selected { border-color: var(--accent); }
.secret-list { list-style: none; padding: 0; margin: 6px 0 0; width: 100%; text-align: left; }
.secret-list li { padding: 8px 10px; border-radius: 10px; background: var(--well); margin-bottom: 8px; display: flex; flex-direction: column; gap: 2px; }
.secret-list li b { letter-spacing: .3em; color: var(--muted); }
.secret-list li.found b { color: var(--accent); letter-spacing: .12em; }
.secret-list li small { color: #b9b6e8; font-style: italic; }
#menu-screen.secret-flash { animation: secret-flash 1.2s ease-out; }
@keyframes secret-flash { 0% { box-shadow: inset 0 0 0 0 #b48cff; } 30% { box-shadow: inset 0 0 200px 40px #b48cffaa; } 100% { box-shadow: inset 0 0 0 0 transparent; } }

/* in-run: discovery toast, level-up tools */
.toast {
  position: absolute; top: 48px; left: 50%; transform: translateX(-50%); z-index: 7; pointer-events: none; white-space: nowrap;
  padding: 8px 18px; border-radius: 999px; font-weight: 700; background: #1a1440ee; border: 1px solid #b48cff; color: #e6dcff;
  box-shadow: 0 0 24px #b48cff66; animation: toast 3.6s forwards;
}
@keyframes toast { 0% { opacity: 0; transform: translate(-50%, -10px); } 10%, 85% { opacity: 1; transform: translate(-50%, 0); } 100% { opacity: 0; } }
.discovered { color: #cdb8ff; font-weight: 700; }
.reward-grid.four { grid-template-columns: repeat(4, 1fr); }
.reward-wrap { position: relative; display: flex; }
.reward-wrap .reward { flex: 1; }
.r-banish { position: absolute; top: -8px; right: -8px; width: 26px; height: 26px; padding: 0; border-radius: 50%; font-size: 12px; background: #3a1d2a; border-color: #ff7a8a; color: #ffd6dc; }
.lu-tools { margin-top: 12px; display: flex; gap: 12px; justify-content: center; align-items: center; flex-wrap: wrap; }

/* ---------- Shop: the merchant, your purse and letters, and the wares as reward cards ---------- */
#overlay .card[data-screen=shop] { width: min(880px, 96vw); padding: 20px 24px; }
[data-screen=shop] .shop-kicker { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
[data-screen=shop] .shop-kicker span { color: var(--accent); }
#overlay h1.merchant { margin: 2px 0 0; font-size: 34px; letter-spacing: .04em; }
.merchant-quirk { margin: 2px 0 10px; color: var(--muted); }
.purse { display: flex; gap: 8px; justify-content: center; margin-bottom: 10px; }
.purse > span { display: flex; flex-direction: column; min-width: 96px; padding: 4px 12px 6px; border-radius: 10px; background: var(--well); border: 1px solid var(--line); font-size: 12px; color: var(--muted); }
.purse b { font-size: 18px; color: var(--accent); }
.held-letters { display: flex; flex-direction: column; align-items: center; gap: 4px; margin-bottom: 10px; font-size: 13px; }
.held-letters .key { width: 32px; height: 30px; }
.held-letters .key .ch { font-size: 14px; }
.lu-held { margin-top: 14px; }
.wares { grid-template-columns: repeat(3, 1fr); margin: 10px 0 12px; }
.reward-grid .reward-wrap:nth-child(5) { animation-delay: .36s; }
.reward-grid .reward-wrap:nth-child(6) { animation-delay: .45s; }
.reward-grid.settled .reward-wrap { animation: none; }
.reward .r-price { margin-top: auto; font-weight: 800; color: var(--accent); white-space: nowrap; }
.reward .r-price s { color: var(--muted); font-weight: 400; font-size: 11px; }
.reward .r-price .free { color: var(--good); }
.ware.blood .r-price, .ware.cant .r-price, .reward .r-why { color: var(--danger); }
.ware.cant .reward { opacity: .6; }
.ware.sold .reward { opacity: .25; }
.ware.locked .reward { border-color: var(--good); box-shadow: 0 0 14px #5cff9d55; }
.ware.refused { animation: shake .25s; }
.r-lock { position: absolute; top: -8px; left: -8px; width: 28px; height: 28px; padding: 0; border-radius: 50%; font-size: 13px; }
.ware.locked .r-lock { border-color: var(--good); background: #12351f; }
.sc-sold { position: absolute; inset: 0; display: grid; place-items: center; font-weight: 900; font-size: 20px; letter-spacing: .2em; color: #ff7a8a; transform: rotate(-14deg); pointer-events: none; }
.ware.just-sold .sc-sold { animation: count-pop .3s ease-out; }
.ribbon { position: absolute; top: 8px; right: -6px; z-index: 1; padding: 2px 8px; font-size: 10px; font-weight: 900; letter-spacing: .1em; color: var(--on-accent); background: var(--good); border-radius: 4px; transform: rotate(8deg); pointer-events: none; }
.reward:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@media (max-width: 760px) { .wares { grid-template-columns: 1fr 1fr; } }
@keyframes deal { from { opacity: 0; transform: translateY(-16px) rotate(-3deg); } to { opacity: 1; transform: none; } }
.pack-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin-bottom: 14px; }
.pack-option { animation: deal .4s ease-out both; }
.pack-option.taken { opacity: .3; }

/* ---------- The stall (a theme's shop: 'stall'): the shop on the field ---------- */
/* The next chapter pinned up and the wares between the character and the merchant, who stands behind a counter on
   the right. The keyboard and HUD stay; the actions take the word input's place. */
#stall { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
#stall > * { pointer-events: auto; }
.stall-main { position: absolute; left: 21%; right: calc(2% + 280px); top: 3%; bottom: 4%; display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.stall-wares { align-self: stretch; margin: 0; grid-template-columns: repeat(3, 1fr); align-content: start; }
.stall-wares .reward { height: 100%; background: var(--panel); }
.stall-wares.pack-grid { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.stall-merchant { position: absolute; right: 2%; bottom: 5%; width: 256px; display: flex; flex-direction: column; align-items: center; }
.stall-bubble { position: relative; align-self: stretch; margin: 0 0 12px; padding: 8px 12px; border-radius: 12px; background: var(--panel); border: 1px solid var(--line); font-size: 14px; }
.stall-bubble p { margin: 0; }
.stall-bubble p + p { margin-top: 4px; }
.stall-bubble .quirk { color: var(--muted); }
.stall-bubble .news { color: var(--good); }
.stall-bubble .bad { color: var(--danger); }
.stall-keeper { font-size: 72px; line-height: 1; }
.stall-keeper canvas { display: block; image-rendering: pixelated; }
.stall-counter { position: relative; width: 256px; height: 96px; border-radius: 8px 8px 0 0; background: var(--panel-2); border: 1px solid var(--line); }
.stall-name { position: absolute; left: 50%; top: 30px; transform: translateX(-50%); white-space: nowrap; font-weight: 800; color: var(--accent); }
body.shopping #attack-form, body.shopping #preview, body.shopping #history { display: none; }
#stall-actions { grid-column: 1 / -1; display: flex; align-items: center; gap: 16px; min-height: 56px; }
.stall-hint { flex: 1; margin: 0; text-align: center; font-size: 13px; color: var(--muted); }
#stall-actions #btn-start { font-size: 20px; padding: 10px 40px; background: var(--accent); color: var(--on-accent); border: none; font-weight: 800; }
#stall-actions .next-wave { display: flex; align-items: center; gap: 16px; max-width: 48%; text-align: left; }
.next-wave .nw-go { white-space: nowrap; }
.next-wave .nw-info { display: flex; flex-direction: column; gap: 2px; padding-left: 16px; border-left: 2px solid currentColor; font-size: 15px; font-weight: 600; }
.next-wave .nw-rule { font-size: 13px; font-weight: 400; opacity: .85; }
/* In the shop, notices go on the floor under the wares (centred on .stall-main), not over them. */
body.shopping .toast { top: auto; bottom: 12px; left: calc(59.5% - 140px); }
#coins.spent { display: inline-block; animation: count-pop .3s ease-out; }
@media (max-width: 1100px) {
  .stall-main { right: calc(2% + 200px); }
  body.shopping .toast { left: calc(59.5% - 100px); }
  .stall-wares { grid-template-columns: repeat(2, 1fr); }
  .stall-merchant { width: 192px; }
}

/* ---------- Developer panel (?dev) ---------- */
#dev-panel {
  position: fixed; left: 10px; bottom: 10px; z-index: 1000; width: 300px; max-height: calc(100vh - 20px); overflow: auto;
  padding: 8px 10px; border-radius: 10px; background: color-mix(in srgb, var(--well) 94.1%, transparent); border: 1px solid #ff9f43; box-shadow: 0 10px 30px #000a;
  font-size: 12px; color: var(--text);
}
#dev-panel.hidden { display: none; }
#dev-panel.right { left: auto; right: 10px; }
#dev-panel.folded > :not(.dev-head) { display: none; }
.dev-head { display: flex; align-items: center; gap: 8px; }
.dev-head b { color: #ff9f43; letter-spacing: .1em; }
.dev-status { flex: 1; color: var(--muted); }
.dev-group { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; padding: 6px 0; border-top: 1px solid var(--line-soft); margin-top: 6px; }
.dev-group h4 { width: 100%; margin: 0 0 2px; font-size: 10px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
#dev-panel button { font-size: 12px; padding: 3px 7px; border-radius: 6px; }
#dev-panel button.on { background: #ff9f43; color: #1a1000; border-color: #ff9f43; }
#dev-panel input, #dev-panel select { font-size: 12px; background: #1a1c33; color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 2px 4px; }
.dev-wave { width: 44px; }
.dev-lbl { color: var(--muted); margin-right: 2px; }
.dev-msg { min-height: 14px; color: #ff9f43; margin-top: 4px; }
/* Particles from fx.js: above the enemies, below the floating numbers. */
#field > canvas.fx-particles { position: absolute; left: 0; top: 0; z-index: 4; image-rendering: pixelated; pointer-events: none; }

/* The Codex: category tabs over a grid of entries, like the Hall of Upgrades, with the entry beside them. The layout
   fills the page between the title and Back, and a long entry scrolls in its panel, so nothing moves when the
   entry changes. */
#view-codex, #view-words { justify-content: flex-start; }
.cx-layout { flex: 1 1 0; grid-template-columns: 1fr 360px; }
.cx-main { display: flex; flex-direction: column; min-height: 0; }
#cx-grid, #wj-grid { flex: 1 1 0; min-height: 0; max-height: none; }
#cx-detail, #wj-detail { min-height: 0; overflow-y: auto; }
@media (max-width: 820px) { .cx-layout { grid-template-columns: 1fr; } }
#cx-tabs { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 4px 0 14px; }
.cx-tab small { opacity: .7; font-size: .8em; }
.cx-tab.selected { border-color: var(--accent); box-shadow: 0 0 18px #ffcf5c55; }
.cx-tab .badge.new { margin-left: 2px; }
.cx-tile { position: relative; }
.cx-tile:not(.locked) { border-color: var(--el, var(--line)); }
#cx-detail p { text-align: left; align-self: stretch; }
#cx-detail .cx-cat, #cx-detail .riddle { text-align: center; }

/* The word journal: the codex's layout, with a search, an order and element filters over the grid. Each tile's strip
   shows its word's elements, as wide as their share of it. */
#wj-tools { display: flex; justify-content: center; gap: 10px; margin: 4px 0 10px; }
#wj-search { flex: 0 1 320px; font: inherit; font-size: 16px; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 4px 10px; outline: none; }
#wj-sort { font: inherit; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 4px 8px; }
#wj-els { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 0 0 12px; }
.wj-tile .up-name { max-width: 100%; overflow-wrap: anywhere; }
.wj-tile .up-name.long { font-size: 11px; }
.wj-strip { display: flex; gap: 2px; width: 80%; height: 4px; }
.wj-strip i { background: var(--el); }
.wj-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 6px 0; }
#wj-detail .wj-stats { color: var(--muted); }

/* ---------- The Pyre Wyrm: a sprite instead of a card, its HP in a bar across the top of the field ---------- */
.enemy.boss.wyrm { min-width: 0; width: auto; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none;
  clip-path: none; filter: drop-shadow(0 6px 0 #07090a99); }
.enemy.wyrm .wyrm-sprite { display: block; image-rendering: pixelated; }
.enemy.wyrm .status-row { position: absolute; top: 18%; left: 50%; transform: translateX(-50%); white-space: nowrap; }
.enemy.wyrm.enraged { animation: wyrm-hot 1s steps(2) infinite; }
@keyframes wyrm-hot { 50% { filter: drop-shadow(0 0 18px var(--fx-fire-hot)) brightness(1.15); } }
.enemy.wyrm.hurt { animation: wyrm-hurt .25s steps(2); }
@keyframes wyrm-hurt { 50% { filter: brightness(2.2) saturate(.4); } }
.enemy.wyrm.entering { animation: wyrm-enter 1.4s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes wyrm-enter {
  0% { transform: translateX(calc(-50% + 420px)) translateY(-260px) scale(.6); opacity: 0; }
  60% { transform: translateX(-50%) translateY(10px) scale(1.04); opacity: 1; }
  100% { transform: translateX(-50%); }
}
.enemy.wyrm.dying { animation: wyrm-die 1.2s steps(12) forwards; }
@keyframes wyrm-die {
  0% { filter: brightness(2) sepia(1); clip-path: inset(0 0 0 0); }
  100% { filter: brightness(.4) sepia(1) saturate(3); clip-path: inset(0 0 100% 0); }
}
.boss-bar { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 5; width: min(620px, 60%);
  padding: 8px 14px 10px; border-radius: 12px; background: #1a0a0ccc; border: 2px solid var(--fx-fire-deep); box-shadow: 0 0 30px -6px var(--fx-flame);
  animation: bar-in .6s ease-out both; pointer-events: none; }
.boss-bar.gone { animation: bar-out .6s ease-in forwards; }
@keyframes bar-in { from { opacity: 0; transform: translate(-50%, -30px); } }
@keyframes bar-out { to { opacity: 0; transform: translate(-50%, -30px); } }
.boss-bar .bb-head { display: flex; align-items: center; justify-content: center; gap: 10px; }
.boss-bar .boss-name { font-size: 22px; font-weight: 800; letter-spacing: .06em; color: var(--fx-ember); text-shadow: 0 0 12px var(--fx-flame); }
.boss-bar .bar { position: relative; height: 12px; margin-top: 6px; }
.boss-bar .hp-fill { background: linear-gradient(90deg, var(--fx-fire-deep), var(--fx-flame), var(--fx-ember)); width: 100%; }
.boss-bar .phase-mark { position: absolute; top: -3px; bottom: -3px; width: 2px; background: #fff; z-index: 1; opacity: .85; }
.boss-bar .meta { display: flex; justify-content: space-between; margin-top: 4px; font-size: 12px; color: #f3d9c4; }
.boss-bar .boss-phase { color: #ffb13d; }
#field.quake { animation: quake .6s steps(8); }
@keyframes quake {
  0%, 100% { translate: 0 0; } 15% { translate: -8px 4px; } 30% { translate: 7px -5px; } 45% { translate: -6px -3px; }
  60% { translate: 5px 4px; } 75% { translate: -3px 2px; } 90% { translate: 2px -1px; }
}
/* Moods (fx.setMood): #field gets data-burn / data-dark / data-wind = low | high while one is on.
   The library on fire: themes with a live backdrop draw real flames; this glow stands in for the rest. */
#field::after { content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0; transition: opacity 2s;
  background: radial-gradient(ellipse 70% 90% at 100% 60%, color-mix(in srgb, var(--fx-flame) 53.3%, transparent), color-mix(in srgb, var(--fx-fire-deep) 20%, transparent) 55%, transparent 75%); }
#field[data-burn=low]::after { opacity: .6; animation: fire-glow 1.2s steps(3) infinite alternate; }
#field[data-burn=high]::after { opacity: 1; animation: fire-glow .8s steps(3) infinite alternate;
  background: radial-gradient(ellipse 110% 100% at 100% 60%, color-mix(in srgb, var(--fx-flame) 66.7%, transparent), color-mix(in srgb, var(--fx-fire-deep) 26.7%, transparent) 60%, transparent 85%); }
@keyframes fire-glow { to { filter: brightness(1.3); } }
#field:has(> canvas.backdrop.live)[data-burn]::after { opacity: .25; }

/* ---------- The Hollow: shadows in the dark, their hidden words across their chests ---------- */
.enemy.boss.shade { min-width: 0; width: auto; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none;
  clip-path: none; filter: none; }
.enemy.shade .shade-sprite { display: block; image-rendering: pixelated; }
.enemy.shade .status-row { display: none; }
.shadow-word { position: absolute; left: 50%; top: 36%; transform: translate(-50%, -50%); display: flex; gap: calc(var(--px) * 0.5px); }
.shadow-word .tile { width: calc(var(--px) * 4px); height: calc(var(--px) * 5px); display: grid; place-items: center;
  font-size: calc(var(--px) * 3.6px); font-weight: 800; line-height: 1; color: #6a5a92; background: #0b0912; box-shadow: inset 0 0 0 1px #33284a; }
.shadow-word .tile.lit { color: #2a1a06; background: var(--fx-light); box-shadow: 0 0 calc(var(--px) * 3px) var(--fx-light), inset 0 0 0 1px #c89a3c; }
.shadow-word .tile.flip { animation: tile-flip .35s steps(4); }
@keyframes tile-flip { 50% { transform: scaleX(0); } }
.shadow-word .tile.solved { background: #fff6d0; }
.shadow-word .tile.missed { color: #ffb0a0; background: #3a0d12; box-shadow: inset 0 0 0 1px #b8462a; }
.shadow-lock { position: absolute; left: 50%; bottom: 4px; transform: translateX(-50%); font-size: 14px; color: #cbb8ff; white-space: nowrap; }
.enemy.shade.rising { animation: shade-rise 1.6s cubic-bezier(.2, .8, .3, 1) var(--rise-delay, 0s) both; }
@keyframes shade-rise {
  0% { clip-path: inset(100% 0 0 0); transform: translateX(-50%) translateY(30px); opacity: 0; }
  100% { clip-path: inset(0); transform: translateX(-50%); opacity: 1; }
}
.enemy.shade.gulp { animation: shade-gulp .45s steps(4); }
@keyframes shade-gulp { 40% { transform: translateX(-50%) scale(1.08, .94); } }
/* Freed: it burns white and rises away as light (after the solving shot lands). */
.enemy.shade.solved { animation: shade-free 1.4s steps(14) .28s forwards; }
@keyframes shade-free {
  30% { filter: brightness(3) sepia(1); opacity: 1; }
  100% { filter: brightness(4) sepia(1); opacity: 0; transform: translateX(-50%) translateY(-40px); }
}
.projectile.dark-swallow { animation: into-dark .28s ease-in forwards; }
@keyframes into-dark { to { opacity: .15; filter: brightness(.2); } }
.projectile.dark-solve { color: #fff6d0; text-shadow: 0 0 12px var(--fx-light), 0 0 24px var(--fx-light); }
.hollow-bar { border-color: #5b4a82; box-shadow: 0 0 30px -6px #5b4a82; background: #0b0912e6; }
.hollow-bar .boss-name { color: #cbb8ff; text-shadow: 0 0 12px #5b4a82; }
.hollow-bar .boss-phase { color: var(--fx-light); }
.hollow-pips { display: flex; gap: 8px; font-size: 22px; }
.hollow-pips .pip.freed { filter: drop-shadow(0 0 6px var(--fx-light)); }
.hollow-clock { font-size: 20px; font-weight: 700; color: #cbb8ff; font-variant-numeric: tabular-nums; }
.hollow-clock.urgent { color: var(--danger); animation: clock-urgent .8s ease-in-out infinite; }
@keyframes clock-urgent { 50% { opacity: .45; } }
.wild-drop { font-size: 18px; }
#history .used.lit { color: var(--fx-light); }
#history .used.swallowed { color: #6a5a92; }
#history .used.solved { color: var(--good); }
/* The lights out: themes with a live backdrop darken the room themselves; this stands in for the rest. */
#field::before { content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none; background: color-mix(in srgb, var(--fx-dark) 80%, transparent); opacity: 0; transition: opacity 2s; }
#field[data-dark]::before { opacity: 1; }
#field:has(> canvas.backdrop.live)[data-dark]::before { opacity: .15; }

/* ---------- The Tempest: a funnel of wind in the air, its gust's letters swirling around it ---------- */
.enemy.boss.gale { min-width: 0; width: auto; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none;
  clip-path: none; filter: drop-shadow(0 10px 0 #07090a55); }
.enemy.gale .gale-sprite { display: block; image-rendering: pixelated; }
.enemy.gale .status-row { display: none; }
.enemy.gale.entering { animation: gale-enter 1.4s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes gale-enter {
  0% { transform: translateX(calc(-50% + 320px)) scale(.2, 1.4); opacity: 0; }
  60% { transform: translateX(-50%) scale(1.1, .95); opacity: 1; }
  100% { transform: translateX(-50%); }
}
.enemy.gale.hurt { animation: gale-hurt .25s steps(2); }
@keyframes gale-hurt { 50% { filter: brightness(2) saturate(.4); } }
/* Its last gust broken: the funnel spreads out flat and blows away. */
.enemy.gale.unwound { animation: gale-unwind 1.3s steps(13) forwards; }
@keyframes gale-unwind { to { transform: translateX(-50%) scale(2.4, .1); opacity: 0; filter: brightness(2); } }
.gust-tile { position: absolute; left: 0; top: 0; width: 30px; height: 34px; display: grid; place-items: center; z-index: 1;
  font-weight: 900; font-size: 20px; line-height: 1; text-transform: uppercase; color: #121a24; background: var(--fx-air-pale);
  border-radius: 5px; box-shadow: 0 0 14px color-mix(in srgb, var(--fx-air) 66.7%, transparent), inset 0 -3px 0 var(--fx-air-edge); will-change: transform; pointer-events: none; }
.gust-tile.scatter { animation: gust-scatter .6s ease-out forwards; }
@keyframes gust-scatter { to { translate: var(--dx) var(--dy); rotate: var(--rot); opacity: 0; } }
.gust-tile.blasting { background: #fff6d0; box-shadow: 0 0 18px #ff9b5c; }
.tempest-bar { border-color: var(--fx-air-edge); box-shadow: 0 0 30px -6px var(--fx-air-edge); background: #121a24e6; }
.tempest-bar .boss-name { color: var(--fx-air-pale); text-shadow: 0 0 12px #5c7a92; }
.tempest-pips { display: flex; gap: 6px; font-size: 20px; }
.tempest-pips .pip.broken { filter: drop-shadow(0 0 6px var(--fx-air-pale)); }
.gust-bar .gust-fill { position: absolute; inset: 0; background: linear-gradient(90deg, #5c7a92, var(--fx-air-pale)); transform-origin: left; transition: none; }
.gust-bar.urgent .gust-fill { background: linear-gradient(90deg, #b8462a, #ff9b5c); }
.tempest-bar .gust-clock { font-variant-numeric: tabular-nums; }
/* The keyboard in the wind: only the gust's letters, free (∞); the rest can't be typed. */
.key.windless { opacity: .15; }
.key.windy { border-color: var(--fx-air-edge); box-shadow: 0 0 10px -2px var(--fx-air); }
.key.windy .n { color: var(--fx-air); }
.key.windy .v { color: var(--fx-air-pale); font-weight: 700; }
.key.windy.spent { opacity: .5; }
.key.refused, #attack-input.refused { animation: shake .25s; }
.key.refused { background: #5a1f28; border-color: var(--danger); }
#history .used.broke { color: var(--fx-air-pale); }
#history .used.missed { color: var(--danger); }
/* Wind for themes without a live backdrop: pale streaks blowing toward the base. */
#fx::before { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 1.5s;
  background: repeating-linear-gradient(176deg, transparent 0 22px, color-mix(in srgb, var(--fx-air) 13.3%, transparent) 22px 24px, transparent 24px 61px);
  background-size: 400px 100%; }
#field[data-wind] #fx::before { opacity: 1; animation: wind-streaks .6s linear infinite; }
#field:has(> canvas.backdrop.live)[data-wind] #fx::before { opacity: .25; }
@keyframes wind-streaks { to { background-position: -400px 0; } }

/* ---------- The shelf (Play) ---------- */
/* Each book is its cover (a theme image: .book-cover, by data-id) with three lines under it. */
#view-books { justify-content: center; }
#bk-shelf { display: flex; justify-content: center; gap: 72px; padding: 8px; }
.book { width: 220px; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 0; color: var(--text); background: none; border: 0; transition: transform .1s; }
.book-cover { width: 160px; height: 220px; margin-bottom: 14px; background: var(--panel-2); border: 2px solid var(--line); }
.book:hover, .book:focus-visible { outline: none; transform: translateY(-6px); }
.book.locked:hover, .book.locked:focus-visible { transform: none; }
.book-number { font-size: 13px; text-transform: uppercase; letter-spacing: .14em; color: var(--muted); }
.book-name { font-size: 22px; font-weight: 700; }
.book-progress { font-size: 14px; color: var(--muted); }
.book:focus-visible .book-name { color: var(--accent); }
.book.locked .book-name, .book.locked .book-progress { color: var(--muted); }

/* ---------- Characters (after the book) ---------- */
/* A row of small portraits (a theme image: .character-portrait, by data-id); the one hovered or focused (.shown)
   has its name and blurb in #ch-detail under the row. */
#view-characters { justify-content: center; }
#ch-shelf { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; padding: 8px; }
.character { padding: 4px; color: var(--text); background: var(--panel-2); border: 2px solid var(--line); border-radius: 8px; transition: transform .1s; }
.character-portrait { display: block; width: 64px; height: 64px; }
.character:hover, .character:focus-visible { outline: none; transform: translateY(-4px); }
.character.shown { border-color: var(--accent); }
.character.locked { opacity: .5; }
.character.locked:hover, .character.locked:focus-visible { transform: none; }
#ch-detail { display: flex; flex-direction: column; align-items: center; gap: 4px; max-width: 520px; min-height: 4.5em; margin: 12px auto 0; text-align: center; }
.character-name { font-size: 22px; font-weight: 700; }
.character-blurb { font-size: 14px; color: var(--muted); line-height: 1.3; }
#ch-detail.locked .character-name { color: var(--muted); }
#overlay-card .unlocked { color: var(--good); }

/* ---------- The tutorial (ui/tutorial.js): the coach's note at the top of the field, and what it's about outlined */
#coach {
  position: absolute; top: 12px; left: 0; right: 0; margin: 0 auto; z-index: 7; width: min(600px, calc(100% - 32px));
  padding: 12px 16px; font-size: 15px; line-height: 1.35; color: var(--text); background: var(--panel);
  border: 1px solid var(--accent); border-radius: 10px; box-shadow: 0 6px 24px #0008;
}
#coach .coach-head { display: flex; gap: 10px; align-items: baseline; font-size: 18px; }
#coach .coach-count { color: var(--muted); font-size: 13px; }
#coach p { margin: 6px 0 0; }
#coach .coach-hint { color: var(--accent); font-weight: 700; }
#coach .coach-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 10px; }
#coach.hint { animation: shake .3s; }
.coach-glow { outline: 2px solid var(--accent); outline-offset: 4px; animation: coach-glow .9s ease-in-out infinite alternate; }
@keyframes coach-glow { from { outline-color: transparent; } }
body.shopping #coach { top: auto; bottom: 12px; }

/* The base has fallen (showFatalBlow): the field stops and greys around the character, a red flash, and what struck
   the last blow stays written over the base until the end screen. */
#field.fallen #lane, #field.fallen #towers, #field.fallen #aids, #field.fallen #fx { filter: grayscale(.85) brightness(.55); transition: filter 1.4s ease-out; }
.fatal-flash { position: absolute; inset: 0; pointer-events: none; animation: fatal-flash 2.4s ease-out forwards;
  background: radial-gradient(ellipse at 8% 70%, transparent 0 12%, rgba(90, 0, 10, .55) 70%, rgba(20, 0, 4, .8)); }
@keyframes fatal-flash { 0% { background-color: rgba(255, 30, 40, .55); } 18% { background-color: rgba(255, 30, 40, .15); } 100% { background-color: transparent; } }
.fatal-blow { position: absolute; transform: translate(-50%, -100%); text-align: center; white-space: nowrap; color: var(--danger);
  animation: fatal-blow .45s cubic-bezier(.2, 1.6, .4, 1) both; }
.fatal-blow b { display: block; font-size: 64px; font-weight: 900; line-height: 1; text-decoration: line-through; text-shadow: 0 0 18px #000, 0 0 30px #ff2030; }
.fatal-blow small { display: block; font-size: 18px; font-weight: 700; color: #fff; text-shadow: 0 0 8px #000; }
@keyframes fatal-blow { from { scale: 2.4; opacity: 0; } to { scale: 1; opacity: 1; } }

/* ---------- The game-over screen: a death certificate on old paper (gameover.js) */
#overlay .card[data-screen=gameover] { width: min(780px, 96vw); padding: 8px 18px 4px; overflow-x: hidden; background: none; border: 0; box-shadow: none; }
.certificate { --cert-paper: #ecdcb4; --cert-edge: #c9ae7a; --cert-rule: #8a7148; --cert-print: #4a3520; --cert-hand: #1f2c52; --cert-red: #9a2b24;
  position: relative; padding: 20px 36px 18px; text-align: left; color: var(--cert-print);
  background:
    radial-gradient(circle at 16% 26%, transparent 0 30px, #8a5a2a2e 31px 35px, transparent 36px),  /* a cup's ring */
    radial-gradient(ellipse 120px 70px at 10% 90%, #9c7a4430, transparent),                         /* a stain */
    linear-gradient(to bottom, transparent calc(50% - 1px), #7f6a4633 calc(50% - 1px) 50%, #fff6 50% calc(50% + 1px), transparent calc(50% + 1px)), /* the fold */
    radial-gradient(ellipse at center, var(--cert-paper) 40%, var(--cert-edge) 100%);
  box-shadow: 0 0 0 4px #07090a, 10px 10px 0 4px #0009; }
/* the form's double rule */
.certificate::before { content: ''; position: absolute; inset: 8px; pointer-events: none; border: 2px solid var(--cert-rule);
  outline: 2px solid var(--cert-rule); outline-offset: -6px; }
.cert-head { text-align: center; padding-bottom: 8px; border-bottom: 6px double var(--cert-rule); }
.cert-office { display: block; font-size: 14px; letter-spacing: .2em; text-transform: uppercase; }
#overlay .certificate h1 { margin: 2px 0; font-size: 44px; letter-spacing: .06em; color: var(--cert-print); }
.cert-no { position: absolute; top: 20px; right: 36px; color: var(--cert-red); font-size: 14px; }
.cert-body { display: flex; gap: 24px; align-items: center; margin: 6px 0 2px; }
.cert-who { flex: 1; text-align: center; }
.cert-line { margin: 2px 0; }
.cert-line b, .cert-fields dd, .cert-name, .stats b { color: var(--cert-hand); }
#overlay .certificate .cert-name { margin: 4px auto; font-size: 34px; font-weight: 700; border-bottom: 2px dashed var(--cert-rule); width: fit-content; min-width: 60%; padding: 0 12px; }
.cert-portrait { padding: 6px; background: #d8c49a; border: 2px solid var(--cert-print); box-shadow: 4px 4px 0 #0003; }
.cert-portrait canvas { display: block; image-rendering: pixelated; filter: sepia(.7) contrast(1.1); }
.cert-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 28px; margin: 4px 0; }
.cert-fields .cert-wide { grid-column: 1 / -1; }
.cert-fields dt { font-size: 13px; letter-spacing: .12em; text-transform: uppercase; }
.cert-fields dd { margin: 0; font-size: 20px; border-bottom: 2px dotted var(--cert-rule); }
.cert-section { display: flex; align-items: center; gap: 12px; margin: 8px 0 2px; font-size: 14px; letter-spacing: .2em; text-transform: uppercase; color: var(--cert-print); }
.cert-section::before, .cert-section::after { content: ''; flex: 1; border-top: 2px solid var(--cert-rule); }
#overlay .certificate .stats { grid-template-columns: repeat(3, 1fr); gap: 2px 22px; margin: 0; }
#overlay .certificate .stats div { display: flex; align-items: baseline; padding: 0; color: inherit; background: none; border: 0; border-radius: 0; border-image: none; }
.certificate .stats div::before { content: ''; order: 1; flex: 1; min-width: 8px; margin: 0 4px; border-bottom: 2px dotted var(--cert-rule); }
#overlay .certificate .stats b { order: 2; display: inline; font-size: 16px; white-space: nowrap; }
.cert-remarks { flex: 1; align-self: stretch; }
.cert-remarks .cert-section { margin-top: 0; }
.cert-remarks ul { margin: 0; padding: 0; list-style: none; }
.cert-remarks li::before { content: '— '; }
.cert-foot { display: flex; gap: 22px; align-items: flex-end; margin-top: 10px; }
.cert-sign { flex: none; text-align: center; }
.cert-scrawl { display: block; padding: 0 10px; font-size: 30px; font-style: italic; color: var(--cert-hand); border-bottom: 2px solid var(--cert-print); }
.cert-sign small { font-size: 13px; letter-spacing: .12em; text-transform: uppercase; }
.cert-stamp { flex: none; margin: 0 6px 6px 0; padding: 4px 16px; text-align: center; color: var(--cert-red); border: 4px double var(--cert-red); rotate: -8deg; opacity: .85;
  mix-blend-mode: multiply; animation: cert-stamp .25s .55s cubic-bezier(.3, 1.6, .5, 1) both; }
.cert-stamp b { display: block; font-size: 30px; letter-spacing: .1em; text-transform: uppercase; line-height: 1; }
.cert-stamp small { font-size: 13px; letter-spacing: .1em; text-transform: uppercase; }
@keyframes cert-stamp { from { scale: 2.2; opacity: 0; } to { scale: 1; opacity: .85; } }
#overlay .card[data-screen=gameover] .menu-actions { margin-top: 12px; justify-content: center; }

/* The demo's mark under the logo (only the demo build writes it, see scripts/build-demo.mjs) */
.logo-text .logo-demo { display: block; font-size: .3em; letter-spacing: .4em; text-transform: uppercase; color: var(--accent); }
