/* THE SEVEN LEVELS — browser interface */

:root {
  /* Semantic terminal palette — see the color hierarchy in the CSS comments
     below for how each is used. Everything stays green-phosphor except the
     two sparingly-used accents (amber for warnings/treasure, red for
     critical danger). */
  --terminal-green: #33ff33;         /* normal text — standard phosphor */
  --terminal-green-bright: #99ff99;  /* player indicator, active controls */
  --terminal-green-dim: #00aa00;     /* secondary labels, panel borders */
  --terminal-white: #e8e8e8;         /* dungeon walls / corridor geometry */
  --terminal-amber: #ffb000;         /* HP warning, gold/treasure, important temp messages */
  --terminal-red: #ff3333;           /* critical danger */
  --terminal-bg: #000000;

  /* Structural chrome — panel fills. Borders/dividers all use
     --terminal-green-dim throughout, so every rule on screen — panel
     outlines and section dividers alike — is drawn with the same weight
     and color, like one consistent line-drawing character set. */
  --panel: #000000;
  --font: 'Courier New', Courier, monospace;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  background: var(--terminal-bg);
  color: var(--terminal-green);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.4;
  height: 100%;
  overflow: hidden;
}

#terminal {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
  height: 100vh;
  overflow-y: auto;
  padding: 8px 12px;
  gap: 6px;
}

/* Header */
#header {
  border-bottom: 1px solid var(--terminal-green-dim);
  padding-bottom: 4px;
  text-align: center;
}

#game-title {
  color: var(--terminal-green);
  font-size: 16px;
  font-weight: bold;
  letter-spacing: 4px;
}

/* Status bar */
#status-bar {
  position: relative;
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  padding: 4px 46px 4px 0;   /* room on the right for the compass */
  min-height: 38px;
  border-bottom: 1px solid var(--terminal-green-dim);
  font-size: 13px;
}

/* Player-identifying elements get the bright accent; plain stat labels stay
   dim; HP escalates from normal -> amber -> red as danger rises; gold and
   potions (treasure/resources) are amber. */
#char-name    { color: var(--terminal-green-bright); font-weight: bold; flex: 1; }
#dungeon-level { color: var(--terminal-green-dim); }
#char-level   { color: var(--terminal-green-dim); }
#hp-display   { color: var(--terminal-green); min-width: 100px; }
#hp-display.warn { color: var(--terminal-amber); }
#hp-display.crit { color: var(--terminal-red); }
#shock-display { color: var(--terminal-red); font-weight: bold; animation: fx-blink 1.1s steps(1) infinite; }
#shock-display.hidden { display: none; }
#rot-display { color: var(--terminal-amber); }
#rot-display.doomed { color: var(--terminal-red); font-weight: bold; animation: fx-blink 1.1s steps(1) infinite; }
#rot-display.hidden { display: none; }
#xp-display       { color: var(--terminal-green-dim); }
#gold-display     { color: var(--terminal-amber); }
#potions-display  { color: var(--terminal-green-dim); }
#potions-display.has-potions { color: var(--terminal-amber); }
#gems-display     { color: var(--terminal-green-dim); }
#gems-display.has-potions { color: var(--terminal-amber); }
#compass-display  { position: absolute; right: 2px; top: 4px; width: 36px; height: 36px; }
#compass-display svg { width: 100%; height: 100%; display: block; overflow: visible; }
#compass-display .bezel { fill: rgba(0, 40, 0, 0.55); stroke: var(--terminal-green-dim); stroke-width: 1.2; }
#compass-display .major { stroke: var(--terminal-green-bright); stroke-width: 1.4; }
#compass-display .minor { stroke: var(--terminal-green-dim); stroke-width: 0.9; }
#compass-display .north { fill: var(--terminal-green-bright); font: bold 6.5px monospace; text-anchor: middle; }
#compass-display .needle { transform-origin: 18px 18px; transition: transform 380ms cubic-bezier(.3,1.4,.5,1); }
#compass-display .tip  { fill: #ff4a2a; stroke: #ffb59e; stroke-width: 0.4; filter: drop-shadow(0 0 1.5px rgba(255, 70, 30, 0.8)); }
#compass-display .tail { fill: #d8e8d8; opacity: 0.75; }
#compass-display .hub  { fill: #0a1a0a; stroke: var(--terminal-green-bright); stroke-width: 0.8; }

