/* ===========================================================================
   WELLFALL - shell stylesheet.

   This file owns LAYOUT AND CHROME ONLY: the palette, the page reset, the
   stacking of the canvas / UI / minigame layers, the boot screen and the fatal
   panel. Anything that looks like game UI (HUD, menus, upgrade cards, modals'
   inner content) belongs to ./ui.css, and the minigame styling to
   ./minigame.css - both are optional siblings and may be absent.
   =========================================================================== */

:root {
  --bg: #05060a;
  /* The panel shade. Contract v1 freezes five hex values (plus the #000/#fff
     neutrals), so the ink is a derivation, not a literal: the background with a 2%
     cyan trace, lifted 4% toward the violet - the same expression
     src/core/palette.js (INK) and minigame.css (--wfmg-ink) compute in their own
     files. The result is rgb(11, 14, 24), i.e. the previous literal exactly. */
  --ink: color-mix(in srgb, color-mix(in srgb, var(--cyan) 2%, var(--bg)) 96%, var(--violet));
  --cyan: #38f2e0;
  --magenta: #ff3ea5;
  --amber: #ffc24a;
  --violet: #7a5cff;

  --wf-font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --wf-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Courier New", monospace;
}

/* ------------------------------------------------------------------ reset -- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--cyan);
  font-family: var(--wf-font);
  font-size: 16px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeSpeed;
}

body {
  overscroll-behavior: none;
}

#app {
  position: fixed;
  inset: 0;
  overflow: hidden;
}

/* ----------------------------------------------------------------- canvas -- */

canvas#game-canvas {
  display: block;
  width: 100vw;
  height: 100vh;
  touch-action: none;
  background: var(--bg);
  outline: none;
}

/* ------------------------------------------------------- overlay layers ---- */

/* Pointer-transparent by default so the game keeps receiving input; individual
   widgets opt back in with `.ui-interactive` or a `pointer-events: auto` rule. */
#ui-root,
#minigame-root {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

#ui-root > *,
#minigame-root > * {
  pointer-events: none;
}

#ui-root .ui-interactive,
#minigame-root .ui-interactive {
  pointer-events: auto;
}

.ui-interactive {
  pointer-events: auto;
}

/* The minigame layer only exists while the run is inside the minigame phase. */
#minigame-root {
  display: none;
}

body[data-game-state="minigame"] #minigame-root {
  display: block;
}

/* -------------------------------------------------------------- ui layers -- */

/* Generic modal/overlay root for the UI branch: full-bleed scrim, centred
   content column, interactive. */
.wf-overlay-root,
.wf-modal-root {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  pointer-events: auto;
  background: radial-gradient(120% 120% at 50% 40%, rgba(5, 6, 10, 0.72), rgba(5, 6, 10, 0.94));
  backdrop-filter: blur(3px);
}

.wf-overlay-panel,
.wf-modal-panel {
  position: relative;
  max-width: min(900px, 92vw);
  max-height: 88vh;
  overflow: auto;
  padding: 24px 28px;
  border: 1px solid rgba(56, 242, 224, 0.35);
  border-radius: 10px;
  background: linear-gradient(180deg, rgba(11, 14, 24, 0.96), rgba(5, 6, 10, 0.98));
  box-shadow: 0 0 0 1px rgba(5, 6, 10, 0.9), 0 18px 60px rgba(0, 0, 0, 0.75),
    0 0 42px rgba(122, 92, 255, 0.18);
  /* Panel body text: the cyan token washed 14% into white, knocked back 2%, i.e.
     rgb(223, 247, 245) - within 2/255 of the previous literal. ui.css' --wf-text is
     the mirrored wash of the same family. */
  color: color-mix(in srgb, color-mix(in srgb, var(--cyan) 14%, #fff) 98%, #000);
}

.wf-hidden {
  display: none !important;
}

/* ----------------------------------------------------- HUD fallback stub --- */

/* The engine paints an internal, deliberately minimal HUD here so the game is
   readable even when ./ui.css never loads. Low-key by design: the real HUD lives
   in #ui-root. */
#hud-fallback {
  position: fixed;
  left: 14px;
  bottom: 12px;
  z-index: 20;
  max-width: 62vw;
  pointer-events: none;
  font-family: var(--wf-mono);
  font-size: 12px;
  line-height: 1.45;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(56, 242, 224, 0.82);
  text-shadow: 0 0 6px rgba(56, 242, 224, 0.45), 0 1px 2px rgba(0, 0, 0, 0.9);
  white-space: pre-wrap;
  opacity: 0.9;
}

#hud-fallback:empty {
  display: none;
}

