html,
body {
  box-sizing: border-box;
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #14181f;
}

/* The safe-area padding is on body only: on html too, the inset would move the game down twice. */
body {
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  height: 100dvh;
}

canvas {
  display: block;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/* The stage is as wide as the canvas; the menu sits below the field. */
#stage {
  position: relative;
  display: flex;
  flex-direction: column;
}

/* Menu button at the right end of the info bar (56 px high, see INFO_BAR_CSS_PX in js/layout.js). Room for it is kept in js/main.js. */
#leave-button {
  position: absolute;
  top: 6px;
  right: 12px;
  width: 96px;
  min-height: 44px;
  box-sizing: border-box;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #1d232c;
  color: #f2f5f8;
  font: 600 16px/1.2 sans-serif;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

#leave-button.asking {
  border-color: #f2c46b;
  color: #f2c46b;
}

/* Settings button in the field's bottom right corner, above the tower menu (64 px) with a 6 px margin: the info bar has no room for it on a phone. */
#settings-round-button {
  position: absolute;
  right: 12px;
  bottom: 70px;
  width: 44px;
  height: 44px;
  box-sizing: border-box;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #1d232c;
  color: #f2f5f8;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

#settings-round-button svg {
  width: 24px;
  height: 24px;
}

/* Mira's button over the field's bottom left, like the Settings button; pressed (move mode) it gets the gold border of the tower menu. */
#hero-round-button {
  position: absolute;
  left: 12px;
  bottom: 70px;
  width: 44px;
  height: 44px;
  box-sizing: border-box;
  padding: 0;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #1d232c;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

#hero-round-button[aria-pressed='true'] {
  border-color: #f2c46b;
}

#hero-round-button canvas {
  display: block;
  margin: auto;
}

/* The result's buttons over the field's bottom edge, above the tower menu like the Settings button. They fade in after 1 s, the RESULT_TAP_DELAY of js/ui/input.js, so they take no tap before. */
#result-buttons {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 70px;
  display: flex;
  gap: 8px;
  animation: result-buttons-in 0.4s 1s both;
}

#result-buttons[hidden] {
  display: none;
}

#result-buttons button {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  box-sizing: border-box;
  padding: 6px 4px;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #1d232c;
  color: #f2f5f8;
  font: 600 16px/1.2 sans-serif;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

#result-buttons button[hidden] {
  display: none;
}

@keyframes result-buttons-in {
  from {
    opacity: 0;
    visibility: hidden;
  }

  to {
    opacity: 1;
    visibility: visible;
  }
}

/* Height matches MENU_CSS_PX in js/layout.js. */
#tower-menu {
  display: flex;
  gap: 4px;
  box-sizing: border-box;
  height: 64px;
  padding: 4px;
}

#tower-menu button {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 2px 4px;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #1d232c;
  color: #f2f5f8;
  font: 600 14px/1.15 sans-serif;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

#tower-menu canvas {
  flex: none;
}

#tower-menu button div {
  text-align: left;
}

#tower-menu button span,
#tower-menu button em {
  display: block;
  font-style: normal;
  font-weight: 400;
}

#tower-menu button[aria-pressed='true'] {
  border-color: #f2c46b;
  color: #f2c46b;
}

/* A price the gold does not cover: a lighter red than the blocked tiles, for text on the dark button. */
#tower-menu button.poor span {
  color: #f08a7e;
}

/* A tap presses the button in a little, so the touch registers at once. */
#tower-menu button:active {
  transform: scale(0.94);
  background: #2a3240;
}

/* Main menu over the field; a tap on a level's Play button or on a Spezial card starts it. A warm glow at the top over a dark sky with a faint tile grid. */
#menu {
  position: fixed;
  inset: 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start; /* The title sits at the top; on a phone the cards scroll below it. */
  overflow-y: auto;
  gap: 20px;
  padding: 16px;
  background:
    radial-gradient(ellipse 70% 45% at 50% 0%, rgba(242, 196, 107, 0.16), rgba(242, 196, 107, 0) 100%),
    linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px) 0 0 / 48px 48px,
    linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px) 0 0 / 48px 48px,
    linear-gradient(180deg, #1d2633 0%, #14181f 60%, #101319 100%);
}