/* Dungeon view, monster portrait, and messages are all the same "panel"
   primitive — same border weight/color, same padding — so they read as
   panes of one terminal rather than separate widgets. Each panel spans the
   full width of #terminal; content that's narrower than the panel (the
   fixed-width corridor render, the monster sprite) is centered within it. */
#view-container {
  position: relative;
  flex-shrink: 0;
}

#dungeon-view {
  background: var(--panel);
  border: 1px solid var(--terminal-green-dim);
  padding: 8px 12px;
  /* The corridor render is almost entirely walls/ceiling/floor geometry —
     rendered in white, distinct from the green UI chrome around it. */
  color: var(--terminal-white);
  font-size: 13px;
  line-height: 1.15;
  letter-spacing: 0;
  text-align: center;
  min-height: 300px;
  max-width: 100%;
  overflow-x: auto;
}

/* Monster portrait (combat only) — overlaid directly on the corridor view,
   no border/background of its own, so it reads as something standing in
   the passage rather than a separate boxed widget. */
#monster-portrait {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

#monster-portrait svg {
  width: calc(190px * var(--sprite-scale, 1));
  height: calc(190px * var(--sprite-scale, 1));
}

/* A great lord seen from afar: Asmodeus on his throne, smaller the farther away */
#sighting {
  position: absolute; inset: 0;
  pointer-events: none; z-index: 2; overflow: hidden;
}
#sighting.hidden { display: none; }
#sighting .seat {
  position: absolute; left: var(--sight-x, 50%); top: 50%;
  width: var(--sight-w, 40%); transform: translate(-50%, -48%);
  opacity: var(--sight-o, 1); transition: left 300ms ease, width 300ms ease, opacity 300ms ease;
}
#sighting .seat > svg { width: 100%; height: auto; display: block; }
#sighting .seat.mirrored > svg { transform: scaleX(-1); }
#sighting .seat.empty .lord-figure { display: none; }
/* Misty fire and drifting smoke around the throne */
#sighting .mist { position: absolute; inset: -12% -10% 0 -10%; pointer-events: none; }
#sighting .mist i {
  position: absolute; bottom: 10%; width: 34%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, rgba(120, 60, 50, 0.55), rgba(40, 10, 8, 0) 70%);
  filter: blur(6px); animation: throne-mist 7s ease-in infinite;
}
#sighting .mist i:nth-child(1) { left: 6%;  animation-delay: -1s; }
#sighting .mist i:nth-child(2) { left: 30%; animation-delay: -3.2s; animation-duration: 8s; }
#sighting .mist i:nth-child(3) { left: 52%; animation-delay: -5s; }
#sighting .mist i:nth-child(4) { left: 70%; animation-delay: -2.2s; animation-duration: 9s; }
#sighting .mist i:nth-child(5) { left: 40%; animation-delay: -6.1s; animation-duration: 6s; }
#sighting .mist b {
  position: absolute; left: 10%; right: 10%; bottom: 4%; height: 26%; border-radius: 50%;
  background: radial-gradient(ellipse at 50% 80%, rgba(255, 120, 30, 0.55), rgba(200, 30, 6, 0.25) 45%, rgba(0, 0, 0, 0) 75%);
  filter: blur(8px); animation: throne-fire 2.6s ease-in-out infinite alternate;
}
@keyframes throne-mist {
  0%   { transform: translateY(10%) scale(0.7); opacity: 0; }
  25%  { opacity: 0.9; }
  100% { transform: translateY(-120%) scale(1.6); opacity: 0; }
}
@keyframes throne-fire { from { opacity: 0.65; transform: scaleY(0.9); } to { opacity: 1; transform: scaleY(1.15); } }
@media (prefers-reduced-motion: reduce) { #sighting .mist i, #sighting .mist b { animation: none; } }
#sighting .lord { position: absolute; left: 27%; width: 46%; bottom: 17%; }
#sighting .lord svg { width: 100%; height: auto; display: block; filter: drop-shadow(0 0 8px rgba(255, 60, 20, 0.5)); }

/* ─── A great lair's warning screen ──────────────────────────────────────
   The corridor fades to a red-dark backdrop and the lair's art fills the view. */
#view-container.lair-mode #dungeon-view { opacity: 0.12; transition: opacity 600ms ease; }
#view-container.lair-mode { background: radial-gradient(ellipse at 50% 60%, #3a0804 0%, #000 75%); }
#monster-portrait.lair svg { width: 100%; height: 100%; max-height: 100%; }
#monster-portrait.lair { animation: lair-in 900ms ease-out; }
@keyframes lair-in { from { opacity: 0; transform: scale(1.06); } to { opacity: 1; transform: none; } }

.lair-smoke { transform-box: fill-box; transform-origin: center; animation: lair-smoke 6s ease-in infinite; }
.lair-smoke.s2 { animation-delay: -1.2s; animation-duration: 7s; }
.lair-smoke.s3 { animation-delay: -2.6s; }
.lair-smoke.s4 { animation-delay: -3.4s; animation-duration: 5.5s; }
.lair-smoke.s5 { animation-delay: -4.5s; animation-duration: 6.5s; }
.lair-smoke.s6 { animation-delay: -0.8s; animation-duration: 4.5s; }
.lair-smoke.s7 { animation-delay: -2.9s; animation-duration: 5s; }
.lair-smoke.s8 { animation-delay: -1.9s; animation-duration: 8s; }
@keyframes lair-smoke {
  0%   { transform: translateY(20px) scale(0.6); opacity: 0; }
  20%  { opacity: 0.9; }
  100% { transform: translateY(-80px) scale(1.8); opacity: 0; }
}
.lair-flame { transform-box: fill-box; transform-origin: 50% 100%; animation: lair-flame 0.45s ease-in-out infinite alternate; }
.lair-flame.f2 { animation-delay: -0.2s; animation-duration: 0.52s; }
@keyframes lair-flame {
  from { transform: scale(0.92, 1.0) skewX(-3deg); opacity: 0.9; }
  to   { transform: scale(1.06, 1.12) skewX(3deg); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .lair-smoke, .lair-flame, #monster-portrait.lair { animation: none; }
  .lair-smoke { opacity: 0.5; }
}

/* ─── Hit effects ─────────────────────────────────────────────────────────
   --fx is the element colour (set from app.js), --shake the jolt size. */
#fx-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 3;
}

/* A glow flooding in from the edges of the view, tinted by element */
.fx-flash {
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 60px 18px var(--fx);
  background: radial-gradient(ellipse at center, transparent 45%, color-mix(in srgb, var(--fx) 35%, transparent));
  animation: fx-flash 380ms ease-out forwards;
}
.fx-flash.fx-big {
  box-shadow: inset 0 0 120px 40px var(--fx);
  animation-duration: 700ms;
}
.fx-flash.fx-flicker { animation: fx-flicker 420ms steps(1) forwards; }
@keyframes fx-flash   { 0% { opacity: 0.95; } 100% { opacity: 0; } }
@keyframes fx-flicker { 0% { opacity: 1; } 15% { opacity: 0.1; } 30% { opacity: 0.9; } 45% { opacity: 0; } 60% { opacity: 0.7; } 100% { opacity: 0; } }

/* The view jolts in proportion to the share of max HP just lost */
#view-container.fx-shake { animation: fx-shake 360ms cubic-bezier(0.36, 0.07, 0.19, 0.97); }
@keyframes fx-shake {
  10%, 90%      { transform: translate(calc(var(--shake) * -0.3), 0); }
  20%, 80%      { transform: translate(calc(var(--shake) * 0.5), calc(var(--shake) * 0.2)); }
  30%, 50%, 70% { transform: translate(calc(var(--shake) * -1), calc(var(--shake) * -0.3)); }
  40%, 60%      { transform: translate(var(--shake), calc(var(--shake) * 0.3)); }
}

/* Floating numbers: red for damage taken, white for damage dealt, green for healing */
.fx-num {
  position: absolute;
  transform: translateX(-50%);
  font: bold 20px 'Courier New', monospace;
  text-shadow: 0 0 4px #000, 0 0 10px var(--fx);
  animation: fx-float 950ms ease-out forwards;
}
.fx-num.big  { font-size: 28px; }
.fx-num.hurt { color: #ff4040; }
.fx-num.hit  { color: #ffffff; }
.fx-num.heal { color: #50ff70; }
@keyframes fx-float {
  0%   { opacity: 0; transform: translate(-50%, 6px) scale(0.8); }
  15%  { opacity: 1; transform: translate(-50%, 0) scale(1.15); }
  100% { opacity: 0; transform: translate(-50%, -42px) scale(1); }
}

/* The monster recoils when hit (flaring in the spell's colour) and lunges when it attacks */
#monster-portrait.vanished svg { opacity: 0.08; transition: opacity 500ms ease; }
#monster-portrait.fx-recoil { animation: fx-recoil 300ms ease-out; }
#monster-portrait.fx-lunge  { animation: fx-lunge 320ms ease-in-out; }
@keyframes fx-recoil {
  0%   { transform: none; filter: none; }
  25%  { transform: translateY(-5px) scale(0.93); filter: brightness(2.2) drop-shadow(0 0 14px var(--fx)); }
  100% { transform: none; filter: none; }
}
@keyframes fx-lunge {
  0%   { transform: none; }
  45%  { transform: translateY(8px) scale(1.14); }
  100% { transform: none; }
}

/* Below a quarter HP: a red heartbeat around the view, and the HP readout blinks */
#view-container.fx-lowhp::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  box-shadow: inset 0 0 70px 10px rgba(255, 0, 0, 0.45);
  animation: fx-heartbeat 1.1s ease-in-out infinite;
}
@keyframes fx-heartbeat { 0%, 100% { opacity: 0.25; } 15% { opacity: 0.8; } 30% { opacity: 0.35; } 45% { opacity: 0.7; } }
#hp-display.crit { animation: fx-blink 1.1s steps(1) infinite; }
@keyframes fx-blink { 50% { opacity: 0.35; } }

/* Reduced motion: keep the colour cues, drop the movement */
@media (prefers-reduced-motion: reduce) {
  #view-container.fx-shake,
  #monster-portrait.fx-recoil,
  #monster-portrait.fx-lunge { animation: none; }
  .fx-num { animation: fx-fade 950ms forwards; }
  .fx-flash.fx-flicker { animation: fx-flash 420ms forwards; }
  #view-container.fx-lowhp::after { animation: none; opacity: 0.5; }
  #hp-display.crit { animation: none; }
}
@keyframes fx-fade { 0% { opacity: 1; } 100% { opacity: 0; } }

/* Messages */
#message-area {
  flex: 1;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--terminal-green-dim);
  padding: 8px 12px;
  min-height: 80px;
  max-height: 260px;
}

#messages {
  color: var(--terminal-green);
  white-space: pre-wrap;
  word-wrap: break-word;
  font-size: 13px;
  line-height: 1.5;
}
/* Messages from a few seconds ago, kept above the newest ones */
#messages .msg-current, #messages .msg-earlier { display: block; }
#messages .msg-earlier { opacity: 0.45; }
#messages .msg-earlier::after { content: ''; display: block; border-bottom: 1px dashed var(--terminal-green-dim); margin: 2px 0 4px; opacity: 0.6; }

