/* ===========================================================================
   Hueward — HUD & overlay layer.
   Art direction: ink-wash on paper (GAME_DESIGN.md §7). Torn-paper tags, ink
   drops, brushed edges, lantern lamps. Every node in here is built by
   src/ui.js under <div id="hud">; this file only dresses it.

   Sizing: the HUD overlays a 960x540 internal-resolution canvas and must
   scale with it, so every dimension is expressed in `--u` (one internal
   pixel). ui.js keeps `--u` in sync with the mount's real width.
   =========================================================================== */

/* Zero-specificity defaults: if the page already positions #hud, its rules win. */
:where(#hud) {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

#hud {
  /* One internal (960x540) pixel, in CSS px. The page sets --ui-scale on the stage
     synchronously while fitting the letterbox, so the very first painted frame is
     already correct; ui.js then keeps an inline --u in step with the real width. */
  --u: calc(var(--ui-scale, 1) * 1px);

  /* Paper & ink */
  --paper: #ece6d6;
  --paper-hi: #f7f3ea;
  --paper-lo: #ded6c0;
  --ink: #15131a;
  --ink-soft: #3a3540;
  --wash: #6f6a72;
  --wash-lo: #b9b3b8;

  /* Hues (§7) */
  --blue: #2f7fe6;   --blue-d: #1b4fa0;   --blue-l: #8fc4ff;
  --red: #d8342b;    --red-d: #8f1d1b;    --red-l: #ff8a7a;
  --yellow: #f2c230; --yellow-d: #b88a12; --yellow-l: #fff2a8;
  --green: #3fae5a;  --green-d: #22703a;  --green-l: #a5f0b0;

  --serif: "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --mono: ui-monospace, Consolas, "SF Mono", Menlo, monospace;

  /* Torn-paper silhouettes */
  --torn-tag: polygon(
    0.8% 8%, 5% 1%, 19% 5%, 33% 0%, 48% 4%, 63% 0%, 79% 5%, 92% 1%, 99% 9%,
    96% 27%, 100% 46%, 97% 65%, 100% 84%, 93% 97%, 78% 100%, 62% 95%,
    46% 100%, 30% 96%, 15% 100%, 4% 94%, 2% 74%, 0% 55%, 3% 33%
  );
  --torn-band: polygon(
    0% 12%, 2% 0%, 12% 5%, 26% 1%, 40% 5%, 54% 1%, 68% 5%, 82% 1%, 96% 5%,
    100% 14%, 99% 50%, 100% 86%, 96% 99%, 82% 95%, 68% 99%, 54% 95%,
    40% 99%, 26% 95%, 12% 99%, 2% 100%, 0% 88%, 1% 50%
  );
  --torn-card: polygon(
    0.6% 4%, 4% 0.8%, 14% 3%, 26% 0.5%, 38% 3%, 50% 0%, 62% 3%, 74% 0.6%,
    86% 3%, 96% 0.8%, 99.4% 5%, 98% 18%, 100% 32%, 98.5% 46%, 100% 60%,
    98% 74%, 99.5% 88%, 96% 98%, 86% 99.5%, 74% 97%, 62% 100%, 50% 97.5%,
    38% 100%, 26% 97%, 14% 99.5%, 4% 98%, 0.6% 92%, 2% 78%, 0% 64%,
    1.5% 50%, 0% 36%, 2% 22%, 0.5% 10%
  );
  --torn-top: polygon(
    0% 15%, 4% 6%, 9% 13%, 14% 4%, 19% 12%, 25% 3%, 31% 11%, 37% 4%,
    43% 13%, 49% 5%, 55% 12%, 61% 3%, 67% 11%, 73% 5%, 79% 13%, 85% 4%,
    91% 12%, 96% 5%, 100% 13%, 100% 100%, 0% 100%
  );

  font-family: var(--serif);
  color: var(--ink);
  pointer-events: none;               /* gameplay input must reach the canvas */
  user-select: none;
  -webkit-user-select: none;
  -webkit-font-smoothing: antialiased;
  z-index: 5;
}