#menu[hidden] {
  display: none;
}

/* The loading screen covers the page until the game is ready: js/main.js adds `lifted` once the menu and the title's spiders are up,
   and it fades out (0.4 s). Without that signal (a failed script) it still lifts after 10 s. */
#loading {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: linear-gradient(180deg, #1d2633 0%, #14181f 60%, #101319 100%);
  animation: loading-lift 0.4s 10s forwards;
}

#loading.lifted {
  animation: loading-lift 0.4s forwards;
}

#loading .loading-name {
  margin: 0;
  font: 700 28px/1.2 sans-serif;
  color: #f2c46b;
}

#loading .loading-text {
  margin: 0;
  font: 400 16px/1.3 sans-serif;
  color: #8b95a3;
}

@keyframes loading-lift {
  to { opacity: 0; visibility: hidden; }
}

/* The hand-drawn title: its svg scales with the box (960 × 300 units), and js/ui/title.js walks the spiders over it. */
#title {
  position: relative;
  box-sizing: border-box;
  width: min(100%, 560px);
  aspect-ratio: 960 / 300;
  margin: -12px 0 0; /* Its picture has space above the letters: pulled up so the title sits high on the menu. */
}

/* The credit line under the title: small and grey. */
#credit {
  margin: -8px 0 0;
  color: #8b95a3;
  font: 400 14px/1.3 sans-serif;
  text-align: center;
}

/* The player's name under the credit line: small and light grey; hidden without a name. */
#player {
  margin: -12px 0 0;
  color: #b8c0cc;
  font: 600 14px/1.3 sans-serif;
  text-align: center;
}

/* One column of level cards below 700 px: the title stays at most 13 % of the screen height, so the whole menu fits. */
@media (max-width: 699px) {
  #title {
    width: min(100%, 41.6vh);
  }
}

#title .title-art {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

#title .swoosh {
  fill: none;
  stroke: #d9473f;
  stroke-width: 26;
  stroke-linecap: round;
}

#title .bracket {
  fill: none;
  stroke: #f0c040;
  stroke-width: 6;
  stroke-linecap: round;
}

#title text {
  fill: #3f8fd6;
  font-family: 'Marker Felt', 'Bradley Hand', 'Segoe Print', 'Comic Sans MS', cursive, sans-serif;
}

.title-spider {
  position: absolute;
  left: 0;
  top: 0;
  height: auto;
  aspect-ratio: 1;
  overflow: visible;
  pointer-events: none;
}

/* The legs step in two groups, one half a step behind the other. */
.title-spider .legs {
  animation: leg-step 0.4s ease-in-out infinite alternate;
}

.title-spider .legs-b {
  animation-delay: -0.2s;
}

@keyframes leg-step {
  from { transform: rotate(-8deg); }
  to { transform: rotate(8deg); }
}

@media (prefers-reduced-motion: reduce) {
  .title-spider .legs {
    animation: none;
  }
}

/* The Levels and Spezial tabs: a row above the cards, as wide as the cards; on a wide screen in the top left corner. */
#menu-tabs {
  display: flex;
  gap: 6px;
  box-sizing: border-box;
  width: min(100%, 360px);
}

#menu-tabs button,
#menu-specials .reset {
  flex: 1 1 0;
  min-height: 44px;
  padding: 6px 14px;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #1d232c;
  color: #f2f5f8;
  font: 600 16px/1.2 sans-serif;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

#menu-tabs button[aria-pressed='true'] {
  border-color: #f2c46b;
  color: #f2c46b;
}

/* The settings button keeps its width for a long word such as "Einstellungen"; the tabs share the rest of the row. */
#settings-button {
  flex: none;
}

#menu-specials {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  width: min(100%, 360px);
}

/* The Levels tab: its groups of five one under another. */
#menu-levels {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: min(100%, 360px);
}