/* Choices — same panel treatment as the controls bar below: this and
   #movement-controls occupy the same "control strip" slot (one has combat/
   interaction choices, the other has movement keys) and are never really
   both in use at once, so they share one visual language. */
#choices-area {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  border: 1px solid var(--terminal-green-dim);
  padding: 8px 12px;
}

/* While playing, movement is handled by #movement-controls and this area
   has no buttons at all — collapse it instead of showing an empty box. */
#choices-area:empty {
  border: none;
  padding: 0;
  min-height: 0;
}

/* Buttons are "active controls" — bright green text, dim structural border.
   Same primitive as .ctrl-btn below: square corners, no native button
   chrome, identical hover/press behavior. */
.choice-btn {
  appearance: none;
  background: var(--panel);
  border: 1px solid var(--terminal-green-dim);
  border-radius: 0;
  color: var(--terminal-green-bright);
  font-family: var(--font);
  font-size: 13px;
  padding: 4px 12px;
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}

.choice-btn:hover {
  background: var(--terminal-green-dim);
  color: var(--terminal-bg);
}

.choice-btn:active {
  background: var(--terminal-green-bright);
  color: var(--terminal-bg);
  border-color: var(--terminal-green-bright);
}

.choice-btn .key {
  color: var(--terminal-green-bright);
  font-weight: bold;
  margin-right: 4px;
}