/* The `hidden` attribute must always beat the display rules below (§7). */
#hud[hidden],
#hud [hidden] { display: none !important; }

/* --------------------------------------------------------------------- */
/* Shared paper surfaces                                                  */
/* --------------------------------------------------------------------- */

.hw-paper {
  background-color: var(--paper);
  background-image:
    repeating-linear-gradient(93deg, rgba(21, 19, 26, 0.035) 0 1px, rgba(0, 0, 0, 0) 1px 4px),
    repeating-linear-gradient(2deg, rgba(21, 19, 26, 0.022) 0 1px, rgba(0, 0, 0, 0) 1px 6px),
    radial-gradient(130% 150% at 18% 0%, #f7f2e4 0%, #ece5d2 55%, #dcd4bd 100%);
  color: var(--ink);
  /* Two shadows: a tight ink halo that hugs the torn silhouette (so the tag has a
     visible edge over pale sky as well as dark cave), then depth underneath. */
  filter:
    drop-shadow(0 0 calc(1.2 * var(--u)) rgba(21, 19, 26, 0.85))
    drop-shadow(0 calc(2 * var(--u)) calc(5 * var(--u)) rgba(12, 10, 16, 0.5));
}

.hw-tag {
  position: absolute;
  clip-path: var(--torn-tag);
  padding: calc(9 * var(--u)) calc(15 * var(--u)) calc(10 * var(--u));
}

.hw-label {
  font-family: var(--mono);
  font-size: calc(11 * var(--u));
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------- */
/* Hearts — ink drops, top-left                                           */
/* --------------------------------------------------------------------- */

.hw-hearts {
  left: calc(14 * var(--u));
  top: calc(12 * var(--u));
  transform: rotate(-0.7deg);
}

.hw-hearts .hw-drops {
  display: flex;
  gap: calc(4 * var(--u));
  margin-top: calc(3 * var(--u));
}

.hw-drop {
  width: calc(20 * var(--u));
  height: calc(24 * var(--u));
  display: block;
}

.hw-drop .fillpath { fill: var(--ink); stroke: var(--ink); stroke-width: 1.2; }
.hw-drop .shine { fill: rgba(247, 243, 234, 0.55); }

.hw-drop.is-empty .fillpath {
  fill: none;
  stroke: var(--wash);
  stroke-width: 1.6;
  stroke-dasharray: 3 2.6;
}
.hw-drop.is-empty .shine { display: none; }

.hw-drop.is-last {
  animation: hw-lastbeat 1.4s ease-in-out infinite;
  transform-origin: 50% 60%;
}

@keyframes hw-lastbeat {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.13); }
}

/* --------------------------------------------------------------------- */
/* Score tag — top-right                                                  */
/* --------------------------------------------------------------------- */

.hw-score {
  right: calc(14 * var(--u));
  top: calc(12 * var(--u));
  min-width: calc(126 * var(--u));
  text-align: right;
  transform: rotate(0.6deg);
}

.hw-score-value {
  font-size: calc(31 * var(--u));
  line-height: 1.02;
  font-weight: 600;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
}

.hw-score-sub {
  margin-top: calc(3 * var(--u));
  font-family: var(--mono);
  font-size: calc(12 * var(--u));
  color: var(--ink-soft);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
}

.hw-muted {
  position: absolute;
  left: calc(16 * var(--u));
  top: calc(78 * var(--u));
  font-family: var(--mono);
  font-size: calc(11 * var(--u));
  letter-spacing: 0.2em;
  color: var(--paper-hi);
  background: rgba(21, 19, 26, 0.82);
  padding: calc(3 * var(--u)) calc(8 * var(--u));
  border-radius: calc(2 * var(--u));
}

/* --------------------------------------------------------------------- */
/* Region name — top-centre, fades in on entry                            */
/* --------------------------------------------------------------------- */

.hw-region {
  position: absolute;
  left: 50%;
  top: calc(16 * var(--u));
  transform: translate(-50%, calc(-8 * var(--u)));
  text-align: center;
  opacity: 0;
  transition: opacity 0.55s ease, transform 0.55s ease;
}

