/* Game shell UI. Deliberately restrained -- the world is the thing you look at,
   so chrome stays dark, thin, and out of the way. */

:root {
  --ui-bg: rgba(10, 13, 12, 0.82);
  --ui-edge: rgba(190, 205, 190, 0.16);
  --ui-text: #e8ece6;
  --ui-dim: #97a394;
  --health: #c8433c;
  --food: #b0863a;
  --water: #3f86b8;
  --breath: #6fcbd4;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #05070a;
  color: var(--ui-text);
  /* The game reads raw key codes; text selection would only get in the way. */
  user-select: none;
  -webkit-user-select: none;
}

#viewport {
  display: block;
  width: 100vw;
  height: 100vh;
  cursor: crosshair;
}

/* ---- Full-screen veils (boot, click-to-play) ---- */

.veil {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: radial-gradient(ellipse at 50% 40%, #16211c 0%, #05070a 70%);
  z-index: 20;
  transition: opacity 0.35s ease;
}

.veil[hidden] { display: none; }
.veil.fading { opacity: 0; pointer-events: none; }

/* Click-to-play sits over the live world rather than hiding it -- you see where
   you're about to spawn, and it reads far better than a dead loading screen. */
#lock-veil {
  background: linear-gradient(to bottom, rgba(5, 7, 10, 0.15), rgba(5, 7, 10, 0.5));
  backdrop-filter: blur(2px);
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.9);
  /* Purely decorative: clicks must fall through to the game beneath it. */
  pointer-events: none;
  cursor: pointer;
}

.veil-inner { text-align: center; max-width: 34rem; padding: 2rem; }

.veil h1 {
  margin: 0 0 0.6rem;
  font-size: clamp(2rem, 6vw, 3.2rem);
  font-weight: 600;
  letter-spacing: 0.06em;
}

.veil-hint {
  margin: 0 0 2rem;
  color: var(--ui-dim);
  font-size: 1.05rem;
  letter-spacing: 0.04em;
}

.veil-keys {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--ui-dim);
  font-size: 0.85rem;
}

.veil-keys li { display: flex; align-items: center; gap: 0.35rem; }

kbd {
  display: inline-block;
  min-width: 1.7em;
  padding: 0.15em 0.45em;
  border: 1px solid var(--ui-edge);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--ui-text);
  font: inherit;
  font-size: 0.8em;
  text-align: center;
}

/* ---- HUD ---- */

#hud {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 10;
}

#hud[hidden] { display: none; }

/* Survival bars sit at the top of the screen, per the design. */
#bars {
  position: absolute;
  top: 1.1rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.85rem;
}

.bar {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.55rem 0.3rem 0.4rem;
  background: var(--ui-bg);
  border: 1px solid var(--ui-edge);
  border-radius: 999px;
}

.bar-glyph { font-size: 0.8rem; line-height: 1; filter: saturate(0.85); }

.bar-track {
  width: 8.5rem;
  height: 0.5rem;
  background: rgba(0, 0, 0, 0.55);
  border-radius: 999px;
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  width: 100%;
  border-radius: 999px;
  /* Width is set every time the rounded value changes; the transition keeps
     that stepping from looking chunky. */
  transition: width 0.25s linear, background-color 0.3s ease;
}

.bar[data-stat="health"] .bar-fill { background: var(--health); }
.bar[data-stat="food"]   .bar-fill { background: var(--food); }
.bar[data-stat="water"]  .bar-fill { background: var(--water); }
.bar[data-stat="breath"] .bar-fill { background: var(--breath); }

.bar[hidden] { display: none; }

.bar.critical { animation: bar-pulse 1.1s ease-in-out infinite; }

@keyframes bar-pulse {
  0%, 100% { border-color: var(--ui-edge); }
  50%      { border-color: rgba(200, 67, 60, 0.9); }
}

/* ---- Interaction prompt ---- */

#prompt {
  position: absolute;
  left: 50%;
  /* Stacked clear of the radio, which is itself clear of the slot bar. */
  bottom: 14rem;
  transform: translateX(-50%);
  padding: 0.4rem 0.8rem;
  background: var(--ui-bg);
  border: 1px solid var(--ui-edge);
  border-radius: 6px;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

#prompt[hidden] { display: none; }

#prompt em { color: #d9a04f; font-style: normal; }

.prompt-keys {
  display: block;
  margin-top: 0.3rem;
  color: var(--ui-dim);
  font-size: 0.72rem;
}

.prompt-keys kbd { margin-right: 0.15rem; }

/* ---- Backpack summary ---- */

