/* Kurt and the Stolen Sun: page shell, canvas scaling and touch controls. */
:root {
  --bg: #07040b;
  --ink: #ffe6c8;
  --panel: rgba(28, 18, 40, 0.55);
  --panel-on: rgba(255, 211, 90, 0.45);
  --edge: rgba(255, 230, 200, 0.35);
  --focus: #ffd35a;
  --pad: 144px;
  --btn: 58px;
  --btn-big: 76px;
  --knob: 54px;
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font: 600 14px/1.3 system-ui, sans-serif;
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

#app {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  touch-action: none;
}

#stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

#screen {
  display: block;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  background: #0b0810;
  outline: none;
  touch-action: none;
}

#screen:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* ---------- Boot and error ---------- */
#boot {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--bg);
  z-index: 10;
  transition: opacity 0.2s ease-out;
}

#boot.done {
  opacity: 0;
  pointer-events: none;
}

#boot[hidden],
#touch[hidden] {
  display: none !important;
}

.boot-card {
  max-width: 28rem;
  padding: 1.5rem;
  text-align: center;
}

.boot-title {
  font-size: 1.4rem;
  letter-spacing: 0.04em;
  color: #ffd35a;
}

.boot-msg {
  margin-top: 0.6rem;
  color: #d8c8e0;
}

.boot-note {
  margin-top: 0.4rem;
  font-size: 0.8rem;
  color: #8a7a96;
}

#boot.error .boot-msg {
  color: #ff9aa0;
}

/* ---------- Touch controls: overlay at the sides in landscape ---------- */
#touch {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}

#touch > * {
  pointer-events: auto;
}

.tc-pad {
  position: absolute;
  left: calc(14px + env(safe-area-inset-left));
  bottom: calc(14px + env(safe-area-inset-bottom));
  width: var(--pad);
  height: var(--pad);
  border-radius: 50%;
  background: var(--panel);
  border: 2px solid var(--edge);
  touch-action: none;
}

.tc-arrow {
  position: absolute;
  width: 0;
  height: 0;
  border: 9px solid transparent;
  opacity: 0.55;
}

.tc-arrow.up {
  left: calc(50% - 9px);
  top: 8px;
  border-bottom-color: var(--ink);
}

.tc-arrow.down {
  left: calc(50% - 9px);
  bottom: 8px;
  border-top-color: var(--ink);
}

.tc-arrow.left {
  top: calc(50% - 9px);
  left: 8px;
  border-right-color: var(--ink);
}

.tc-arrow.right {
  top: calc(50% - 9px);
  right: 8px;
  border-left-color: var(--ink);
}

.tc-pad.on-up .tc-arrow.up,
.tc-pad.on-down .tc-arrow.down,
.tc-pad.on-left .tc-arrow.left,
.tc-pad.on-right .tc-arrow.right {
  opacity: 1;
  filter: drop-shadow(0 0 4px var(--focus));
}

.tc-knob {
  position: absolute;
  left: calc(50% - var(--knob) / 2);
  top: calc(50% - var(--knob) / 2);
  width: var(--knob);
  height: var(--knob);
  border-radius: 50%;
  background: rgba(255, 230, 200, 0.22);
  border: 2px solid rgba(255, 230, 200, 0.5);
  pointer-events: none;
}

.tc-actions {
  position: absolute;
  right: calc(12px + env(safe-area-inset-right));
  bottom: calc(12px + env(safe-area-inset-bottom));
  display: grid;
  grid-template-columns: repeat(3, var(--btn));
  grid-template-areas:
    "purr zoom talk"
    "claw pounce jump";
  gap: 8px;
  align-items: end;
  touch-action: none;
}

.tc-system {
  position: absolute;
  right: calc(10px + env(safe-area-inset-right));
  top: calc(10px + env(safe-area-inset-top));
  display: flex;
  gap: 8px;
  touch-action: none;
}

.tc-btn {
  width: var(--btn);
  height: var(--btn);
  padding: 0;
  border-radius: 50%;
  border: 2px solid var(--edge);
  background: var(--panel);
  color: var(--ink);
  font: 700 11px/1 system-ui, sans-serif;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  touch-action: none;
  cursor: pointer;
  transition: transform 90ms cubic-bezier(0.22, 1, 0.36, 1), background-color 120ms;
}

.tc-jump {
  grid-area: jump;
}

.tc-claw {
  grid-area: claw;
}

.tc-pounce {
  grid-area: pounce;
}

.tc-zoom {
  grid-area: zoom;
}

.tc-purr {
  grid-area: purr;
}

.tc-talk {
  grid-area: talk;
}

.tc-btn.big {
  width: var(--btn-big);
  height: var(--btn-big);
  margin: calc((var(--btn) - var(--btn-big)) / 2);
  font-size: 13px;
  border-color: rgba(255, 211, 90, 0.6);
}

.tc-system .tc-btn {
  width: 52px;
  height: 44px;
  border-radius: 10px;
}

.tc-btn.on {
  transform: scale(0.94);
  background: var(--panel-on);
  border-color: var(--focus);
}

.tc-btn.locked {
  opacity: 0.3;
}

.tc-talk {
  opacity: 0.55;
}

.tc-talk.hint {
  opacity: 1;
  border-color: var(--focus);
  box-shadow: 0 0 10px rgba(255, 211, 90, 0.55);
}