.hw-region.is-in {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* Sits over both the pale sky and the dark caves, so it carries its own ground:
   near-opaque ink with paper type is ~8:1 over the worst-case light background and
   better over dark. Blurred shadows alone were ~1:1 against pale paper. */
.hw-region-name {
  display: inline-block;
  font-size: calc(19 * var(--u));
  letter-spacing: 0.19em;
  text-indent: 0.19em;
  text-transform: uppercase;
  color: var(--paper-hi);
  background: rgba(21, 19, 26, 0.92);
  padding: calc(4 * var(--u)) calc(14 * var(--u)) calc(5 * var(--u));
  box-shadow: 0 calc(2 * var(--u)) calc(6 * var(--u)) rgba(12, 10, 16, 0.5);
}

.hw-region-rule {
  height: calc(2 * var(--u));
  margin: calc(4 * var(--u)) auto 0;
  width: 52%;
  background: linear-gradient(90deg,
    rgba(236, 230, 214, 0) 0%,
    rgba(236, 230, 214, 0.85) 30%,
    rgba(236, 230, 214, 0.85) 70%,
    rgba(236, 230, 214, 0) 100%);
  filter: drop-shadow(0 calc(1 * var(--u)) 0 rgba(12, 10, 16, 0.8));
}

/* --------------------------------------------------------------------- */
/* Palette — four lantern lamps, bottom-centre                            */
/* --------------------------------------------------------------------- */

/* The rack is a torn-paper plaque, like the hearts and score tags. Without it the
   lantern ironwork is ink over whatever the world happens to be, which disappears
   entirely against near-black stone. With it, all three states read on a constant
   ground everywhere in the map. */
.hw-palette {
  position: absolute;
  left: 50%;
  bottom: calc(44 * var(--u));
  transform: translateX(-50%);
  display: flex;
  gap: calc(12 * var(--u));
  align-items: flex-end;
  padding: calc(8 * var(--u)) calc(16 * var(--u)) calc(9 * var(--u));
  clip-path: var(--torn-band);
}

.hw-lamp {
  position: relative;
  width: calc(54 * var(--u));
  padding: calc(4 * var(--u)) 0 0;
  text-align: center;
  cursor: pointer;
  pointer-events: auto;                 /* the one HUD element that takes clicks */
  transition: transform 0.18s ease;
}

.hw-lamp.hue-b { --hue: var(--blue);   --hue-d: var(--blue-d);   --hue-l: var(--blue-l); }
.hw-lamp.hue-r { --hue: var(--red);    --hue-d: var(--red-d);    --hue-l: var(--red-l); }
.hw-lamp.hue-y { --hue: var(--yellow); --hue-d: var(--yellow-d); --hue-l: var(--yellow-l); }
.hw-lamp.hue-g { --hue: var(--green);  --hue-d: var(--green-d);  --hue-l: var(--green-l); }

.hw-lamp.is-locked { cursor: default; }
.hw-lamp.is-owned:hover { transform: translateY(calc(-2 * var(--u))); }
.hw-lamp.is-lit { transform: translateY(calc(-4 * var(--u))); }

.hw-lamp-halo {
  position: absolute;
  left: 50%;
  top: calc(16 * var(--u));
  width: calc(88 * var(--u));
  height: calc(88 * var(--u));
  margin: calc(-44 * var(--u)) 0 0 calc(-44 * var(--u));
  border-radius: 50%;
  background: radial-gradient(circle, var(--hue-l) 0%, var(--hue) 26%, rgba(0, 0, 0, 0) 68%);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.hw-lamp.is-lit .hw-lamp-halo {
  opacity: 0.5;
  animation: hw-halo 1.9s ease-in-out infinite;
}

@keyframes hw-halo {
  0%, 100% { opacity: 0.38; transform: scale(0.94); }
  50%      { opacity: 0.58; transform: scale(1.06); }
}

.hw-lamp-svg {
  position: relative;
  display: block;
  width: calc(40 * var(--u));
  height: calc(52 * var(--u));
  margin: 0 auto;
  overflow: visible;
}

/* ------------------------------------------------------------------------
   Three states, ONE silhouette. Every part is drawn in every state; only the
   fill, the outline and the glow change:

     locked  hollow ghosted ink, dashed, no colour  -> "absent, go find it"
     owned   solid ink linework, hue in the glass,
             no flame and no halo                   -> "present, but dark"
     lit     the same, glass bright, flame + halo    -> "burning"

   Locked vs owned is a hollow/solid difference, not an opacity difference, so
   the two are separable at a glance in the first minutes of the game.
   ------------------------------------------------------------------------ */

/* --- base state = LOCKED: outline only, nothing filled, no hue anywhere --- */
.hw-l-ring,
.hw-l-iron {
  fill: none;
  stroke: var(--wash);
  stroke-width: 1.9;
  stroke-dasharray: 3.4 2.8;
  stroke-linejoin: round;
}
.hw-l-hook {
  fill: none;
  stroke: var(--wash);
  stroke-width: 2;
  stroke-dasharray: 3.4 2.8;
  stroke-linecap: round;
}
.hw-l-glass {
  fill: none;
  stroke: var(--wash);
  stroke-width: 2.2;
  stroke-dasharray: 4.5 3.5;
  stroke-linejoin: round;
}
.hw-l-rib {
  stroke: var(--wash);
  stroke-width: 1.2;
  stroke-dasharray: 3 3;
  opacity: 0.5;
}
.hw-l-shade { fill: rgba(21, 19, 26, 0.28); opacity: 0; }
.hw-l-shine { fill: none; opacity: 0; }
.hw-l-flame { fill: var(--hue-l); opacity: 0; transform-origin: 50% 70%; }
.hw-l-lock {
  fill: var(--wash);
  font-family: var(--serif);
  font-size: 15px;
  font-weight: 700;
  text-anchor: middle;
}
.hw-lamp.is-locked { opacity: 0.82; }
.hw-lamp.is-locked .hw-lamp-svg { filter: none; }

/* --- OWNED and LIT share the full ink linework --- */
.hw-lamp.is-owned .hw-l-ring,
.hw-lamp.is-lit   .hw-l-ring,
.hw-lamp.is-owned .hw-l-iron,
.hw-lamp.is-lit   .hw-l-iron {
  fill: var(--ink);
  stroke: var(--ink);
  stroke-width: 1.5;
  stroke-dasharray: none;
}
.hw-lamp.is-owned .hw-l-hook,
.hw-lamp.is-lit   .hw-l-hook {
  stroke: var(--ink);
  stroke-width: 2.2;
  stroke-dasharray: none;
}
.hw-lamp.is-owned .hw-l-rib,
.hw-lamp.is-lit   .hw-l-rib {
  stroke: rgba(247, 243, 234, 0.55);
  stroke-width: 1.3;
  stroke-dasharray: none;
  opacity: 0.85;
}
.hw-lamp.is-owned .hw-l-shine,
.hw-lamp.is-lit   .hw-l-shine {
  fill: rgba(247, 243, 234, 0.4);
  opacity: 1;
}
.hw-lamp.is-owned .hw-l-glass,
.hw-lamp.is-lit   .hw-l-glass {
  stroke: var(--ink);
  stroke-width: 2.2;
  stroke-dasharray: none;
}

/* --- OWNED: hue in the glass, but the wick is out --- */
.hw-lamp.is-owned .hw-l-glass { fill: var(--hue-d); }
/* An unlit glass is the hue in shadow: it darkens the paler hues (Yellow reaches
   ~4:1 on paper instead of ~2.5:1) and reads as "cold" beside the lit lamp. */
.hw-lamp.is-owned .hw-l-shade { opacity: 1; }
.hw-lamp.is-owned .hw-l-flame { opacity: 0; }   /* no flame when unlit */

/* --- LIT: bright glass, flame, halo --- */
.hw-lamp.is-lit .hw-l-glass { fill: var(--hue); }
.hw-lamp.is-lit .hw-lamp-svg {
  filter: drop-shadow(0 0 calc(3 * var(--u)) var(--hue-l));
}
.hw-lamp.is-lit .hw-l-flame {
  opacity: 1;
  animation: hw-flame 1.5s ease-in-out infinite;
}

@keyframes hw-flame {
  0%, 100% { transform: scaleY(0.9); opacity: 0.85; }
  50%      { transform: scaleY(1.1); opacity: 1; }
}

.hw-lamp.is-owned .hw-l-lock,
.hw-lamp.is-lit   .hw-l-lock { display: none; }

.hw-lamp-foot {
  margin-top: calc(2 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(4 * var(--u));
}

.hw-lamp-key {
  font-family: var(--mono);
  font-size: calc(11 * var(--u));
  font-weight: 700;
  line-height: 1;
  color: var(--paper-hi);
  background: rgba(21, 19, 26, 0.9);
  padding: calc(3 * var(--u)) calc(5 * var(--u));
  border-radius: calc(2 * var(--u));
}

/* On the plaque the ground is known, so plain ink type reads at ~15:1. */
.hw-lamp-name {
  font-family: var(--mono);
  font-size: calc(10.5 * var(--u));
  letter-spacing: 0.08em;
  line-height: 1;
  color: var(--ink);
}

.hw-lamp.is-locked .hw-lamp-name { color: var(--wash); }
.hw-lamp.is-locked .hw-lamp-key { opacity: 0.62; }
.hw-lamp.is-lit .hw-lamp-name { font-weight: 700; }

/* --------------------------------------------------------------------- */
/* Control strip — permanent, along the bottom                            */
/* --------------------------------------------------------------------- */

.hw-strip {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: calc(36 * var(--u));
  padding-top: calc(6 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: nowrap;
  gap: calc(9 * var(--u));
  background:
    linear-gradient(180deg, rgba(21, 19, 26, 0.86) 0%, rgba(21, 19, 26, 0.96) 100%);
  clip-path: var(--torn-top);
}

.hw-ctl {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  gap: calc(4 * var(--u));
  font-family: var(--mono);
  font-size: calc(12 * var(--u));
  letter-spacing: 0.04em;
  color: #e6dfcd;
  white-space: nowrap;
}

.hw-ctl b {
  font-weight: 700;
  color: var(--ink);
  background: var(--paper-hi);
  padding: calc(2 * var(--u)) calc(5 * var(--u));
  border-radius: calc(2 * var(--u));
  font-size: calc(11.5 * var(--u));
  line-height: 1.25;
}

.hw-ctl b.hw-ctl-btn {
  pointer-events: auto;
  cursor: pointer;
}

.hw-ctl b.hw-ctl-btn:hover {
  background: #fff;
  box-shadow: 0 0 0 calc(1.5 * var(--u)) rgba(247, 243, 234, 0.55);
}

.hw-ctl-sep {
  width: calc(1 * var(--u));
  height: calc(13 * var(--u));
  background: rgba(230, 223, 205, 0.28);
}

/* --------------------------------------------------------------------- */
/* Coach card — top-right, non-blocking (§8, engine rule C)               */
/* --------------------------------------------------------------------- */

.hw-coach {
  position: absolute;
  right: calc(18 * var(--u));
  top: calc(132 * var(--u));       /* clear of the score tag (ends ~94u) by ~38u */
  width: calc(292 * var(--u));
  padding: calc(14 * var(--u)) calc(18 * var(--u)) calc(16 * var(--u));
  clip-path: var(--torn-card);
  transform: rotate(-0.9deg);      /* counter to the score tag's +0.6deg */
  transition: opacity 0.35s ease;
}

.hw-coach-title {
  font-size: calc(26 * var(--u));
  letter-spacing: 0.16em;
  line-height: 1.1;
}

.hw-coach-rule {
  height: calc(2 * var(--u));
  margin: calc(6 * var(--u)) 0 calc(8 * var(--u));
  background: linear-gradient(90deg, var(--ink) 0%, rgba(21, 19, 26, 0.15) 100%);
}

.hw-coach-obj {
  font-size: calc(14.5 * var(--u));
  line-height: 1.35;
  margin-bottom: calc(9 * var(--u));
}

.hw-coach-legend {
  display: flex;
  flex-wrap: wrap;
  gap: calc(5 * var(--u)) calc(8 * var(--u));
  margin-bottom: calc(9 * var(--u));
}

.hw-chip {
  display: flex;
  align-items: center;
  gap: calc(4 * var(--u));
  font-family: var(--mono);
  font-size: calc(11 * var(--u));
  letter-spacing: 0.06em;
  color: var(--ink);
}

.hw-chip i {
  display: block;
  width: calc(11 * var(--u));
  height: calc(11 * var(--u));
  border-radius: 50%;
  border: calc(1.5 * var(--u)) solid var(--ink);
  background: var(--chip, var(--wash));
}

.hw-coach-keys {
  font-family: var(--mono);
  font-size: calc(11.5 * var(--u));
  line-height: 1.5;
  color: var(--ink-soft);
}

.hw-coach-skip {
  margin-top: calc(8 * var(--u));
  font-family: var(--mono);
  font-size: calc(11 * var(--u));
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--wash);
}

/* --------------------------------------------------------------------- */
/* Banner — colour-core teaching (§8)                                     */
/* --------------------------------------------------------------------- */

/* The container is pure geometry and must NEVER paint: while no message is up it
   holds no card at all and is `hidden` besides, so nothing cream sits over the
   playfield. All paper styling lives on .hw-banner-card. Because the container is
   absolutely positioned and fixed-size, adding or removing the card shifts nothing. */
.hw-banner {
  position: absolute;
  left: 50%;
  bottom: calc(118 * var(--u));
  width: calc(600 * var(--u));
  margin-left: calc(-300 * var(--u));
  display: flex;
  justify-content: center;
  background: none;
  border: 0;
  box-shadow: none;
  filter: none;
  clip-path: none;
  padding: 0;
}

.hw-banner-card {
  width: 100%;
  padding: calc(13 * var(--u)) calc(24 * var(--u)) calc(14 * var(--u));
  clip-path: var(--torn-band);
  text-align: center;
  border-left: calc(6 * var(--u)) solid var(--accent, var(--ink));
  opacity: 0;
  transform: translateY(calc(10 * var(--u))) scale(0.98);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.hw-banner-card.is-in {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.hw-banner-text {
  color: var(--ink);
  font-size: calc(17 * var(--u));
  line-height: 1.34;
  letter-spacing: 0.015em;
}

/* The hue name stays INK (15:1 on paper). Saturated Yellow on paper is ~1.4:1 and
   Red ~3.8:1 — unreadable as body type — so the colour identity moves to an
   underline, which also keeps the meaning from resting on colour alone. */
.hw-banner-text .hw-hue-word {
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--ink);
  border-bottom: calc(3 * var(--u)) solid var(--accent, var(--ink));
  padding-bottom: calc(1 * var(--u));
}

/* --------------------------------------------------------------------- */
/* Toasts — situational hints, bottom-left                                */
/* --------------------------------------------------------------------- */

/* Same rule as the banner: the stack is geometry only. Empty -> no children and
   `hidden`, so it cannot leave a blank tag on screen. */
.hw-toasts {
  position: absolute;
  left: calc(14 * var(--u));
  bottom: calc(46 * var(--u));
  width: calc(320 * var(--u));
  display: flex;
  flex-direction: column-reverse;
  gap: calc(7 * var(--u));
  background: none;
  border: 0;
  box-shadow: none;
  filter: none;
  clip-path: none;
  padding: 0;
}

.hw-toast {
  /* A toast is text the player MUST read, over unpredictable background values, so it
     is fully opaque warm paper with ink text (15:1) — never a translucent wash. */
  padding: calc(8 * var(--u)) calc(12 * var(--u)) calc(9 * var(--u));
  border-left: calc(4 * var(--u)) solid var(--ink);
  clip-path: var(--torn-tag);
  color: var(--ink);
  font-size: calc(13.5 * var(--u));
  line-height: 1.32;
  opacity: 0;
  transform: translateX(calc(-12 * var(--u)));
  /* in fast, out slower: the readable state is reached almost immediately */
  transition: opacity 0.16s ease-out, transform 0.16s ease-out;
}

.hw-toast.is-in { opacity: 1; transform: translateX(0); }
.hw-toast.is-out {
  opacity: 0;
  transform: translateX(calc(-12 * var(--u)));
  transition: opacity 0.3s ease-in, transform 0.3s ease-in;
}

/* --------------------------------------------------------------------- */
/* Floaters — rising score pops                                           */
/* --------------------------------------------------------------------- */

.hw-floaters {
  position: absolute;
  inset: 0;
  background: none;
  border: 0;
  box-shadow: none;
  filter: none;
}

.hw-floater {
  position: absolute;
  font-family: var(--serif);
  font-size: calc(16 * var(--u));
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--paper-hi);
  /* A crisp 1px ink outline rather than a blur: legible on the pale paper ground and
     in the dark caves alike, where a soft glow only worked against one of them. */
  text-shadow:
    calc(1 * var(--u)) 0 0 var(--ink), calc(-1 * var(--u)) 0 0 var(--ink),
    0 calc(1 * var(--u)) 0 var(--ink), 0 calc(-1 * var(--u)) 0 var(--ink),
    calc(1 * var(--u)) calc(1 * var(--u)) 0 var(--ink),
    calc(-1 * var(--u)) calc(1 * var(--u)) 0 var(--ink),
    calc(1 * var(--u)) calc(-1 * var(--u)) 0 var(--ink),
    calc(-1 * var(--u)) calc(-1 * var(--u)) 0 var(--ink),
    0 calc(2 * var(--u)) calc(6 * var(--u)) rgba(12, 10, 16, 0.6);
  transform: translate(-50%, -50%);
  animation: hw-float 0.95s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
  white-space: nowrap;
}

/* Word pops (CHECKPOINT, ...) arrive at the player, i.e. at screen centre. Keep them
   small, plaque-style and lifted clear of the sprite so they inform without covering
   the thing the player is looking at. */
.hw-floater.is-label {
  font-family: var(--mono);
  font-size: calc(11 * var(--u));
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  text-transform: uppercase;
  color: var(--paper-hi);
  background: rgba(21, 19, 26, 0.92);
  padding: calc(3 * var(--u)) calc(9 * var(--u)) calc(4 * var(--u));
  text-shadow: none;
  margin-top: calc(-30 * var(--u));
}

@keyframes hw-float {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.7); }
  18%  { opacity: 1; transform: translate(-50%, calc(-50% - 7 * var(--u))) scale(1.1); }
  40%  { transform: translate(-50%, calc(-50% - 17 * var(--u))) scale(1); }
  100% { opacity: 0; transform: translate(-50%, calc(-50% - 44 * var(--u))) scale(0.96); }
}

/* --------------------------------------------------------------------- */
/* Pause overlay                                                          */
/* --------------------------------------------------------------------- */

.hw-pause {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(8 * var(--u));
  background:
    radial-gradient(120% 120% at 50% 45%, rgba(21, 19, 26, 0.42) 0%, rgba(21, 19, 26, 0.74) 100%);
}

.hw-pause-title {
  font-size: calc(56 * var(--u));
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  color: var(--paper-hi);
  text-shadow: 0 calc(3 * var(--u)) calc(10 * var(--u)) rgba(0, 0, 0, 0.9);
}

.hw-pause-sub {
  font-family: var(--mono);
  font-size: calc(14 * var(--u));
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #d8d1bf;
}

/* --------------------------------------------------------------------- */
/* End cards — GAME_OVER / VICTORY (§6)                                   */
/* --------------------------------------------------------------------- */

.hw-end {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;                 /* a click anywhere restarts */
  cursor: pointer;
  background:
    radial-gradient(110% 110% at 50% 45%, rgba(21, 19, 26, 0.55) 0%, rgba(12, 10, 16, 0.88) 100%);
  animation: hw-fadein 0.4s ease both;
}

@keyframes hw-fadein { from { opacity: 0; } to { opacity: 1; } }

.hw-card {
  position: relative;
  width: calc(520 * var(--u));
  padding: calc(24 * var(--u)) calc(34 * var(--u)) calc(22 * var(--u));
  clip-path: var(--torn-card);
  text-align: center;
  animation: hw-cardin 0.45s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes hw-cardin {
  from { transform: translateY(calc(16 * var(--u))) scale(0.97); }
  to   { transform: translateY(0) scale(1); }
}

.hw-card-eyebrow {
  font-family: var(--mono);
  font-size: calc(11 * var(--u));
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  text-transform: uppercase;
  color: var(--wash);
}

.hw-card-title {
  font-size: calc(38 * var(--u));
  line-height: 1.1;
  letter-spacing: 0.09em;
  margin-top: calc(2 * var(--u));
}

.hw-end.is-victory .hw-card-title {
  background: linear-gradient(90deg, var(--blue-d), var(--green-d) 34%, var(--yellow-d) 66%, var(--red-d));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hw-card-rule {
  height: calc(2 * var(--u));
  margin: calc(10 * var(--u)) auto calc(12 * var(--u));
  width: 72%;
  background: linear-gradient(90deg,
    rgba(21, 19, 26, 0) 0%, rgba(21, 19, 26, 0.85) 22%,
    rgba(21, 19, 26, 0.85) 78%, rgba(21, 19, 26, 0) 100%);
}

.hw-card-score {
  font-size: calc(52 * var(--u));
  line-height: 1;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.hw-card-scorelabel {
  font-family: var(--mono);
  font-size: calc(11 * var(--u));
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: calc(2 * var(--u));
}

.hw-best {
  margin: calc(9 * var(--u)) auto 0;
  display: inline-block;
  font-family: var(--mono);
  font-size: calc(12 * var(--u));
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--paper-hi);
  background: var(--ink);
  padding: calc(4 * var(--u)) calc(12 * var(--u));
  transform: rotate(-1.4deg);
}

.hw-hues {
  display: flex;
  justify-content: center;
  gap: calc(9 * var(--u));
  margin: calc(14 * var(--u)) 0 calc(4 * var(--u));
}

.hw-hue {
  width: calc(30 * var(--u));
  height: calc(30 * var(--u));
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: calc(13 * var(--u));
  font-weight: 700;
  color: var(--wash);
  border: calc(2 * var(--u)) dashed var(--wash);
  background: rgba(0, 0, 0, 0);
}

.hw-hue.is-found {
  color: var(--paper-hi);
  border: calc(2 * var(--u)) solid var(--ink);
  background: var(--chip);
  box-shadow: 0 0 calc(10 * var(--u)) var(--chip);
  text-shadow: 0 calc(1 * var(--u)) calc(2 * var(--u)) rgba(12, 10, 16, 0.8);
}

.hw-stats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: calc(6 * var(--u)) calc(8 * var(--u));
  margin-top: calc(14 * var(--u));
}

.hw-stat { text-align: center; }

.hw-stat-k {
  font-family: var(--mono);
  font-size: calc(10.5 * var(--u));
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--wash);
}

.hw-stat-v {
  font-size: calc(21 * var(--u));
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.hw-card-prompt {
  margin-top: calc(16 * var(--u));
  font-family: var(--mono);
  font-size: calc(13 * var(--u));
  letter-spacing: 0.13em;
  color: var(--ink);
  animation: hw-breathe 2.2s ease-in-out infinite;
}

.hw-card-prompt b {
  background: var(--ink);
  color: var(--paper-hi);
  padding: calc(2 * var(--u)) calc(6 * var(--u));
  border-radius: calc(2 * var(--u));
  font-weight: 700;
}

@keyframes hw-breathe {
  0%, 100% { opacity: 0.62; }
  50%      { opacity: 1; }
}

/* --------------------------------------------------------------------- */
/* Reduced motion — kill the decorative loops, keep every state legible.   */
/* --------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  #hud *,
  #hud *::before,
  #hud *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
  .hw-lamp.is-lit .hw-lamp-halo { opacity: 0.5; }
  .hw-lamp.is-lit .hw-l-flame { opacity: 1; }
  .hw-card-prompt { opacity: 1; }
  /* Floaters carry information (score), not decoration — keep them readable. */
  .hw-floater { animation-duration: 0.95s !important; }
}