/* ---- Slot bar ----
   Oval slots along the bottom of the screen: a picture with its count under it.
   Empty slots are drawn too, because how much room is left is the thing you
   most need to see. */

#backpack {
  position: absolute;
  left: 50%;
  bottom: 1.1rem;
  transform: translateX(-50%);
  display: flex;
  gap: 0.45rem;
  padding: 0.4rem 0.5rem;
  background: var(--ui-bg);
  border: 1px solid var(--ui-edge);
  border-radius: 999px;
  /* Above the radio subtitle, which shares the bottom of the screen. */
  z-index: 2;
}

.slot {
  position: relative;
  width: 3.4rem;
  height: 3.9rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1rem;
  border-radius: 50% / 44%;
  background: rgba(20, 22, 20, 0.55);
  border: 1px solid var(--ui-edge);
}

.slot.empty { background: rgba(20, 22, 20, 0.28); border-style: dashed; }

.slot-icon {
  width: 1.7rem;
  height: 1.7rem;
  display: block;
}

.slot-count {
  font-size: 0.72rem;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: #e8e4d8;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9);
}

/* The number you press, sat in the corner of the oval. */
.slot-index {
  position: absolute;
  top: 0.12rem;
  left: 0.42rem;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1;
  color: #cfc9b6;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.95);
}

.slot.empty .slot-index { color: var(--ui-dim); }

.slot.selected {
  border-color: #e0c15a;
  background: rgba(62, 54, 26, 0.75);
}

.inv-slot .slot-index {
  top: 0.2rem;
  left: 0.5rem;
  font-size: 0.85rem;
}

/* ---- Backpack screen ---- */

/* The list of things you can make, inside the backpack screen. */

.inv-make {
  margin: 0.9rem 0 0.5rem !important;
}

.inv-recipes {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  max-height: 11rem;
  overflow-y: auto;
}

.inv-recipe {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.35rem 0.5rem;
  font: inherit;
  color: inherit;
  text-align: left;
  background: rgba(40, 44, 38, 0.9);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  cursor: pointer;
}

.inv-recipe:hover { background: rgba(64, 74, 56, 0.95); border-color: #9ad3a4; }
.inv-recipe .slot-icon { width: 1.5rem; height: 1.5rem; flex: none; }
.inv-recipe-text { display: flex; flex-direction: column; gap: 0.1rem; }
.inv-recipe-text strong { font-size: 0.85rem; font-weight: 600; }

.inv-recipe-cost {
  font-size: 0.72rem;
  color: var(--ui-dim);
}

#inventory {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(8, 10, 9, 0.62);
  z-index: 20;
  /* The HUD is pointer-events:none; this screen must take clicks back. */
  pointer-events: auto;
  /* The canvas underneath asks for a crosshair; a panel wants a real pointer. */
  cursor: default;
}

#inventory[hidden] { display: none; }

.inv-panel {
  display: flex;
  gap: 1.1rem;
  align-items: flex-start;
}

.inv-side {
  min-width: 17rem;
  padding: 1rem 1.1rem;
  background: var(--ui-bg);
  border: 1px solid var(--ui-edge);
  border-radius: 10px;
}

.inv-side h3 {
  margin: 0 0 0.7rem;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ui-dim);
}

.inv-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.4rem;
}

.inv-slot {
  position: relative;
  height: 3.9rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  border-radius: 50% / 42%;
  background: rgba(24, 26, 23, 0.75);
  border: 1px solid var(--ui-edge);
  cursor: pointer;
}

.inv-slot:hover:not(.empty) { border-color: #9ad3a4; }
.inv-slot.selected { border-color: #e0c15a; background: rgba(60, 52, 24, 0.8); }
.inv-slot.empty { cursor: default; border-style: dashed; opacity: 0.5; }
.inv-slot .slot-icon { width: 1.9rem; height: 1.9rem; }

.inv-status {
  margin: 0.75rem 0 0;
  font-size: 0.8rem;
  color: var(--ui-dim);
}

.inv-status.warn { color: #f0b48a; }

.inv-hint {
  margin: 0.75rem 0 0;
  font-size: 0.78rem;
  color: var(--ui-dim);
}

.inv-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.7rem;
}

.inv-actions button {
  flex: 1;
  padding: 0.4rem 0.5rem;
  font: inherit;
  font-size: 0.8rem;
  color: inherit;
  background: rgba(40, 44, 38, 0.9);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  cursor: pointer;
}

.inv-actions button:hover:not(:disabled) { background: rgba(58, 64, 52, 0.95); }
.inv-actions button:disabled { opacity: 0.45; cursor: default; }

/* ---- Blown sand ----
   A wash over everything, on top of the fog tint the world itself gets. Darker
   at the edges so it reads as air you are inside rather than a colour filter. */

#sandveil {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  /* A plain translucent wash, not a blend mode: the HUD is its own stacking
     context, so `mix-blend-mode: multiply` blended against the HUD's own empty
     background rather than the world behind it, and showed nothing at all. */
  background:
    radial-gradient(ellipse at center, rgba(206, 165, 84, 0.62) 0%, rgba(150, 110, 44, 0.92) 100%);
  transition: opacity 0.25s linear;
}

/* ---- Arrival captions ----
   The story of how you got here, over the opening camera move. Same panel
   language as the radio, centred and larger, because it is the only thing on
   screen at the time. */

#captions {
  position: absolute;
  left: 50%;
  /* Low, so the shot itself is the thing you are looking at. */
  bottom: 7%;
  transform: translateX(-50%);
  max-width: min(40rem, 84vw);
  text-align: center;
  pointer-events: none;
}