/* ---------- Portrait: game on top, controls below ---------- */
@media (orientation: portrait) {
  .has-touch-ui #stage {
    flex: 0 0 auto;
    height: min(62dvh, 92vw);
    padding-bottom: 0;
  }

  .has-touch-ui #touch {
    position: relative;
    inset: auto;
    flex: 1 1 auto;
    min-height: 220px;
    border-top: 1px solid rgba(255, 230, 200, 0.08);
    background: radial-gradient(120% 90% at 50% 0%, #1a1024 0%, var(--bg) 70%);
  }

  .has-touch-ui .tc-system {
    top: 10px;
  }

  .has-touch-ui .tc-pad {
    bottom: calc(24px + env(safe-area-inset-bottom));
  }

  .has-touch-ui .tc-actions {
    bottom: calc(22px + env(safe-area-inset-bottom));
  }
}

/* Narrow phones: slightly smaller buttons so both clusters fit side by side. */
@media (max-width: 380px) {
  :root {
    --pad: 128px;
    --btn: 54px;
    --btn-big: 68px;
  }

  .tc-actions {
    gap: 6px;
  }

  /* Keeps long labels like POUNCE inside the smaller circles. */
  .tc-btn {
    font-size: 10px;
    letter-spacing: 0;
  }
}

/* Very narrow phones (320 px and below): smaller still, so the pad (and the 16 px slop around it that
   catches a sliding thumb) stays clear of Purr and Claw. Buttons stay at or above 44 px. */
@media (max-width: 340px) {
  :root {
    --pad: 112px;
    --btn: 48px;
    --btn-big: 60px;
    --knob: 44px;
  }

  .tc-btn {
    font-size: 9px;
  }
}

@media (max-width: 300px) {
  :root {
    --pad: 96px;
    --btn: 44px;
    --btn-big: 54px;
    --knob: 36px;
  }
}

/* Short landscape phones: keep the overlay compact. */
@media (orientation: landscape) and (max-height: 420px) {
  :root {
    --pad: 128px;
    --btn: 54px;
    --btn-big: 66px;
  }

  .tc-btn {
    background: rgba(28, 18, 40, 0.4);
    font-size: 10px;
    letter-spacing: 0;
  }
}

/* Site achievement toasts sit bottom right by default, over the dialogue box and, on touch, right on JUMP.
   Here they go top right (html raises specificity over the injected progression.css). With touch controls
   they move again (portrait: in the free band under the game, below Map/Pause; landscape: compact, in the
   gap between pad and buttons, since dialogue uses the top there, or at the top while a hint box fills that
   gap) and let taps fall through so play never stalls. */
html .prog-toast-container {
  top: max(16px, env(safe-area-inset-top, 0px));
  bottom: auto;
}

.has-touch-ui .prog-toast {
  pointer-events: none;
}

@media (orientation: portrait) {
  /* The stage is min(62dvh, 92vw) tall; Map/Pause take the next 54 px. */
  .has-touch-ui .prog-toast-container {
    top: calc(min(62dvh, 92vw) + 62px);
    bottom: auto;
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: min(340px, calc(100vw - 24px));
    max-width: none;
  }
}

/* Short portrait phones: the band over the pad only fits a compact toast. */
@media (orientation: portrait) and (max-height: 700px) {
  .has-touch-ui .prog-toast {
    gap: 8px;
    padding: 6px 10px;
  }

  .has-touch-ui .prog-toast__label {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .has-touch-ui .prog-toast__icon {
    width: 28px;
    height: 28px;
    font-size: 15px;
    border-radius: 8px;
  }

  .has-touch-ui .prog-toast__sub {
    display: none;
  }
}

@media (orientation: landscape) {
  .has-touch-ui .prog-toast-container {
    top: auto;
    bottom: calc(8px + env(safe-area-inset-bottom));
    left: calc(26px + var(--pad) + env(safe-area-inset-left));
    right: calc(28px + 3 * var(--btn) + env(safe-area-inset-right));
    max-width: none;
    align-items: center;
  }

  .has-touch-ui .prog-toast {
    width: 100%;
    max-width: 340px;
    gap: 8px;
    padding: 6px 10px;
  }

  .has-touch-ui .prog-toast__label {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .has-touch-ui .prog-toast__icon {
    width: 28px;
    height: 28px;
    font-size: 15px;
    border-radius: 8px;
  }

  .has-touch-ui .prog-toast__sub {
    display: none;
  }

  /* A hint box is in the bottom gap (game.js sets the class): the toast waits at the top instead. */
  html.hint-low .prog-toast-container {
    top: calc(8px + env(safe-area-inset-top));
    bottom: auto;
  }
}

/* Short windows: a full toast would reach the area title card, so it goes compact (label, title, XP). */
@media (max-height: 500px) {
  html .prog-toast {
    gap: 8px;
    padding: 6px 10px;
  }

  html .prog-toast__label {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  html .prog-toast__icon {
    width: 28px;
    height: 28px;
    font-size: 15px;
    border-radius: 8px;
  }

  html .prog-toast__sub {
    display: none;
  }
}

/* The ending's dialogue sits at the top of the screen, so its toasts go to the bottom (game.js sets the class).
   Touch layouts already keep them off it, and the bottom there is the pad. */
html.dialogue-top:not(.has-touch-ui) .prog-toast-container {
  top: auto;
  bottom: max(16px, env(safe-area-inset-bottom, 0px));
}

/* The smallest landscape phones: the gap only fits the title, so the XP badge goes. */
@media (orientation: landscape) and (max-width: 640px) {
  .has-touch-ui .prog-toast__xp {
    display: none;
  }
}

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