:root {
  --bg: #0b0f22;
  --panel: #151a36;
  --panel-2: #1e2448;
  --line: #2d3563;
  --text: #f6f0e6;
  --muted: #b9b4cc;
  --accent: #ffb547;
  --accent-2: #ff8a2e;
  --good: #72e3a0;
  --warn: #ff9a6b;
  --header-h: 48px;
  /* The safe areas (notches, rounded corners, the home indicator), with the
     page drawn edge to edge (viewport-fit=cover); the tests set them too. */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  /* Over a home indicator, what a thumb touches keeps 16 px clear of it: the
     inset and up to 10 px more, beside the 6 px the bars keep anyway. */
  --home-b: calc(var(--safe-b) + min(var(--safe-b), 10px));
  /* What a thumb touches keeps 16 px from the screen's edge below it, and 16
     px over a home indicator. */
  --dock-b: max(16px, calc(6px + var(--home-b)));
  /* The smallest text (docs/PLATFORMS.md, "Layout"): 14 px on a desktop, 15
     on a tablet, 13 on a phone (a touch screen under 600 px one way). The
     canvas reads it too (render.js). */
  --t-min: 14px;
  color-scheme: dark;
}

@media (pointer: coarse) {
  :root {
    --t-min: 15px;
  }
}

@media (pointer: coarse) and (max-width: 599px), (pointer: coarse) and (max-height: 599px) {
  :root {
    --t-min: 13px;
    /* A phone's screen has rounded corners, which Android doesn't report:
       the boosters at the bottom keep 24 px clear of them. */
    --dock-b: max(24px, calc(6px + var(--home-b)));
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Ubuntu, sans-serif;
  -webkit-text-size-adjust: 100%;
}

a {
  color: var(--accent);
}

button {
  font: inherit;
  color: inherit;
  touch-action: manipulation;
  cursor: pointer;
}

button:disabled {
  cursor: default;
}

[hidden] {
  display: none !important;
}

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

.site-header {
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
}

.site-header nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 14px;
}

.page {
  padding: 8px max(8px, var(--safe-r)) 40px max(8px, var(--safe-l));
}

/* ---------- Game layout ---------- */

.game-root {
  --bg-a: #0a1530;
  --bg-b: #1d3766;
  --tint: #ffb547;
  /* The side column, where the HUD and the boosters stand beside the board (.cols). */
  --side-w: 228px;
  position: relative;
  margin: 0 auto;
  width: 100%;
  max-width: 1040px;
  /* The viewport under the site header, which grows by the top inset in the
     home-screen app. */
  height: calc(100vh - var(--header-h) - 16px);
  height: calc(100dvh - var(--header-h) - var(--safe-t) - 16px);
  min-height: 300px;
  max-height: 960px;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto auto;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: 'hud' 'stage' 'bars' 'dock';
  border-radius: 14px;
  border: 1px solid var(--line);
  overflow: hidden;
  /* No page scrolling, pinch or double-tap zoom, pull-to-refresh, selection
     or long-press menu over the game (docs/PLATFORMS.md); the menus still
     scroll (.overlay). */
  touch-action: none;
  overscroll-behavior: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  background-color: var(--bg-a);
  /* A faint paper grain over the region's colors, lit warmly from below. */
  background-image:
    repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.022) 0 1px, transparent 1px 7px),
    repeating-linear-gradient(35deg, rgba(0, 0, 0, 0.07) 0 1px, transparent 1px 11px),
    radial-gradient(ellipse 80% 40% at 50% 110%, color-mix(in srgb, var(--tint) 22%, transparent), transparent 70%),
    linear-gradient(180deg, var(--bg-a), var(--bg-b));
  transition: background-color 0.4s;
}

@supports not (background: color-mix(in srgb, red 50%, blue)) {
  .game-root {
    background-image:
      repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.022) 0 1px, transparent 1px 7px),
      repeating-linear-gradient(35deg, rgba(0, 0, 0, 0.07) 0 1px, transparent 1px 11px),
      radial-gradient(ellipse 80% 40% at 50% 110%, rgba(255, 181, 71, 0.2), transparent 70%),
      linear-gradient(180deg, var(--bg-a), var(--bg-b));
  }
}