#captions[hidden] { display: none; }

/* Everything else gets out of the way while the arrival plays. */
.during-shot > *:not(#captions) {
  opacity: 0;
  transition: opacity 0.4s ease;
}

.caption-title {
  margin: 0 0 0.9rem;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #e9e4d4;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.95);
}

.caption-line {
  margin: 0.35rem 0;
  font-size: 1rem;
  line-height: 1.5;
  color: #cfc9b6;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.95);
  opacity: 0;
  transition: opacity 0.8s ease;
}

.caption-line.visible { opacity: 1; }

/* ---- Refusal notice ---- */

#notice {
  position: absolute;
  left: 50%;
  bottom: 30%;
  transform: translateX(-50%);
  padding: 0.45rem 0.9rem;
  background: var(--ui-bg);
  border: 1px solid rgba(200, 67, 60, 0.5);
  border-radius: 5px;
  color: #f0d8d6;
  font-size: 0.88rem;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.25s ease;
}

#notice.visible { opacity: 1; }

/* ---- Underwater tint ----
   Sells being submerged, and makes the breath bar's context obvious. */

#underwater {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s ease;
  background:
    radial-gradient(ellipse at center, rgba(28, 92, 110, 0.28) 30%, rgba(9, 42, 58, 0.72) 100%);
}

#underwater.active { opacity: 1; }

/* ---- Crosshair ---- */

#crosshair {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  height: 4px;
  margin: -2px 0 0 -2px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.65);
  box-shadow: 0 0 3px rgba(0, 0, 0, 0.9);
}

/* ---- Walkie-talkie subtitles ---- */

#radio {
  position: absolute;
  left: 50%;
  /* Clear of the slot bar, which owns the bottom of the screen. */
  bottom: 8.2rem;
  transform: translateX(-50%);
  max-width: min(46rem, 82vw);
  padding: 0.6rem 1rem 0.7rem;
  background: var(--ui-bg);
  border: 1px solid var(--ui-edge);
  border-left: 2px solid #7f9c6d;
  border-radius: 4px;
  text-align: left;
}

#radio[hidden] { display: none; }