#menu-levels[hidden],
#menu-specials[hidden] {
  display: none;
}

/* The campaign's first chapter above the Levels groups: the hero picture beside the prologue. */
#menu-campaign {
  display: flex;
  align-items: center;
  gap: 14px;
  box-sizing: border-box;
  width: min(100%, 360px);
  padding: 12px;
  border: 2px solid #2e3440;
  border-radius: 8px;
  background: #1d232c;
  color: #f2f5f8;
}

#menu-campaign[hidden] {
  display: none;
}

#menu-campaign img {
  flex: none;
  width: 104px;
  height: 104px;
}

#menu-campaign .text {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

#menu-campaign h2 {
  margin: 0;
  font: 700 18px/1.25 sans-serif;
  color: #f2c46b;
}

#menu-campaign p {
  margin: 0;
  font: 400 14px/1.4 sans-serif;
  color: #d5dce5;
}

#menu-campaign .hero-name {
  font-weight: 600;
  color: #f2f5f8;
}

#menu-campaign .chapter {
  color: #aab3bf;
}

/* Four cards side by side on wide screens; the groups of the Levels tab three in a row. */
@media (min-width: 700px) {
  #menu-tabs {
    width: min(100%, 1120px);
  }

  #menu-specials {
    grid-template-columns: repeat(4, 1fr);
    width: min(100%, 1120px);
  }

  #menu-campaign {
    width: min(100%, 1120px);
  }

  #menu-levels {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-start; /* An open level card makes its group taller; the other groups keep their top edge. */
    width: min(100%, 1120px);
  }

  #menu-levels .group {
    width: 360px;
  }
}

/* On a wide screen the tabs sit in the top left corner, beside the title. */
@media (min-width: 900px) {
  #menu-tabs {
    position: absolute;
    top: 16px;
    left: 16px;
    width: auto;
  }
}

/* The Settings tab: a card in place of the cards, with the name field, the language and the sound switches. A tap on another tab shows those again. */
#menu-settings {
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-sizing: border-box;
  width: min(100%, 360px);
  padding: 20px;
  border: 2px solid #2e3440;
  border-radius: 8px;
  background: #1d232c;
}

#menu-settings[hidden] {
  display: none;
}

/* Settings over a round: only the fields show, and Back is there; the menu's title, tabs and cards stay hidden. */
#menu.in-round > :not(#menu-settings) {
  display: none;
}

#settings-back {
  display: none;
  min-height: 44px;
  padding: 6px 14px;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #1d232c;
  color: #f2f5f8;
  font: 600 16px/1.2 sans-serif;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

#menu.in-round #settings-back {
  display: block;
}

#menu-settings label,
#menu-settings p {
  margin: 0;
  color: #8b95a3;
  font: 400 14px/1.3 sans-serif;
}

#menu-settings input {
  box-sizing: border-box;
  width: 100%;
  min-height: 44px;
  padding: 6px 12px;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #14181f;
  color: #f2f5f8;
  font: 600 16px/1.2 sans-serif; /* 16 px: no zoom on focus in iOS Safari. */
}

#menu-settings input:focus {
  outline: none;
  border-color: #f2c46b;
}

#language-buttons,
#sound-buttons {
  display: flex;
  gap: 6px;
}

#language-buttons button,
#sound-buttons button {
  flex: 1 1 0;
  min-height: 44px;
  padding: 6px 14px;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #1d232c;
  color: #f2f5f8;
  font: 600 16px/1.2 sans-serif;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}

#language-buttons button[aria-pressed='true'],
#sound-buttons button[aria-pressed='true'] {
  border-color: #f2c46b;
  color: #f2c46b;
}

/* A special card with its reset button under it. */
#menu-specials .entry {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

#menu-specials .reset {
  flex: none;
  width: 100%;
}

.card {
  display: flex;
  align-items: center;
  gap: 12px;
  box-sizing: border-box;
  min-height: 72px;
  padding: 8px 12px 8px 8px;
  border: 2px solid #2e3440;
  border-radius: 8px;
  background: #1d232c;
  color: #f2f5f8;
  font: 600 18px/1.2 sans-serif;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
}