/* Name input */
#name-input-area {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
}

#name-input-area .prompt { font-size: 22px; }

.prompt {
  color: var(--terminal-green);
}

#name-input {
  background: var(--panel);
  border: 1px solid var(--terminal-green);
  color: var(--terminal-green);
  font-family: var(--font);
  font-size: 22px;
  height: 48px;
  padding: 0 14px;
  outline: none;
  width: 360px;
  max-width: 100%;
  box-sizing: border-box;
  caret-color: var(--terminal-green);
}

#name-input:focus { box-shadow: 0 0 8px var(--terminal-green-dim); }

/* Settings panel: a small dialog over the game */
#settings-panel {
  position: fixed;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  min-width: 340px;
  background: var(--panel);
  border: 1px solid var(--terminal-green);
  box-shadow: 0 0 24px rgba(0, 255, 0, 0.15), 0 0 0 9999px rgba(0, 0, 0, 0.6);
  padding: 14px 18px;
  z-index: 50;
  font-size: 14px;
}
#settings-panel.hidden { display: none; }
#settings-title { color: var(--terminal-green-bright); margin-bottom: 10px; letter-spacing: 0.1em; }
#settings-rows button { display: flex; justify-content: space-between; gap: 24px; width: 100%; margin: 4px 0; text-align: left; }
#settings-rows .val-on { color: var(--terminal-green-bright); }
#settings-rows .val-off { color: var(--terminal-green-dim); }
.settings-hint { margin-top: 10px; color: var(--terminal-green-dim); font-size: 12px; }