.radio-speaker {
  margin-bottom: 0.2rem;
  color: #8fae7c;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.radio-text { font-size: 0.95rem; line-height: 1.45; }

/* ---- Main menu ---- */

#mainmenu {
  position: fixed;
  inset: 0;
  overflow-y: auto;
  display: grid;
  place-items: center;
  padding: 2rem 1rem;
  background: radial-gradient(ellipse at 50% 30%, #16211c 0%, #05070a 70%);
  z-index: 40;
  transition: opacity 0.3s ease;
}

#mainmenu.fading { opacity: 0; pointer-events: none; }

.menu-panel { width: min(34rem, 100%); }

.menu-panel h1 {
  margin: 0 0 0.3rem;
  font-size: clamp(1.9rem, 5vw, 2.8rem);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-align: center;
}

.menu-tagline {
  margin: 0 0 2.2rem;
  color: var(--ui-dim);
  font-size: 0.88rem;
  text-align: center;
}

.menu-section { margin-bottom: 2rem; }

.menu-section h2 {
  margin: 0 0 0.7rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--ui-edge);
  color: var(--ui-dim);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.menu-empty, .menu-note {
  margin: 0.6rem 0 0;
  color: var(--ui-dim);
  font-size: 0.8rem;
}

/* ---- World list ---- */

.world-list { display: flex; flex-direction: column; gap: 0.4rem; }

.world-row { display: flex; gap: 0.4rem; }

.world-play {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
  padding: 0.65rem 0.85rem;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  color: var(--ui-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.world-play:hover { background: rgba(255, 255, 255, 0.12); border-color: #7f9c6d; }

.world-name { font-size: 0.95rem; }
.world-meta { color: var(--ui-dim); font-size: 0.72rem; }

.world-rename {
  width: 2.4rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  color: var(--ui-dim);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.world-rename:hover { background: rgba(255, 255, 255, 0.12); color: var(--ui-text); }

.world-delete {
  width: 2.4rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  color: var(--ui-dim);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.world-delete:hover { background: rgba(200, 67, 60, 0.25); color: #f3d4d2; }

/* ---- Create world ---- */

.create-form { display: flex; flex-direction: column; gap: 0.7rem; }

.create-form label { display: flex; flex-direction: column; gap: 0.25rem; }

.create-form label span {
  color: var(--ui-dim);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
}

.create-form label em {
  color: #6b7568;
  font-style: normal;
  font-size: 0.9em;
}

.create-form input {
  padding: 0.55rem 0.7rem;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  color: var(--ui-text);
  font: inherit;
  font-size: 0.9rem;
}

.create-form input:focus { outline: none; border-color: #7f9c6d; }

.menu-check {
  flex-direction: row !important;
  align-items: center;
  gap: 0.5rem !important;
  cursor: pointer;
}

.menu-check input { width: 1rem; height: 1rem; accent-color: #c8433c; }
.menu-check span { color: var(--ui-text) !important; font-size: 0.9rem !important; }
.menu-hard { margin-top: -0.3rem; color: #c98a86; }

.create-form button {
  margin-top: 0.3rem;
  padding: 0.65rem 1rem;
  background: #3f5c37;
  border: 1px solid #7f9c6d;
  border-radius: 5px;
  color: var(--ui-text);
  font: inherit;
  font-size: 0.92rem;
  cursor: pointer;
  transition: background 0.15s ease;
}

.create-form button:hover { background: #4d7042; }

/* ---- Pause menu ---- */

#pause {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(5, 7, 10, 0.72);
  backdrop-filter: blur(3px);
  z-index: 25;
  /* The HUD is pointer-events:none; the menu must take clicks back. */
  pointer-events: auto;
  /* The canvas underneath asks for a crosshair; a menu wants a real pointer. */
  cursor: default;
}

#pause button { cursor: pointer; }

#pause[hidden] { display: none; }

.pause-panel {
  min-width: 22rem;
  padding: 1.6rem 2rem 1.4rem;
  background: var(--ui-bg);
  border: 1px solid var(--ui-edge);
  border-radius: 8px;
  text-align: center;
}

.pause-panel h2 {
  margin: 0 0 0.25rem;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.05em;
}

.pause-world {
  margin: 0 0 1.3rem;
  color: var(--ui-dim);
  font-size: 0.82rem;
}

.pause-buttons { display: flex; flex-direction: column; gap: 0.45rem; }

.pause-buttons button {
  padding: 0.55rem 1rem;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  color: var(--ui-text);
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background 0.15s ease;
}

.pause-buttons button:hover { background: rgba(255, 255, 255, 0.13); }

.pause-status {
  margin: 0.8rem 0 0;
  min-height: 1.1em;
  color: #8fae7c;
  font-size: 0.8rem;
}

.pause-keys {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.3rem 1rem;
  margin: 1.2rem 0 0;
  padding: 1rem 0 0;
  border-top: 1px solid var(--ui-edge);
  list-style: none;
  color: var(--ui-dim);
  font-size: 0.75rem;
  text-align: left;
}

.pause-keys li { display: flex; align-items: center; gap: 0.3rem; }

/* ---- Sleep fade ----
   Opacity is driven per-frame from the game loop, so no CSS transition here:
   the loop already eases it, and a transition would fight that. */

#sleepfade {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: #000;
  opacity: 0;
  z-index: 15;
}

/* ---- Recipe book ---- */

.recipe-book {
  max-height: 46vh;
  overflow-y: auto;
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--ui-edge);
  text-align: left;
}

.recipe-book[hidden] { display: none; }

.recipe-section {
  margin: 1rem 0 0.5rem;
  color: var(--ui-dim);
  font-size: 0.68rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.recipe-section:first-child { margin-top: 0; }

.recipe {
  padding: 0.45rem 0.6rem;
  margin-bottom: 0.3rem;
  background: rgba(255, 255, 255, 0.04);
  border-radius: 4px;
}

.recipe-name { font-size: 0.88rem; }
.recipe-cost { color: #8fae7c; font-size: 0.78rem; }
.recipe-hint { color: var(--ui-dim); font-size: 0.74rem; font-style: italic; }

/* ---- Death screen ---- */

#death {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: radial-gradient(ellipse at center, rgba(48, 8, 8, 0.55) 0%, rgba(4, 2, 2, 0.9) 75%);
  backdrop-filter: blur(4px);
  z-index: 26;
  pointer-events: auto;
  cursor: default;
}

#death[hidden] { display: none; }

.death-panel {
  min-width: 20rem;
  max-width: 26rem;
  padding: 2rem 2.2rem 1.8rem;
  background: rgba(12, 8, 8, 0.86);
  border: 1px solid rgba(200, 67, 60, 0.35);
  border-radius: 8px;
  text-align: center;
}

.death-panel h2 {
  margin: 0 0 0.4rem;
  color: #d9534f;
  font-size: clamp(2.2rem, 7vw, 3.2rem);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.death-sub {
  margin: 0 0 1.4rem;
  color: var(--ui-dim);
  font-size: 0.85rem;
}

.death-label {
  margin: 0 0 0.4rem;
  color: var(--ui-dim);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.death-loot {
  margin-bottom: 1.2rem;
  padding: 0.7rem 0.9rem;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  text-align: left;
}

.death-item {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.85rem;
  line-height: 1.6;
}

.death-item span:last-child { color: var(--ui-dim); font-variant-numeric: tabular-nums; }
.death-empty { margin: 0; color: var(--ui-dim); font-size: 0.85rem; }

.death-home {
  margin: 0 0 1.4rem;
  color: var(--ui-dim);
  font-size: 0.8rem;
  line-height: 1.5;
}

.death-respawn {
  width: 100%;
  padding: 0.7rem 1rem;
  background: #7a2f2b;
  border: 1px solid #c8433c;
  border-radius: 5px;
  color: #f6e7e6;
  font: inherit;
  font-size: 1rem;
  letter-spacing: 0.05em;
  cursor: pointer;
  transition: background 0.15s ease;
}

.death-respawn:hover { background: #943a35; }

/* ---- Autosave flash ---- */

#autosave {
  position: absolute;
  left: 1.1rem;
  bottom: 1.1rem;
  padding: 0.3rem 0.6rem;
  background: var(--ui-bg);
  border: 1px solid var(--ui-edge);
  border-radius: 4px;
  color: var(--ui-dim);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity 0.4s ease;
}

#autosave.visible { opacity: 1; }

/* ---- Debug overlay ---- */

#debug {
  position: fixed;
  top: 0;
  left: 0;
  margin: 0;
  padding: 0.6rem 0.9rem;
  max-height: 100vh;
  overflow: hidden;
  background: var(--ui-bg);
  border-right: 1px solid var(--ui-edge);
  border-bottom: 1px solid var(--ui-edge);
  color: #cfe3c8;
  font: 12px/1.45 ui-monospace, "SF Mono", Menlo, monospace;
  white-space: pre;
  pointer-events: none;
  z-index: 30;
}

#debug[hidden] { display: none; }

/* ---- Touchscreens -------------------------------------------------------
   Two problems, and they are separate. One: there is no keyboard, so the
   controls have to be on the glass. Two: a phone has about a third of the
   room a laptop has, so a HUD built for a laptop covers the game with itself.
   The `touch` and `phone` classes come from src/core/device.js. */

#touch {
  position: fixed;
  inset: 0;
  z-index: 12;
  /* The controls take taps; the gap between them is the view, and taps there
     have to reach the look handler underneath. */
  pointer-events: none;
  /* Clear of the notch and the home bar. */
  padding: calc(env(safe-area-inset-top) + 0.6rem) calc(env(safe-area-inset-right) + 0.8rem)
    calc(env(safe-area-inset-bottom) + 0.8rem) calc(env(safe-area-inset-left) + 0.8rem);
}

#touch[hidden] { display: none; }

.touch-button {
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Thumb-sized. Smaller than this and you press the wrong one in the dark. */
  width: 3.6rem;
  height: 3.6rem;
  padding: 0;
  font-size: 1.35rem;
  line-height: 1;
  color: var(--ui-text);
  background: rgba(10, 13, 12, 0.55);
  border: 1px solid var(--ui-edge);
  border-radius: 50%;
  /* No 300ms tap delay, no double-tap zoom, no text cursor, no blue flash. */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.touch-button.on {
  background: rgba(120, 170, 120, 0.5);
  border-color: rgba(220, 235, 220, 0.5);
}

/* The arrow keys, laid out as a cross where a left thumb rests. */
.touch-pad {
  position: absolute;
  left: calc(env(safe-area-inset-left) + 0.9rem);
  bottom: calc(env(safe-area-inset-bottom) + 1rem);
  display: grid;
  grid-template-columns: repeat(3, 3.6rem);
  grid-template-rows: repeat(3, 3.6rem);
  gap: 0.3rem;
}

.touch-pad .touch-up { grid-area: 1 / 2; }
.touch-pad .touch-left { grid-area: 2 / 1; }
.touch-pad .touch-right { grid-area: 2 / 3; }
.touch-pad .touch-down { grid-area: 3 / 2; }

/* Use, jump, collect and the pack, under the right thumb. */
.touch-actions {
  position: absolute;
  right: calc(env(safe-area-inset-right) + 0.9rem);
  bottom: calc(env(safe-area-inset-bottom) + 1rem);
  display: grid;
  grid-template-columns: repeat(2, 3.6rem);
  gap: 0.5rem;
  justify-items: end;
}

/* Build mode's own row: step through the pieces, turn one round, and leave.
   Only on screen while build mode is open -- and sat above the action buttons
   rather than beside them, because the right thumb is already there. */
.touch-buildbar {
  position: absolute;
  right: calc(env(safe-area-inset-right) + 0.9rem);
  /* Clear above the action buttons: three rows of them at 3.6rem plus gaps
     plus their own standoff, which is where the build row landed on top of
     JUMP the first time. */
  bottom: calc(env(safe-area-inset-bottom) + 13.4rem);
  display: none;
  gap: 0.5rem;
}

#touch.building .touch-buildbar { display: flex; }

/* A phone has no room for both. Build mode takes its pieces from its own row,
   not from the slot bar, so the slot bar is the one that gives way. */
html.phone.building #backpack { display: none; }

.touch-buildbar .touch-button {
  width: 3.2rem;
  height: 3.2rem;
}

/* The keyboard's odd jobs, out of the way along the top. */
.touch-extras {
  position: absolute;
  right: calc(env(safe-area-inset-right) + 0.9rem);
  top: calc(env(safe-area-inset-top) + 4.4rem);
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

.touch-extras .touch-button {
  width: 2.9rem;
  height: 2.9rem;
  font-size: 1.05rem;
}

/* A finger has no crosshair to aim, and nothing hovers. */
html.touch #crosshair { opacity: 0.35; }
html.touch #viewport { cursor: default; }

/* Nothing on a touchscreen should scroll, bounce, zoom on a double tap, or
   put a magnifier over the game. */
html.touch, html.touch body {
  overscroll-behavior: none;
  touch-action: none;
  -webkit-touch-callout: none;
}

/* ---- Small screens ----
   A phone is about a third of a laptop across. Everything the HUD draws has
   to come down to match, or the bars and the slot bar meet in the middle. */

html.phone {
  font-size: 13px;
}

html.phone .slot {
  width: 2.5rem;
  height: 2.9rem;
}

html.phone .slot-icon {
  width: 1.25rem;
  height: 1.25rem;
}

html.phone #backpack {
  gap: 0.25rem;
  padding: 0.3rem 0.35rem;
  /* Clear above the arrow keys rather than beside them: the pad is 3.6rem x 3
     plus its gaps and its 1rem of standoff, and a slot bar the width of seven
     slots has nowhere to go beside that on a screen this narrow. */
  bottom: calc(env(safe-area-inset-bottom) + 13.4rem);
}

html.phone #bars {
  top: calc(env(safe-area-inset-top) + 0.5rem);
  gap: 0.4rem;
}

html.phone .bar-track { width: 4.6rem; }

html.phone #prompt {
  /* Above the radio, which sits at 17.4rem and is about four high -- they
     landed on top of each other, and the prompt is the one you are reading
     while you are trying to do the thing it describes. */
  bottom: calc(env(safe-area-inset-bottom) + 22.2rem);
  font-size: 0.85rem;
}

html.phone #radio {
  left: 50%;
  transform: translateX(-50%);
  width: min(26rem, calc(100vw - 2rem));
  bottom: calc(env(safe-area-inset-bottom) + 17.4rem);
}

html.phone #captions { font-size: 0.9rem; }

html.phone .veil-keys { display: none; }

/* A phone held sideways has no vertical room at all: the arrow keys and the
   action buttons take the bottom, so the slot bar goes up beside the bars. */
html.short #backpack {
  bottom: auto;
  top: calc(env(safe-area-inset-top) + 3.2rem);
}

html.short #prompt,
html.short #radio {
  bottom: calc(env(safe-area-inset-bottom) + 5.6rem);
}

html.short .touch-extras {
  flex-direction: row;
  top: calc(env(safe-area-inset-top) + 0.5rem);
  right: calc(env(safe-area-inset-right) + 0.9rem);
}

/* Menus are tapped, not clicked: every target gets a finger's worth of room,
   and a long list has to be able to scroll on a short screen. The panels are
   named as they are actually named in the markup -- a rule for a class nobody
   uses is a rule that quietly does nothing. */
html.touch button {
  min-height: 2.9rem;
}

html.touch .menu-panel,
html.touch .pause-panel,
html.touch .death-panel,
html.touch .inv-panel {
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* A panel that scrolls has to be allowed to, inside a document that cannot. */
  touch-action: pan-y;
}

/* A word has to fit inside the same circle an arrow does. */
.touch-button.touch-word {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.touch-extras .touch-button.touch-word { font-size: 0.55rem; }

/* The slot bar is a row of buttons on a touchscreen: tapping one is how you
   change what is in your hand, since there are no number keys to press. */
html.touch #backpack { pointer-events: auto; }
html.touch .slot { touch-action: manipulation; }

/* ---- Mode picker ----
   Four cards on the create screen. Two of them are locked until the challenges
   say otherwise, and a locked card says what it costs rather than vanishing:
   something you cannot see is not something to work towards. */

.create-form .mode-picker {
  display: grid;
  gap: 0.5rem;
  margin: 0.2rem 0 0.9rem;
  padding: 0;
  border: 0;
}

.create-form .mode-picker legend {
  padding: 0;
  margin-bottom: 0.4rem;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ui-dim);
}

.create-form .mode-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.1rem 0.6rem;
  align-items: baseline;
  padding: 0.6rem 0.75rem;
  background: rgba(20, 22, 20, 0.42);
  border: 1px solid var(--ui-edge);
  border-radius: 0.7rem;
  cursor: pointer;
}

.create-form .mode-card input {
  /* `.create-form label` lays its labels out as a column and dims every span
     inside them -- and being a class plus a type it outranks a bare
     `.mode-card`, so the cards were flex columns with dim titles until every
     rule here was scoped to match it. */
  grid-column: 1;
  width: auto;
  padding: 0;
  background: none;
  border: 0;
  grid-row: 1 / -1;
  align-self: center;
  justify-self: center;
  margin: 0;
  accent-color: #7ab87a;
}

.create-form .mode-card .mode-name {
  grid-column: 2;
  font-size: 0.95rem;
  letter-spacing: 0;
  font-weight: 600;
  color: var(--ui-text);
}

.create-form .mode-card .mode-blurb {
  grid-column: 2;
  font-size: 0.82rem;
  line-height: 1.35;
  letter-spacing: 0;
  color: var(--ui-dim);
}

.create-form .mode-card:has(input:checked) {
  background: rgba(60, 90, 60, 0.35);
  border-color: rgba(160, 210, 160, 0.45);
}

.create-form .mode-card.locked {
  cursor: not-allowed;
  opacity: 0.55;
}

/* What it costs, and how far along you are. */
.create-form .mode-card .mode-locked {
  grid-column: 2;
  margin-top: 0.15rem;
  font-size: 0.76rem;
  letter-spacing: 0.05em;
  color: #d9a04f;
}

/* ---- Challenge mode ------------------------------------------------------
   The corner, top left: the one part of the HUD with nothing else in it. The
   bars are top centre, the slot bar is bottom centre, the radio is bottom
   left. Clear of a notch, because a phone in landscape puts one right there. */

#challenge {
  position: absolute;
  top: calc(env(safe-area-inset-top) + 1.1rem);
  left: calc(env(safe-area-inset-left) + 1.1rem);
  min-width: 10.5rem;
  max-width: 15rem;
  padding: 0.55rem 0.75rem 0.6rem;
  background: var(--ui-bg);
  border: 1px solid var(--ui-edge);
  border-left: 2px solid rgba(160, 200, 160, 0.5);
  border-radius: 6px;
}

#challenge[hidden] { display: none; }

.challenge-count {
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  color: var(--ui-dim);
}

.challenge-title {
  margin-top: 0.12rem;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.2;
}

.challenge-bar {
  height: 0.28rem;
  margin-top: 0.45rem;
  background: rgba(20, 22, 20, 0.75);
  border-radius: 999px;
  overflow: hidden;
}

.challenge-bar[hidden] { display: none; }

.challenge-bar i {
  display: block;
  height: 100%;
  width: 0;
  background: #7ab87a;
  border-radius: 999px;
  transition: width 0.25s ease-out;
}

.challenge-tally {
  margin-top: 0.2rem;
  font-size: 0.72rem;
  color: var(--ui-dim);
}

/* Seven marks: what you have spent, and what is left. */
.challenge-lives {
  margin-top: 0.3rem;
  font-size: 0.8rem;
  letter-spacing: 0.16em;
  color: #9b6f6c;
}

.challenge-lives.last { color: #d9605a; }

/* A pass or a failure lights the whole corner for a moment. */
#challenge.passed { border-left-color: #7ab87a; box-shadow: 0 0 0 1px rgba(122, 184, 122, 0.5); }
#challenge.failed { border-left-color: #c8433c; box-shadow: 0 0 0 1px rgba(200, 67, 60, 0.5); }

/* The card that names a challenge as it starts. The radio's language, because
   that is the voice the game already explains itself in. */
#challenge-card {
  position: absolute;
  left: 50%;
  top: 22%;
  transform: translateX(-50%);
  width: min(30rem, calc(100vw - 3rem));
  padding: 0.9rem 1.1rem;
  background: rgba(10, 13, 12, 0.9);
  border: 1px solid var(--ui-edge);
  border-left: 3px solid rgba(160, 200, 160, 0.6);
  border-radius: 6px;
  animation: challenge-card-in 0.35s ease-out;
}

#challenge-card[hidden] { display: none; }

#challenge-card .card-kicker {
  margin: 0 0 0.3rem;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  color: #9fbf9f;
}

#challenge-card h2 {
  margin: 0 0 0.35rem;
  font-size: 1.25rem;
}

#challenge-card p:last-child {
  margin: 0;
  color: var(--ui-dim);
  line-height: 1.4;
}