.card .thumb {
  flex: none;
  width: 96px;
  height: 54px;
  border-radius: 4px;
}

.card .text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.card .text span {
  font: 400 14px/1.3 sans-serif;
  color: #aab3bf;
}

.card .result {
  color: #d5dce5;
}

/* The level played last. */
.card.played {
  border-color: #f2c46b;
  color: #f2c46b;
}

/* A level that is still locked: its number and picture are dimmed; its card names the levels to win first, and its buttons are off. */
.card.locked .badge,
.card.locked .thumb {
  opacity: 0.45;
}

.group .level-card .play:disabled,
#menu-specials .reset:disabled {
  opacity: 0.5;
  cursor: default;
}

/* A group of five on its theme's ground picture; the veil below keeps the buttons readable on the bright sand and snow. The open level card takes a line of its own below the buttons. */
.group {
  position: relative;
  isolation: isolate;
  box-sizing: border-box;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  row-gap: 10px;
  justify-content: space-between;
  padding: 12px 6px 10px;
  border: 2px solid #2e3440;
  border-radius: 12px;
  background-color: #1d232c;
  background-size: 160px 160px;
}

.group::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(14, 17, 22, 0.4);
  z-index: -1;
}

/* The buttons follow a gentle arc, like the path in the sketch. Counted by button type, as the level cards sit between them. */
.group .round:nth-of-type(1),
.group .round:nth-of-type(5) {
  transform: translateY(10px);
}

.group .round:nth-of-type(2),
.group .round:nth-of-type(4) {
  transform: translateY(4px);
}

/* A round numbered button, its number only; the name and result are on its level card. */
.card.round {
  flex: none;
  width: 68px;
  min-height: 0;
  padding: 0;
  border: none;
  background: none;
  justify-content: center;
}

.card.round .badge {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 52px;
  height: 52px;
  border: 3px solid #f2f5f8;
  border-radius: 50%;
  background: #1d232c;
  color: #f2f5f8;
  font: 700 22px/1 sans-serif;
}

.card.round.played .badge {
  border-color: #f2c46b;
  color: #f2c46b;
}

/* A locked round level: its badge is dimmed and dashed; its card says why and Play is off. */
.card.round.locked .badge {
  border-style: dashed;
  opacity: 0.5;
}

/* A locked Spezial card (Random Land): its picture is dimmed and its note says why; the card cannot be started. */
#menu-specials .card.locked {
  border-style: dashed;
  cursor: default;
}

#menu-specials .card.locked .thumb {
  opacity: 0.5;
}

#menu-specials .lock {
  color: #f2c46b;
  font: 400 14px/1.3 sans-serif;
}

/* The card under a round button, as in the sketch: a pointer to the button, the name and level, the details, the last run and Play. */
.group .level-card {
  position: relative;
  order: 1;
  flex: 0 0 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 10px 12px 12px;
  border: 2px solid #2e3440;
  border-radius: 8px;
  background: #1d232c;
  color: #f2f5f8;
  text-align: left;
}

.group .level-card[hidden] {
  display: none;
}

.group .level-card::before {
  content: '';
  position: absolute;
  top: -8px;
  left: var(--pointer, 50%);
  transform: translateX(-50%);
  border: 8px solid transparent;
  border-top: 0;
  border-bottom-color: #2e3440;
}

.group .level-card strong {
  font: 600 18px/1.2 sans-serif;
}

.group .level-card span {
  font: 400 14px/1.3 sans-serif;
  color: #aab3bf;
}

.group .level-card .result {
  color: #d5dce5;
}

.group .level-card .lock {
  color: #f2c46b;
}

.group .level-card .play:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.group .level-card .play {
  align-self: stretch;
  min-height: 44px;
  margin-top: 6px;
  padding: 6px 14px;
  border: 2px solid #2e3440;
  border-radius: 6px;
  background: #14181f;
  color: #f2f5f8;
  font: 600 16px/1.2 sans-serif;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}