/* Command bar while playing, with the optional on-screen arrows */
#movement-controls {
  display: flex;
  align-items: center;
  gap: 16px;
  justify-content: flex-start;
  flex-wrap: wrap;
  border: 1px solid var(--terminal-green-dim);
  padding: 8px 12px;
}

.dpad {
  display: grid;
  grid-template-columns: repeat(3, 52px);
  grid-template-rows: repeat(2, 44px);
  gap: 4px;
  flex-shrink: 0;
}
.dpad.hidden { display: none; }
.arrow-btn { font-size: 20px; }
.ctrl-btn.empty { border: none; background: transparent; cursor: default; }
/* On the map screen only the arrows show (when they're on). */
#movement-controls.map-walk .command-bar { display: none; }

.command-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  align-content: center;
}
/* Commands come in groups that wrap as a unit, with thin bars between */
.cmd-group { display: inline-flex; gap: 6px; flex-wrap: nowrap; }
.bar-sep {
  width: 1px;
  align-self: stretch;
  min-height: 22px;
  margin: 2px 4px;
  background: var(--terminal-green-dim);
  opacity: 0.6;
}

.ctrl-btn {
  appearance: none;
  background: var(--panel);
  border: 1px solid var(--terminal-green-dim);
  color: var(--terminal-green-bright);
  font-family: var(--font);
  font-size: 13px;
  cursor: pointer;
  padding: 2px 4px;
  min-width: 36px;
  height: 30px;
  border-radius: 0;
  transition: background 0.1s, color 0.1s;
}

.ctrl-btn:hover {
  background: var(--terminal-green-dim);
  color: var(--terminal-bg);
}

.ctrl-btn:active {
  background: var(--terminal-green-bright);
  color: var(--terminal-bg);
  border-color: var(--terminal-green-bright);
}

/* Help line */
#help-line {
  padding: 2px 0;
  border-top: 1px solid var(--terminal-green-dim);
  min-height: 20px;
}

#key-hint {
  color: var(--terminal-green-dim);
  font-size: 11px;
}

/* Utility */
.hidden { display: none !important; }

/* Scrollbar */
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: var(--terminal-bg); }
::-webkit-scrollbar-thumb { background: var(--terminal-green-dim); }

/* HP colors */
.hp-good { color: var(--terminal-green); }
.hp-warn { color: var(--terminal-amber); }
.hp-crit { color: var(--terminal-red); }