@keyframes challenge-card-in {
  from { opacity: 0; transform: translate(-50%, -0.5rem); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* The eighth failure. The whole screen, because it is the only thing in the
   game that undoes hours of work. */
#run-lost .veil-inner h1 { color: #c8433c; }
.run-lost-line { font-size: 1.05rem; }
.run-lost-sub { color: var(--ui-dim); }

/* The survival bars are centred, so on anything narrower than a wide desktop
   window they reach across into this corner. The title is the part that can
   go: it is on the card as the challenge starts, and the card has room for it.
   Under a phone's width the corner shrinks further. */
@media (max-width: 1100px) {
  .challenge-title,
  .challenge-tally { display: none; }
}

html.phone #challenge {
  /* Under the bars rather than beside them: they are centred, and on a screen
     this narrow the middle reaches into this corner. Moving the corner costs
     nothing; moving the bars would push them over the view. */
  top: calc(env(safe-area-inset-top) + 3.2rem);
  min-width: 8.5rem;
  max-width: 11rem;
  padding: 0.4rem 0.55rem 0.45rem;
}

html.phone .challenge-title,
html.phone .challenge-tally { display: none; }

html.phone #challenge-card { top: 16%; }

/* A prize card is the same card in a warmer colour: it is good news, and the
   challenge cards are not news at all. */
#challenge-card.prize {
  border-left-color: #d9a04f;
}