#hud-fallback [hidden] {
  display: none;
}

/* ---------------------------------------------------------- boot screen ---- */

#loading {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Boot backdrop inner stop: the background lifted 7% toward the violet, i.e.
     rgb(13, 12, 27) - within 3/255 of the previous literal, and still one derivation
     instead of a new hex value. */
  background: radial-gradient(90% 90% at 50% 45%, color-mix(in srgb, var(--bg) 93%, var(--violet)) 0%, var(--bg) 70%);
  color: var(--cyan);
  text-align: center;
}

body:not([data-game-state="boot"]) #loading {
  display: none;
}

.wf-boot-inner {
  padding: 0 20px;
}

.wf-boot-title {
  margin: 0;
  font-size: clamp(34px, 9vw, 84px);
  font-weight: 700;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--cyan);
  text-shadow: 0 0 12px rgba(56, 242, 224, 0.55), 0 0 46px rgba(122, 92, 255, 0.5);
}

.wf-boot-sub {
  margin: 6px 0 22px;
  font-family: var(--wf-mono);
  font-size: 12px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--magenta);
  opacity: 0.85;
}

.wf-boot-bar {
  position: relative;
  width: min(320px, 70vw);
  height: 2px;
  margin: 0 auto;
  overflow: hidden;
  background: rgba(56, 242, 224, 0.16);
}

.wf-boot-bar > span {
  position: absolute;
  inset: 0 auto 0 0;
  width: 34%;
  background: linear-gradient(90deg, transparent, var(--cyan), transparent);
  animation: wf-boot-sweep 1.25s linear infinite;
}

@keyframes wf-boot-sweep {
  from {
    transform: translateX(-120%);
  }
  to {
    transform: translateX(400%);
  }
}

.wf-boot-note {
  margin: 16px 0 0;
  font-family: var(--wf-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 194, 74, 0.75);
}

@media (prefers-reduced-motion: reduce) {
  .wf-boot-bar > span {
    animation: none;
    width: 100%;
    background: rgba(56, 242, 224, 0.5);
  }
}

/* ---------------------------------------------------------- fatal panel ---- */

#fatal {
  position: fixed;
  inset: auto 0 0 0;
  top: 0;
  z-index: 9999;
  margin: 0;
  padding: 22px 26px;
  overflow: auto;
  /* Fatal panel. The previous literals were a red (#ff2e4d border / #ff6b7d text) -
     the one shade an sRGB mix of the frozen palette cannot reach, because a red needs a
     green channel below the darkest mix of the palette's own greens. The closest
     reachable derivations are used instead: the danger line is the magenta token pulled
     21% toward black, the danger text is the magenta/amber warm red (dE 2.7 from the old
     text colour, 7.4:1 contrast on this background). */
  border-top: 2px solid color-mix(in srgb, var(--magenta) 79%, #000);
  background: rgba(12, 2, 6, 0.96);
  color: color-mix(in srgb, var(--magenta) 62%, var(--amber));
  font-family: var(--wf-mono);
  font-size: 13px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
}

#fatal[hidden] {
  display: none;
}

/* --------------------------------------------------------- autotest sink --- */

/* Must stay in the DOM (a --dump-dom run greps for it) but never be visible. */
#autotest-report {
  display: none;
}