.stage {
  grid-area: stage;
  position: relative;
  min-height: 0;
  min-width: 0;
}

.stage canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  outline: none;
}

/* A finished/quit board must not sit behind the title, map or achievements. */
.game-root:not(.playing) > .stage { visibility: hidden; }

/* A focus ring for keyboard players only; the pointer never needs it. */
.keys .stage canvas:focus-visible {
  box-shadow: inset 0 0 0 2px rgba(255, 214, 140, 0.55);
}

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

.hud {
  grid-area: hud;
  display: flex;
  align-items: center;
  gap: 8px 10px;
  /* What a thumb touches keeps 16 px from the screen's sides. */
  padding: 6px 16px;
  min-height: 56px;
  background: rgba(6, 8, 24, 0.55);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.hud-a,
.hud-b {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

.hud-mode {
  font-weight: 800;
  font-size: max(14px, var(--t-min));
  color: var(--muted);
  white-space: nowrap;
}

.hud-goals {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}

.goal {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px 3px 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.1);
  font-weight: 800;
  font-size: max(14px, var(--t-min));
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.goal.done {
  background: rgba(114, 227, 160, 0.18);
  border-color: rgba(114, 227, 160, 0.45);
  color: var(--good);
}

.hud-best {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.hud-score,
.hud-sets {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.05;
}

.hud-num {
  font-size: 21px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  min-width: 2ch;
  text-align: right;
}

.hud-score .hud-num {
  min-width: 7ch;
}

.hud-label {
  font-size: var(--t-min);
  color: var(--muted);
}

.hud-sets.low .hud-num {
  color: var(--warn);
}

.hud-combo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  opacity: 0.4;
  transition: opacity 0.2s;
}

.hud-combo.on {
  opacity: 1;
}

.combo-x {
  font-weight: 900;
  font-size: 15px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* Combo marks: small folded squares that count down the sets left. */
.pips {
  display: flex;
  gap: 5px;
  padding: 0 2px;
}

.pip {
  width: 7px;
  height: 7px;
  border-radius: 1px;
  transform: rotate(45deg);
  background: #3a3552;
}

.pip.on {
  background: linear-gradient(135deg, #ffe7b0 50%, var(--accent) 50%);
  box-shadow: 0 0 6px var(--accent);
}

.btn-icon {
  appearance: none;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.07);
  display: grid;
  place-items: center;
  padding: 0;
}

.pause-bars {
  width: 14px;
  height: 16px;
  border-left: 5px solid var(--text);
  border-right: 5px solid var(--text);
}

/* ---------- Dock ---------- */

.dock {
  grid-area: dock;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 6px 16px var(--dock-b);
  background: rgba(6, 8, 24, 0.55);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* A stuck tray or a booster waiting for its target: a bar of its own above
   the boosters (beside them, under the board, in side columns). */
.bars {
  grid-area: bars;
  padding: 4px 16px 2px;
  background: rgba(6, 8, 24, 0.55);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.dock-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 12px;
  font-size: max(14px, var(--t-min));
  text-align: center;
  padding: 2px 0 4px;
}

.stuck-bar {
  color: #ffe2b0;
}

.booster {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 6px;
  min-height: 44px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.07);
  color: var(--text);
}

.booster .b-icon {
  display: grid;
  place-items: center;
}

.b-name {
  font-size: var(--t-min);
  font-weight: 700;
}

.b-count {
  min-width: 22px;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(255, 181, 71, 0.2);
  color: var(--accent);
  font-weight: 900;
  font-size: var(--t-min);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.booster.empty {
  opacity: 0.5;
}

.booster.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(255, 181, 71, 0.4);
}

.btn-text {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: max(14px, var(--t-min));
  font-weight: 700;
  padding: 10px 8px;
  min-height: 44px;
  min-width: 44px;
}

/* ---------- Buttons ---------- */

.btn {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  padding: 11px 18px;
  min-height: 46px;
  border-radius: 12px;
  font-weight: 800;
  font-size: 16px;
  line-height: 1.2;
}

.btn:hover {
  background: rgba(255, 255, 255, 0.13);
}

.btn.primary {
  background: linear-gradient(180deg, #ffc863, #ff902e);
  border-color: transparent;
  color: #2b1300;
}

.btn.primary:hover {
  background: linear-gradient(180deg, #ffd27d, #ff9d45);
}

.btn.small {
  padding: 7px 12px;
  min-height: 44px;
  min-width: 44px;
  font-size: max(14px, var(--t-min));
}

.btn.chest {
  border-color: rgba(255, 214, 140, 0.65);
  color: #ffe2b0;
}

.btn.done {
  color: var(--good);
}

.btn:focus-visible,
.btn-icon:focus-visible,
.booster:focus-visible,
.btn-text:focus-visible,
.lvl:focus-visible {
  outline: 3px solid rgba(255, 214, 140, 0.8);
  outline-offset: 2px;
}

/* ---------- Overlay screens ---------- */

.overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  /* Its buttons keep 16 px from the screen's edges, and over a home indicator. */
  padding: 16px 16px var(--dock-b);
  overflow-y: auto;
  /* A finger scrolls a menu, and only the menu. */
  touch-action: pan-y;
  overscroll-behavior: contain;
  background: rgba(5, 7, 20, 0.72);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

.overlay[data-screen='title'],
.overlay[data-screen='map'],
.overlay[data-screen='achievements'],
.overlay[data-screen='help'] {
  background: rgba(5, 7, 20, 0.35);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.card {
  margin: auto;
  width: min(440px, 100%);
  padding: 20px 20px 18px;
  text-align: center;
  background: rgba(16, 18, 42, 0.95);
  border: 1px solid rgba(255, 214, 140, 0.22);
  border-radius: 18px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.card h2 {
  margin: 4px 0 10px;
  font-size: 26px;
}

.card h3 {
  margin: 14px 0 6px;
  font-size: 15px;
  color: var(--accent);
}

.muted {
  color: var(--muted);
}

.small {
  font-size: var(--t-min);
}

.eyebrow {
  margin: 0;
  font-size: var(--t-min);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--tint);
  font-weight: 800;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 16px;
}

.actions.col {
  flex-direction: column;
  align-items: stretch;
}

.actions .toggles {
  display: flex;
  gap: 8px;
  justify-content: center;
}

.goal-list {
  list-style: none;
  padding: 0;
  margin: 10px auto;
  display: inline-flex;
  flex-direction: column;
  gap: 8px;
  text-align: left;
}

.goal-line {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
  font-weight: 700;
}

.goal-line.done {
  color: var(--good);
}

.sets-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-weight: 700;
  margin: 6px 0;
}

.tip {
  margin: 12px 0 8px;
  padding: 10px 12px;
  border-radius: 12px;
  background: rgba(255, 181, 71, 0.1);
  border: 1px solid rgba(255, 181, 71, 0.3);
  line-height: 1.45;
  text-align: left;
}

.spinner {
  width: 34px;
  height: 34px;
  margin: 14px auto 4px;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, 0.15);
  border-top-color: var(--accent);
  animation: spin 0.9s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Title */

.title-screen {
  position: relative;
  margin: auto;
  width: min(460px, 100%);
  text-align: center;
  padding: 8px 0;
}

.paper-cranes {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}

.overlay > :not(.paper-cranes) {
  position: relative;
  z-index: 1;
}

/* Paper cranes flying up past the menu. Each image holds two frames, wings
   up and wings down, and the flap animation switches between them. */
.paper-cranes i {
  position: absolute;
  bottom: -44px;
  left: calc(2% + var(--k) * 12%);
  width: 36px;
  height: 36px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 100'%3E%3Cpolygon points='42,54 58,54 40,10' fill='%23ce7f1e' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='34,58 45,62 6,29' fill='%23ed9d2c' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='55,62 66,58 89,25' fill='%23ed9d2c' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='89,25 99,34 86,31' fill='%23ce7f1e'/%3E%3Cpolygon points='30,58 50,50 70,58 50,67' fill='%23ffae34' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='38,55 50,55 55,4' fill='%23ffcd81'/%3E%3Cpolygon points='50,55 62,55 55,4' fill='%23ffae34'/%3E%3Cpolygon points='38,55 62,55 55,4' fill='none' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='142,54 158,54 146,84' fill='%23ce7f1e' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='134,58 145,62 106,29' fill='%23ed9d2c' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='155,62 166,58 189,25' fill='%23ed9d2c' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='189,25 199,34 186,31' fill='%23ce7f1e'/%3E%3Cpolygon points='130,58 150,50 170,58 150,67' fill='%23ffae34' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='138,55 150,55 160,94' fill='%23ffcd81'/%3E%3Cpolygon points='150,55 162,55 160,94' fill='%23ffae34'/%3E%3Cpolygon points='138,55 162,55 160,94' fill='none' stroke='rgba(156,79,8,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E") 0 0 / 200% 100% no-repeat;
  opacity: 0.72;
  animation:
    flap 0.46s linear infinite,
    fly-right calc(16s + var(--k) * 2.3s) linear infinite;
  animation-delay: calc(var(--k) * -0.11s), calc(var(--k) * -3.7s);
}

.paper-cranes i:nth-child(3n + 1) {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 100'%3E%3Cpolygon points='42,54 58,54 40,10' fill='%232992c1' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='34,58 45,62 6,29' fill='%2338b1e0' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='55,62 66,58 89,25' fill='%2338b1e0' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='89,25 99,34 86,31' fill='%232992c1'/%3E%3Cpolygon points='30,58 50,50 70,58 50,67' fill='%2341c2f2' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='38,55 50,55 55,4' fill='%2389d9f7'/%3E%3Cpolygon points='50,55 62,55 55,4' fill='%2341c2f2'/%3E%3Cpolygon points='38,55 62,55 55,4' fill='none' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='142,54 158,54 146,84' fill='%232992c1' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='134,58 145,62 106,29' fill='%2338b1e0' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='155,62 166,58 189,25' fill='%2338b1e0' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='189,25 199,34 186,31' fill='%232992c1'/%3E%3Cpolygon points='130,58 150,50 170,58 150,67' fill='%2341c2f2' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='138,55 150,55 160,94' fill='%2389d9f7'/%3E%3Cpolygon points='150,55 162,55 160,94' fill='%2341c2f2'/%3E%3Cpolygon points='138,55 162,55 160,94' fill='none' stroke='rgba(17,97,143,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.paper-cranes i:nth-child(3n + 2) {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 100'%3E%3Cpolygon points='42,54 58,54 40,10' fill='%23d45599' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='34,58 45,62 6,29' fill='%23ef70b3' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='55,62 66,58 89,25' fill='%23ef70b3' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='89,25 99,34 86,31' fill='%23d45599'/%3E%3Cpolygon points='30,58 50,50 70,58 50,67' fill='%23ff7fc2' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='38,55 50,55 55,4' fill='%23ffb0d9'/%3E%3Cpolygon points='50,55 62,55 55,4' fill='%23ff7fc2'/%3E%3Cpolygon points='38,55 62,55 55,4' fill='none' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='142,54 158,54 146,84' fill='%23d45599' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='134,58 145,62 106,29' fill='%23ef70b3' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='155,62 166,58 189,25' fill='%23ef70b3' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='189,25 199,34 186,31' fill='%23d45599'/%3E%3Cpolygon points='130,58 150,50 170,58 150,67' fill='%23ff7fc2' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3Cpolygon points='138,55 150,55 160,94' fill='%23ffb0d9'/%3E%3Cpolygon points='150,55 162,55 160,94' fill='%23ff7fc2'/%3E%3Cpolygon points='138,55 162,55 160,94' fill='none' stroke='rgba(168,43,111,0.55)' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.paper-cranes i:nth-child(2n) {
  left: calc(26% + var(--k) * 10%);
  animation-name: flap, fly-left;
}

.paper-cranes i:nth-child(3n) {
  width: 26px;
  height: 26px;
  opacity: 0.5;
}

@keyframes flap {
  0%,
  49.9% {
    background-position: 0 0;
  }
  50%,
  100% {
    background-position: 100% 0;
  }
}

@keyframes fly-right {
  from {
    transform: translate(0, 0) rotate(-16deg);
  }
  50% {
    transform: translate(16vw, -62vh) rotate(-10deg);
  }
  to {
    transform: translate(30vw, -125vh) rotate(-16deg);
  }
}

@keyframes fly-left {
  from {
    transform: translate(0, 0) scaleX(-1) rotate(-16deg);
  }
  50% {
    transform: translate(-16vw, -62vh) scaleX(-1) rotate(-10deg);
  }
  to {
    transform: translate(-30vw, -125vh) scaleX(-1) rotate(-16deg);
  }
}

.logo {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin: 6px auto 4px;
}

.logo-crane {
  flex: none;
  filter: drop-shadow(0 0 16px rgba(255, 174, 52, 0.45));
}

.logo-text {
  font-size: clamp(36px, 9vw, 56px);
  font-weight: 900;
  line-height: 0.95;
  text-align: left;
  letter-spacing: 0.5px;
  color: #ffd98a;
  background: linear-gradient(180deg, #fff6d8 10%, #ffb238 90%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 12px rgba(255, 170, 60, 0.35));
}

.tagline {
  margin: 12px auto 0;
  max-width: 34ch;
  color: var(--muted);
  line-height: 1.45;
}

.menu {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 18px auto 10px;
  width: min(320px, 100%);
}

.menu-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 4px;
}

.menu-row .toggles {
  display: flex;
  gap: 8px;
}

.stats {
  font-size: var(--t-min);
  margin: 8px 0 0;
}

/* Map */

.map-screen,
.list-card {
  margin: 0 auto;
  width: min(720px, 100%);
}

.list-card {
  text-align: left;
  margin: auto;
}

.map-head {
  position: sticky;
  top: 0;
  z-index: 2;
  background: #101a32;
  display: flex;
  align-items: center;
  gap: 12px;
  justify-content: space-between;
}

.map-head h2 {
  margin: 0;
  font-size: 22px;
  flex: 1;
  text-align: center;
}

.chest-meter {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 800;
  font-size: max(14px, var(--t-min));
  white-space: nowrap;
}

.chest-ready {
  display: flex;
  justify-content: center;
  margin-top: 10px;
}

.region {
  margin: 14px 0;
  padding: 12px;
  border-radius: 16px;
  background: linear-gradient(180deg, var(--bg-a), var(--bg-b));
  border: 1px solid rgba(255, 255, 255, 0.12);
}

.region h3 {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 0 0 10px;
  font-size: 16px;
}

.region-stars {
  font-size: var(--t-min);
  color: #ffd76b;
}

.lvl-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
}

.lvl {
  appearance: none;
  min-height: 54px;
  padding: 6px 2px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(0, 0, 0, 0.28);
  color: var(--text);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
}

.lvl:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.1);
}

.lvl-n {
  font-weight: 900;
  font-size: 18px;
}

.lvl-stars {
  font-size: var(--t-min);
  line-height: 1.1;
  color: #ffd76b;
  letter-spacing: 1px;
  min-height: 1em;
}

.lvl.locked {
  opacity: 0.38;
}

.lvl.hard {
  border-color: rgba(255, 128, 128, 0.7);
}

.lvl.current {
  border-color: var(--tint);
  box-shadow:
    0 0 0 2px var(--tint),
    0 0 18px var(--tint);
}

/* Results */

.stars {
  display: flex;
  justify-content: center;
  gap: 10px;
  font-size: 46px;
  line-height: 1;
  margin: 6px 0;
}

.star {
  color: rgba(255, 255, 255, 0.16);
}

.star.got {
  color: #ffd76b;
  text-shadow: 0 0 16px rgba(255, 200, 80, 0.7);
  animation: pop 0.45s var(--d, 0s) both cubic-bezier(0.3, 1.6, 0.5, 1);
}

@keyframes pop {
  from {
    transform: scale(0);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.big-score {
  margin: 4px 0;
  font-size: 42px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}

.badge {
  display: inline-block;
  margin: 6px 4px;
  padding: 4px 12px;
  border-radius: 999px;
  background: rgba(255, 181, 71, 0.18);
  color: var(--accent);
  font-weight: 800;
}

.stat-row {
  display: flex;
  justify-content: center;
  gap: 18px;
  margin: 12px 0 4px;
}

.stat {
  display: flex;
  flex-direction: column;
}

.stat-v {
  font-size: 20px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}

.stat-l {
  font-size: var(--t-min);
  color: var(--muted);
}

.unlocked {
  margin-top: 10px;
  padding: 8px 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.05);
}

.unlocked p {
  margin: 4px 0;
}

.result .btn.chest {
  margin-top: 12px;
}

.chest-card .reward {
  font-size: 20px;
  font-weight: 800;
  color: var(--accent);
}

.chest-open .icon {
  animation: wobble 0.6s ease-out both;
}

@keyframes wobble {
  0% {
    transform: scale(0.6) rotate(0);
  }
  40% {
    transform: scale(1.1) rotate(-6deg);
  }
  70% {
    transform: scale(1) rotate(4deg);
  }
  100% {
    transform: scale(1) rotate(0);
  }
}

.boosters-now {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 14px;
  font-size: max(14px, var(--t-min));
}

.boosters-now .have {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

/* Achievements and help lists */

.ach-list,
.help-list {
  list-style: none;
  padding: 0;
  margin: 14px 0 0;
  display: grid;
  gap: 8px;
}

.ach-list li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  opacity: 0.7;
}

.ach-list li.got {
  opacity: 1;
  border-color: rgba(255, 214, 140, 0.45);
  background: rgba(255, 181, 71, 0.08);
}

.ach-list li.got strong::after {
  content: ' ✓';
  color: var(--good);
}

.help-list li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 8px 4px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}

.help-list li > div {
  flex: 1;
}

.help-list li:not(:has(canvas)) > div {
  padding-left: 40px;
}

.help-list p {
  margin: 3px 0 0;
  line-height: 1.45;
  color: var(--muted);
}

/* ---------- Below the game ---------- */

.ad-slot {
  max-width: 970px;
  margin: 12px auto 0;
  min-height: 0;
}

.ad-slot[data-filled='true'] {
  min-height: 90px;
}

/* Room for the house ad before it fills, so the buttons above don't jump. */
.ad-results {
  min-height: 94px;
  margin-top: 14px;
}

.about {
  max-width: 820px;
  margin: 24px auto 0;
  color: var(--muted);
  line-height: 1.55;
  font-size: 15px;
}

.about h1,
.about h2 {
  color: var(--text);
}

kbd {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
  font-size: 0.9em;
  color: var(--text);
}

/* ---------- Narrow phones: goals get their own HUD row ---------- */

@media (max-width: 600px) {
  .hud {
    flex-wrap: wrap;
    justify-content: space-between;
    padding: 5px 16px;
  }

  .hud-goals {
    order: 3;
    flex: 1 0 100%;
  }

  .hud-num {
    font-size: 19px;
  }

  .hud-score .hud-num {
    min-width: 6ch;
  }
}

@media (max-width: 520px) {
  .page {
    padding: 0 var(--safe-r) 32px var(--safe-l);
  }

  .game-root {
    border-radius: 0;
    border-left: 0;
    border-right: 0;
    height: calc(100vh - var(--header-h));
    height: calc(100dvh - var(--header-h) - var(--safe-t));
  }

  .about {
    padding: 0 12px;
  }

  .b-name {
    display: none;
  }

  .booster {
    padding: 5px 10px;
  }

  .card {
    padding: 16px 14px;
  }
}

/* ---------- Side columns ----------
   main.js adds .cols where they give the larger board, by a tenth at least:
   phones and tablets held sideways, and wide screens in full screen. The HUD
   stands above the boosters in a column at the left; the board and its tray
   take the rest, as tall as the game; a stuck tray's or a booster's bar sits
   under the board. */
.game-root.playing.cols {
  grid-template-columns: var(--side-w) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas:
    'hud stage'
    'dock stage'
    'dock bars';
}

.playing.cols > .hud {
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  flex-wrap: nowrap;
  gap: 8px;
  padding: 10px 16px 6px;
  border-bottom: 0;
  border-right: 1px solid rgba(255, 255, 255, 0.08);
}

.playing.cols .hud-mode {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.playing.cols .hud-b {
  justify-content: space-between;
}

.playing.cols .hud-goals {
  order: 0;
  flex: none;
  flex-direction: column;
  align-items: stretch;
}

.playing.cols .goal {
  justify-content: flex-start;
}

.playing.cols .hud-score .hud-num {
  min-width: 0;
}

/* The boosters fill the column under the HUD, from the bottom up. */
.playing.cols > .dock {
  align-self: stretch;
  align-content: flex-end;
  justify-content: flex-start;
  border-top: 0;
  border-right: 1px solid rgba(255, 255, 255, 0.08);
}

.playing.cols > .bars {
  padding-bottom: var(--dock-b);
}

/* The board keeps above a home indicator where it meets the bottom of the
   screen (a bar under it keeps its own margin), and the tray 16 px from its
   right edge. */
.playing.cols > .stage canvas {
  width: calc(100% - 16px);
  height: calc(100% - var(--home-b));
}

.playing.cols.bars-on > .stage canvas {
  height: 100%;
}

/* ---------- Phones held sideways ----------
   The game takes the screen: the site header steps aside while a game is in
   play (html.pg-in-play, main.js) and comes back with every menu, which fits
   under it, so "Full screen" is a tap away on the pause menu. */
@media (orientation: landscape) and (max-height: 560px) {
  .page {
    padding: 0 var(--safe-r) 24px var(--safe-l);
  }

  .game-root {
    height: calc(100vh - var(--header-h));
    height: calc(100dvh - var(--header-h) - var(--safe-t));
    min-height: 250px;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }

  html.pg-in-play .site-header {
    display: none;
  }

  html.pg-in-play .game-root {
    height: 100vh;
    height: 100dvh;
  }

  /* In play the column meets the top of the screen: 16 px from it, and 24
     px from a phone's rounded corners, as the bars and the boosters keep. */
  .playing.cols > .hud {
    gap: 6px;
    padding-top: 16px;
    padding-left: 24px;
  }

  .playing.cols > .dock {
    padding-left: 24px;
  }

  .playing.cols > .bars {
    padding-left: 24px;
    padding-right: 24px;
  }

  /* The boosters by their icons, two a row (their names are in How to play). */
  .playing.cols .b-name {
    display: none;
  }

  .playing.cols .hud-goals {
    gap: 4px;
  }

  .card {
    padding: 12px 16px;
  }

  .card h2 {
    font-size: 22px;
    margin-bottom: 6px;
  }

  .big-score {
    font-size: 32px;
  }

  .stars {
    font-size: 36px;
  }

  .goal-list {
    margin: 6px auto;
  }

  .tip {
    margin: 6px 0;
    padding: 8px 10px;
    line-height: 1.35;
  }

  /* A level's card, the pause menu and the results in two parts, side by
     side, so they fit under the header: what it is about on the left, what
     to do on the right, a result's buttons at its top, in view however many
     rewards it lists. */
  .card.split {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    column-gap: 20px;
    width: min(680px, 100%);
  }

  .card.split > .card-info,
  .card.split > .card-act {
    flex: 1 1 0;
    min-width: 0;
  }

  .card.split > :not(.card-info):not(.card-act) {
    flex: 1 0 100%;
  }

  .card.split .card-act > .actions:first-child {
    margin-top: 6px;
  }

  .card.split.pause .actions.col {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }

  .card.split.pause .actions.col .toggles {
    grid-column: 1 / -1;
  }

  .chest-open .icon {
    width: 56px !important;
    height: 56px !important;
  }

  .menu {
    margin: 10px auto 6px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    width: min(560px, 100%);
  }

  .menu > .btn.primary,
  .menu > .btn.chest,
  .menu-row {
    grid-column: 1 / -1;
  }

  .tagline {
    display: none;
  }

  .logo-text {
    font-size: 34px;
  }

  .logo-crane {
    width: 48px !important;
    height: 48px !important;
  }
}

/* ---------- Full screen (the site's button, docs/PLATFORMS.md) ----------
   The game fills the screen inside its safe areas, without its frame, and is
   laid out and drawn again at its size (main.js follows the root's and the
   canvas's size). "Leave full screen" keeps the top middle, over a band of
   its own above the HUD, and the menus start under it. With side columns
   the board takes the whole height, so the button moves to the column's top
   right, beside the pause button and the level's name, and on a phone the
   column keeps 24 px from the screen's corners. */
.game-root:fullscreen {
  --fs-band: max(60px, calc(var(--safe-t) + 52px));
  max-width: none;
  max-height: none;
  border: 0;
  border-radius: 0;
  padding: var(--fs-band) var(--safe-r) 0 var(--safe-l);
}

.game-root:fullscreen .overlay {
  top: var(--fs-band);
  padding: 0 calc(16px + var(--safe-r)) var(--dock-b) calc(16px + var(--safe-l));
}

.game-root.cols:fullscreen {
  --fs-top: max(16px, calc(var(--safe-t) + 8px));
  padding-top: 0;
}

.game-root.cols:fullscreen > .hud {
  padding-top: var(--fs-top);
  padding-left: 24px;
}

.game-root.cols:fullscreen > .dock {
  padding-left: 24px;
}

.game-root.cols:fullscreen .overlay {
  top: max(68px, calc(var(--safe-t) + 60px));
}

/* Paused menus do not need the stuck/aim bar behind them. Reclaim its room
   when the site header returns on a sideways phone. */
html:not(.pg-in-play) .game-root > .bars { display: none; }

.playing.cols > .bars .dock-bar {
  padding-bottom: 0;
}

.game-root.cols:fullscreen > .stage canvas {
  top: var(--safe-t);
  height: calc(100% - var(--safe-t) - var(--home-b));
}

.game-root.cols.bars-on:fullscreen > .stage canvas {
  height: calc(100% - var(--safe-t));
}

/* The goals keep 8 px under "Leave full screen", beside the pause button. */
.game-root.cols:fullscreen > .hud {
  gap: 10px;
}

.game-root.cols:fullscreen .hud-a {
  padding-right: 52px;
}

.game-root.cols .am-fs-exit {
  top: var(--fs-top, max(8px, var(--safe-t)));
  left: calc(var(--safe-l) + var(--side-w) - 60px);
}

@media (prefers-reduced-motion: reduce) {
  /* Calm decoration; action and result feedback keep their timing. */
  .paper-cranes { display: none; }
  .spinner { animation: none; }
  #game-root { transition: none; }
}

/* Compact phones: use the space for the mat. Menus keep the exit's upper
   band; in upright play it joins the dock with its own 44 px place. */
@media (max-width: 520px) {
  html.pg-in-play .game-root.playing:not(.cols):fullscreen {
    padding-top: 0;
  }
  html.pg-in-play .game-root.playing:not(.cols):fullscreen > .hud {
    padding-top: max(16px, var(--safe-t));
    padding-left: 24px;
  }
  html.pg-in-play .game-root.playing:not(.cols):fullscreen > .dock {
    padding-right: calc(68px + var(--safe-r));
  }
  html.pg-in-play .game-root.playing:not(.cols):fullscreen .am-fs-exit {
    top: auto;
    left: auto;
    right: calc(16px + var(--safe-r));
    bottom: var(--dock-b);
  }
}

@media (max-width: 520px), (max-width: 700px) and (max-height: 400px) {
  .playing .booster {
    gap: 4px;
    padding: 5px 3px;
  }
  .playing .b-name { display: none; }
  .playing .b-count { min-width: 18px; padding: 1px 2px; }
  .playing .btn-text { padding-inline: 2px; }
}

@media (max-width: 700px) and (max-height: 400px) {
  .game-root { --side-w: 180px; }
  .playing.cols .hud-mode { white-space: normal; overflow: visible; font-size: var(--t-min); }
}

.stage canvas.pg-motion[hidden] { display: none; }