#challenge-card.prize .card-kicker { color: #d9a04f; }

/* ---- Starting items, for infinite worlds ---- */

.create-form .starter-picker {
  margin: 0 0 0.9rem;
  padding: 0;
  border: 0;
}

.create-form .starter-picker[hidden] { display: none; }

.create-form .starter-picker legend {
  padding: 0;
  margin-bottom: 0.45rem;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ui-dim);
}

.create-form .starter-picker legend em {
  text-transform: none;
  letter-spacing: 0;
  font-style: normal;
  color: #6b7568;
}

.starter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: 0.35rem;
}

.create-form .starter {
  display: flex;
  flex-direction: row !important;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.5rem;
  background: rgba(20, 22, 20, 0.42);
  border: 1px solid var(--ui-edge);
  border-radius: 5px;
  cursor: pointer;
}

.create-form .starter span {
  color: var(--ui-text) !important;
  font-size: 0.82rem !important;
  letter-spacing: 0 !important;
}

.create-form .starter input { width: auto; padding: 0; margin: 0; accent-color: #7ab87a; }

.create-form .starter.taken {
  background: rgba(60, 90, 60, 0.35);
  border-color: rgba(160, 210, 160, 0.45);
}

/* Once the slots are full the rest go quiet, rather than silently losing what
   you tick beyond the seventh. */
.create-form .starter:has(input:disabled) { opacity: 0.4; cursor: not-allowed; }