/* Minimap */
#messages.map-view {
  font-size: calc(11px * var(--map-zoom, 1));
  letter-spacing: 0;
  line-height: 1.2;
  color: var(--terminal-green-dim);
  /* The panel around it does the scrolling, in both directions at once, so
     a two-finger touchpad drag pans the map naturally. */
  white-space: pre;
  word-wrap: normal;
  width: max-content;
}

#message-area.map-mode {
  overflow: auto;
  min-height: 50vh;
  max-height: 70vh;
  user-select: none;
}
/* The hand only when there's somewhere to drag the map to */
#message-area.map-mode.pannable { cursor: grab; }
#message-area.map-mode.dragging { cursor: grabbing; }

/* Fixed title and legend around the scrolling map */
#map-header, #map-legend {
  margin: 0;
  padding: 4px 12px;
  background: var(--panel);
  color: var(--terminal-green);
  font-size: 13px;
  white-space: pre;
  overflow: hidden;
  text-overflow: ellipsis;
}
#map-header { border: 1px solid var(--terminal-green-dim); border-bottom: none; }
#map-legend { border: 1px solid var(--terminal-green-dim); border-top: none; color: var(--terminal-green-dim); white-space: pre-wrap; }

.choice-btn:disabled { opacity: 0.35; cursor: default; }

/* Whole-floor map: up to 80×60 cells, so shrink to fit the panel. */
#messages.map-view.map-full {
  font-size: calc(7px * var(--map-zoom, 1));
  line-height: 1.1;
}

/* Emphasis for important temporary messages (level-ups, big finds, etc.) */
.glow {
  color: var(--terminal-green-bright);
  text-shadow: 0 0 8px var(--terminal-green-bright);
}

.glow.amber {
  color: var(--terminal-amber);
  text-shadow: 0 0 8px var(--terminal-amber);
}

/* ── Asmodeus banished (victory screen) ─────────────────────────────────────
   He shakes, then shrinks to a spark, spinning, while a rift of hellfire
   opens behind him and drags the embers in; a flash, the rift snaps shut,
   and BANISHED burns in its place. Everything ends on its last frame. */
#banish-scene {
  position: relative;
  height: min(52vh, 420px);
  overflow: hidden;
  border: 1px solid #5a1208;
  background: radial-gradient(ellipse at 50% 50%, #2a0503 0%, #0b0101 55%, #000 80%);
  margin-bottom: 6px;
}
#banish-scene > * { position: absolute; left: 50%; top: 50%; pointer-events: none; }

#banish-scene .rift {
  width: 70%; aspect-ratio: 1; translate: -50% -50%;
  border-radius: 50%;
  background: conic-gradient(from 0deg, #000, #6e0b02, #ff5a12, #2a0000, #000, #9b1404, #ffb347, #300000, #000);
  filter: blur(6px);
  mask: radial-gradient(circle, #000 0 18%, rgba(0,0,0,0.85) 40%, transparent 70%);
  -webkit-mask: radial-gradient(circle, #000 0 18%, rgba(0,0,0,0.85) 40%, transparent 70%);
  animation: rift-open 6.2s ease-in-out forwards, rift-spin 1.6s linear infinite;
}
@keyframes rift-open {
  0%   { scale: 0;    opacity: 0; }
  20%  { scale: 0.7;  opacity: 0.9; }
  60%  { scale: 1.05; opacity: 1; }
  78%  { scale: 1.1;  opacity: 1; }
  86%  { scale: 0;    opacity: 0.9; }
  100% { scale: 0;    opacity: 0; }
}
@keyframes rift-spin { to { rotate: 360deg; } }

#banish-scene .rift-ring {
  width: 30%; aspect-ratio: 1; translate: -50% -50%;
  border-radius: 50%;
  box-shadow: 0 0 40px 10px #ff4a0f, inset 0 0 30px 6px #ff7a1a;
  animation: ring-life 6.2s ease-in-out forwards;
}
@keyframes ring-life {
  0%   { scale: 0;   opacity: 0; }
  25%  { scale: 1;   opacity: 0.8; }
  78%  { scale: 1.4; opacity: 1; }
  86%  { scale: 0.05; opacity: 1; }
  100% { scale: 0.12; opacity: 0.35; }   /* a faint scar where the rift closed */
}

#banish-scene .embers { width: 100%; height: 100%; left: 0; top: 0; animation: embers-out 6.2s linear forwards; }
#banish-scene .embers i {
  position: absolute; left: 50%; top: 50%; width: 5px; height: 5px; border-radius: 50%;
  background: #ffb347; box-shadow: 0 0 8px 2px #ff5a12;
  transform: rotate(var(--a)) translateX(var(--r));
  animation: ember-in 1.3s ease-in var(--d) infinite;
}
@keyframes ember-in {
  from { transform: rotate(var(--a)) translateX(calc(var(--r) * 2)); opacity: 0; }
  20%  { opacity: 1; }
  to   { transform: rotate(calc(var(--a) + 160deg)) translateX(0); opacity: 0; }
}
@keyframes embers-out { 0%, 80% { opacity: 1; } 86%, 100% { opacity: 0; } }

#banish-scene .shrinking-lord {
  height: 92%; aspect-ratio: 1; translate: -50% -50%;
  transform-origin: 50% 50%;
  animation: lord-banish 6.2s cubic-bezier(.55,0,.75,.4) forwards;
}
#banish-scene .shrinking-lord svg { width: 100%; height: 100%; }
@keyframes lord-banish {
  0%   { scale: 1;    rotate: 0deg;   filter: drop-shadow(0 0 0 #f00); opacity: 1; translate: -50% -50%; }
  4%   { translate: -52% -50%; }
  8%   { translate: -48% -51%; }
  12%  { translate: -51% -49%; }
  16%  { scale: 1;    rotate: 0deg;   filter: drop-shadow(0 0 18px #ff2a00) brightness(1.3); translate: -50% -50%; }
  45%  { scale: 0.45; rotate: 220deg; filter: drop-shadow(0 0 22px #ff5a12) brightness(1.6) hue-rotate(-15deg); }
  70%  { scale: 0.06; rotate: 620deg; filter: drop-shadow(0 0 30px #ffb347) brightness(2.6); opacity: 1; }
  78%  { scale: 0.01; rotate: 760deg; opacity: 0.9; }
  80%, 100% { scale: 0; opacity: 0; }
}

#banish-scene .banish-flash {
  width: 100%; height: 100%; left: 0; top: 0;
  background: radial-gradient(circle at 50% 50%, #fff 0%, #ffd9a0 20%, transparent 60%);
  opacity: 0;
  animation: banish-flash 6.2s linear forwards;
}
@keyframes banish-flash { 0%, 80% { opacity: 0; } 83% { opacity: 1; } 100% { opacity: 0; } }

#banish-scene .banish-title, #banish-scene .banish-sub {
  translate: -50% -50%; white-space: nowrap; text-align: center; opacity: 0;
  font-family: inherit; color: #ff5a1f; text-transform: uppercase;
}
#banish-scene .banish-title {
  font-size: clamp(28px, 7vw, 64px); letter-spacing: 0.35em; font-weight: bold;
  text-shadow: 0 0 12px #ff2a00, 0 0 30px #a00, 0 0 2px #fff;
  animation: title-in 1.6s ease-out 5.4s forwards, title-burn 2.4s ease-in-out 7s infinite;
}
#banish-scene .banish-sub {
  top: 66%; font-size: clamp(11px, 1.8vw, 15px); letter-spacing: 0.25em; color: #d9a07a;
  animation: title-in 1.6s ease-out 6.4s forwards;
}
@keyframes title-in { from { opacity: 0; scale: 1.4; filter: blur(8px); } to { opacity: 1; scale: 1; filter: none; } }
@keyframes title-burn { 50% { text-shadow: 0 0 18px #ff4a0f, 0 0 46px #c00, 0 0 2px #fff; } }

@media (prefers-reduced-motion: reduce) {
  #banish-scene * { animation-duration: 0.01s !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; }
}

/* ── Asmodeus triumphant (before the death screen) ──────────────────────────
   Out of the dark he rises over you, huge, glowing, shaking with laughter,
   while hellfire climbs from below; YOU HAVE FALLEN burns in. It holds on
   the last frame, still laughing, until the player continues. */
#banish-scene.scene-triumph {
  background: radial-gradient(ellipse at 50% 100%, #4a0802 0%, #160201 50%, #000 80%);
}
#banish-scene .hell-glow {
  width: 100%; height: 100%; left: 0; top: 0; translate: none;
  background: radial-gradient(ellipse at 50% 85%, rgba(255, 70, 10, 0.55) 0%, rgba(120, 0, 0, 0.25) 40%, transparent 70%);
  opacity: 0;
  animation: glow-in 3s ease-in forwards, glow-throb 1.8s ease-in-out 3s infinite;
}
@keyframes glow-in { to { opacity: 1; } }
@keyframes glow-throb { 50% { opacity: 0.7; } }

#banish-scene .rising-lord {
  height: 100%; aspect-ratio: 1; left: 50%; top: 0; translate: -50% 0;
  transform-origin: 50% 100%;
  animation: lord-rise 3.2s cubic-bezier(.2,.7,.3,1) forwards;
}
#banish-scene .rising-lord svg { width: 100%; height: 100%; }
@keyframes lord-rise {
  0%   { scale: 0.35; translate: -50% 60%; opacity: 0; filter: brightness(0.2); }
  35%  { opacity: 1; }
  100% { scale: 1;    translate: -50% 3%;  opacity: 1; filter: brightness(1.15) drop-shadow(0 0 22px #ff2a00); }
}
/* His laughter: a heaving shake that never stops. */
#banish-scene .laugh { width: 100%; height: 100%; animation: laugh 0.42s ease-in-out 3.2s infinite; }
@keyframes laugh {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  25% { transform: translateY(-1.5%) rotate(-0.6deg); }
  50% { transform: translateY(0.6%) rotate(0.4deg); }
  75% { transform: translateY(-1%) rotate(0.6deg); }
}

#banish-scene .hellfire { width: 100%; height: 100%; left: 0; top: 0; translate: none; }
#banish-scene .hellfire i {
  position: absolute; bottom: -10%; left: var(--x); width: 18%; height: var(--h);
  translate: -50% 0; transform-origin: 50% 100%;
  background: radial-gradient(ellipse at 50% 100%, #fff3b0 0%, #ffb020 18%, #ff4a0a 42%, rgba(160, 10, 0, 0.6) 65%, transparent 75%);
  filter: blur(3px);
  mix-blend-mode: screen;
  scale: 1 0;
  animation: flame-climb 2.6s ease-out var(--d) forwards, flame-flicker 0.5s ease-in-out calc(var(--d) + 2.6s) infinite alternate;
}
@keyframes flame-climb { to { scale: 1 1; } }
@keyframes flame-flicker { from { scale: 1 0.9; } to { scale: 1.05 1.12; } }

#banish-scene .triumph-title, #banish-scene .triumph-sub {
  translate: -50% -50%; white-space: nowrap; text-align: center; opacity: 0; font-family: inherit;
}
#banish-scene .triumph-title {
  top: 78%; font-size: clamp(24px, 6vw, 54px); letter-spacing: 0.3em; font-weight: bold; color: #ffd0a0;
  text-shadow: 0 0 10px #ff2a00, 0 0 28px #a00, 0 2px 0 #300;
  animation: title-in 1.4s ease-out 3.4s forwards, title-burn 2.4s ease-in-out 4.8s infinite;
}
#banish-scene .triumph-sub {
  top: 91%; font-size: clamp(11px, 1.8vw, 15px); letter-spacing: 0.12em; color: #ffe2c8; font-style: italic;
  background: rgba(0, 0, 0, 0.72); padding: 3px 12px; border-radius: 3px;
  text-shadow: 0 0 6px #000;
  animation: title-in 1.4s ease-out 4.4s forwards;
}

/* Hover help for the control panel (shown after a second's hover). */
#tooltip {
  position: fixed; z-index: 1000; max-width: 280px; pointer-events: none;
  padding: 7px 10px; border: 1px solid var(--terminal-green-dim, #2a6b2a); border-radius: 3px;
  background: rgba(4, 16, 4, 0.96); color: #c8f5c8; font-size: 12px; line-height: 1.4;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.6), 0 0 8px rgba(80, 255, 80, 0.12);
  animation: tip-in 140ms ease-out;
}
#tooltip[hidden] { display: none; }
@keyframes tip-in { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
