/* ═══════════════════════════════════════════════════
   Dad in Action — style.css
   Desert / Arabian Nights palette
   ═══════════════════════════════════════════════════ */

:root {
  /* Palette */
  --sky:        #5b8dd9;
  --sand:       #e8761a;
  --sand-light: #f5a623;
  --sand-dark:  #c45e10;
  --cream:      #fff8ee;
  --warm-white: #fffbf4;
  --brown:      #7a3b10;
  --red:        #e03030;
  --red-muted:  #c0a0a0;

  /* HUD chrome */
  --pill-bg:    rgba(255,255,255,0.92);
  --pill-shadow: 0 3px 12px rgba(0,0,0,0.18), inset 0 1px 0 rgba(255,255,255,0.9);
  --circle-bg:  #f5a623;
  --circle-shadow: 0 4px 0 #c45e10, 0 6px 14px rgba(0,0,0,0.25);

  /* Layout */
  --toolbar:   64px;
  --touch:     108px;
  --nav-band:  86px;   /* landscape: canvas above, all navigation below */

  /* Space kept clear for the phone's own system bars.
     In a browser the chrome already sits above the page, so this is 0 (or
     the notch inset on a full-bleed iOS page). Inside an app's WebView the
     page usually starts at the very top of the screen, under the status
     bar — there the host app passes its real inset with #safeTop=<px> and
     JS puts it in --embed-safe-top. See applySafeArea() in game.js. */
  --safe-top:    max(env(safe-area-inset-top, 0px),    var(--embed-safe-top, 0px));
  --safe-bottom: max(env(safe-area-inset-bottom, 0px), var(--embed-safe-bottom, 0px));

  /* ── Canvas HUD tokens ──────────────────────────────────────────────
     CSS cannot style what the engine paints on the canvas, so the engine
     reads these instead (see THEME in js/game.js). A theme in css/themes/
     overrides them alongside the ordinary CSS and restyles both halves of
     the UI from one file. --game-pixelated: 1 switches canvas scaling to
     nearest-neighbour for pixel-art games. */
  --game-font-display:  'Fredoka One', cursive;
  --game-font-body:     'Nunito', sans-serif;
  --game-hud-pill-bg:   rgba(0,0,0,0.35);
  --game-hud-pill-text: rgba(255,255,255,0.85);
  --game-chip-bg:       rgba(10,18,42,0.62);
  --game-paused-bg:     rgba(20,50,120,0.72);
  --game-paused-text:   #f5a623;
  --game-paused-sub:    rgba(255,248,238,0.6);
  --game-lock-color:    rgba(255,248,238,0.45);
  /* --game-gutter: colour of the letterbox bands around the canvas. Left
     undefined here so an unthemed game keeps using the level's own sky; a
     theme sets it when a bright sky would clash with dark chrome. */

  /* Corner radius the engine uses for the canvas HUD pills and meters, and
     the stair-block size when those corners should be stepped (0 = curved) */
  --game-hud-radius:    10;
  --game-hud-step:      0;
  --game-pixelated:     0;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  width: 100%; height: 100%;
  background: var(--sky);
  overflow: hidden;
  font-family: 'Nunito', 'Fredoka One', sans-serif;
  /* Nothing on screen is text worth selecting — a tap on a label
     button must never turn into a text selection or callout menu. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;   /* no double-tap zoom */
}

button {
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* The play surface and the control pad take NO browser gestures at all.
   iOS ignores user-scalable=no, and once the browser decides a touch is
   the start of a pinch or a pan it CANCELS that touch — which is what
   dropped a held direction button as soon as a second finger landed on
   JUMP. The overlay is deliberately left alone so its level list still
   scrolls normally. */
#stage, #gameCanvas,
#touch, #touch button,
#toolbar, #toolbar button,
#overlay, #overlay button {
  touch-action: none;
}
/* …except the one thing that really does scroll: the level list. */
.overlay-body { touch-action: pan-y; }

/* ══════════════════════════════════════════════════
   TOP HUD BAR
   ══════════════════════════════════════════════════ */
#toolbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  /* The bar grows by the status-bar inset rather than being pushed down,
     so its own height still describes the strip the canvas has to clear
     (scaleToStage measures offsetHeight). */
  height: calc(var(--toolbar) + var(--safe-top));
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--safe-top) max(14px, env(safe-area-inset-right, 0px)) 0 max(14px, env(safe-area-inset-left, 0px));
  gap: 10px;
  z-index: 30;
  /* subtle gradient strip — not opaque, game sky shows through edges */
  background: linear-gradient(180deg, rgba(0,0,0,0.18) 0%, rgba(0,0,0,0) 100%);
  /* Only the pills and buttons take taps; the gaps between them fall
     through to the stage, where a tap is a jump. */
  pointer-events: none;
}
#toolbar > *, #toolbar button { pointer-events: auto; }

/* ── Circular icon buttons (pause / music) ── */
.hud-circle-btn {
  flex-shrink: 0;
  width: 46px; height: 46px;
  border-radius: 50%;
  border: none;
  background: var(--circle-bg);
  color: var(--brown);
  box-shadow: var(--circle-shadow);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: transform .1s, box-shadow .1s;
  -webkit-tap-highlight-color: transparent;
}
.hud-circle-btn:active {
  transform: translateY(2px);
  box-shadow: 0 2px 0 var(--sand-dark), 0 3px 8px rgba(0,0,0,0.2);
}

/* Right-hand button group (music + full screen) */
.hud-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
/* Only one of the two icons shows, depending on the current state */
#btnFull .ico-exit  { display: none; }
body.is-fullscreen #btnFull .ico-enter { display: none; }
body.is-fullscreen #btnFull .ico-exit  { display: block; }
/* No fullscreen API (iPhone Safari) — nothing to offer, so don't tease */
body.no-fullscreen #btnFull { display: none; }

/* ── White pill panels ── */
.hud-pill {
  background: var(--pill-bg);
  box-shadow: var(--pill-shadow);
  border-radius: 30px;
  padding: 6px 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-width: 110px;
}

/* Stars row */
.hud-stars {
  display: flex;
  gap: 2px;
}
.star {
  font-size: 18px;
  line-height: 1;
  color: #d0d0d0;
  text-shadow: 0 1px 2px rgba(0,0,0,0.1);
  transition: color .3s, transform .3s;
}
.star.lit {
  color: var(--sand-light);
  text-shadow: 0 0 6px rgba(245,166,35,0.7);
  transform: scale(1.15);
}
/* Default first two stars lit to match mockup */
.star.s1, .star.s2 { color: var(--sand-light); }

.hud-score-label {
  font-family: 'Fredoka One', cursive;
  font-size: 18px;
  color: var(--sand);
  letter-spacing: 0.5px;
  white-space: nowrap;
}
.hud-score-label span {
  color: var(--brown);
  font-weight: 900;
}

/* Timer pill */
.hud-timer {
  min-width: 90px;
  font-family: 'Fredoka One', cursive;
  font-size: 18px;
  color: var(--brown);
  letter-spacing: 1px;
}

/* ── Centre: title banner + hearts ── */
.hud-centre {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.hud-title-banner {
  background: linear-gradient(180deg, var(--sand-light) 0%, var(--sand) 100%);
  box-shadow: 0 4px 0 var(--sand-dark), 0 6px 16px rgba(0,0,0,0.25);
  border-radius: 12px;
  padding: 5px 22px;
  position: relative;
}
/* Ribbon tails */

.hud-title-banner::after, .hud-title-banner::before {
  position: absolute;
  left: -50px;
  top: 10px;
  width: 60px;
  height: 50px;
  background-image: url('../img/ribbon-left.png');
  background-repeat: no-repeat;
  background-position: top left;
  background-size: 100%;
  border-radius: 10px;
  z-index: -1;
  content: "";
}

.hud-title-banner::after {
  left: auto;
  right: -50px;
  background-image: url('../img/ribbon-right.png');
}

#gameTitle {
  font-family: 'Fredoka One', cursive;
  font-size: 21px;
  color: var(--warm-white);
  text-shadow: 0 1px 3px rgba(0,0,0,0.3);
  letter-spacing: 0.5px;
  white-space: nowrap;
}

/* Lives hearts */
.hud-lives {
  display: flex;
  gap: 3px;
  border-radius: 25px;
  background: var(--Linear, linear-gradient(180deg, #F5ECE5 69.77%, #FFD2AF 100%));
  padding: 20px 10px 3px 15px;
  margin-top: -12px;
}
.heart {
  font-size: 18px;
  line-height: 1;
  display: inline-block;
  width: 32px;
  height: 32px;
  margin-right: 10px;
  transition: all 0.3s ease-out;
  background-image: url('../img/ico-heart.png');
  background-repeat: no-repeat;
  background-size: 100%;
}
.heart.full  { color: var(--red); text-shadow: 0 0 6px rgba(220,50,50,0.5); }
.heart.empty { background-image: url('../img/ico-heart-gone.png'); }
.heart.full.pulse {
  animation: heartbeat .35s ease;
}
@keyframes heartbeat {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.35); }
  100% { transform: scale(1); }
}

/* ══════════════════════════════════════════════════
   STAGE & CANVAS
   ══════════════════════════════════════════════════ */
#stage {
  position: fixed;
  top: 0; left: 0; right: 0; bottom: 0;  /* full screen — HUD floats on top */
  background: var(--sky);
  overflow: hidden;
}

#gameCanvas {
  position: absolute;
  top: 0; left: 0;
  transform-origin: top left;
  display: block;
}
/* Added by the engine when the theme sets --game-pixelated: 1 */
#gameCanvas.pixelated {
  image-rendering: pixelated;
  image-rendering: crisp-edges;
}

/* ══════════════════════════════════════════════════
   OVERLAY (start / level-complete / error)
   ══════════════════════════════════════════════════ */

/* Outer shell — fills the canvas, flex column, no padding of its own */
#overlay {
  position: absolute;
  top: 0; left: 0;
  transform-origin: top left;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background: rgba(22, 45, 110, 0.94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: opacity .3s;
  pointer-events: all;
  color: var(--warm-white);
  overflow: hidden;
}
#overlay.hidden { opacity: 0; pointer-events: none; }

/* ── Sticky header: title + score — never scrolls away ── */
.overlay-header {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 22px 28px 12px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
  text-align: center;
}

/* A full overlay states the title itself and lives mean nothing before play,
   so the toolbar's banner and hearts step aside while one is open. That frees
   the header from having to clear the floating bar. */
body.overlay-open .hud-title-banner,
body.overlay-open .hud-lives {
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s;
}

#overlay h2 {
  font-family: 'Fredoka One', cursive;
  font-size: clamp(20px, 4vw, 32px);
  color: var(--sand-light);
  text-shadow: 0 2px 8px rgba(0,0,0,0.4);
  line-height: 1.1;
  margin: 0;
}

.overlay-score {
  font-family: 'Fredoka One', cursive;
  font-size: clamp(36px, 8vw, 60px);
  color: var(--sand-light);
  text-shadow: 0 0 20px rgba(245,166,35,0.5), 0 2px 0 var(--sand-dark);
  line-height: 1;
}

.overlay-sub {
  font-size: 13px;
  color: rgba(255,248,238,0.72);
  max-width: 420px;
  line-height: 1.6;
}

.overlay-detail {
  font-size: 12px;
  color: rgba(255,248,238,0.62);
  line-height: 1.8;
}

/* ── Scrollable body: level list ── */
.overlay-body {
  flex: 1 1 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 14px 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  scrollbar-width: thin;
  scrollbar-color: rgba(245,166,35,0.45) transparent;
}
.overlay-body::-webkit-scrollbar { width: 4px; }
.overlay-body::-webkit-scrollbar-thumb { background: rgba(245,166,35,0.45); border-radius: 2px; }

/* ── Sticky footer: action buttons — always visible ── */
.overlay-footer {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  padding: 12px 28px 18px;
  border-top: 1px solid rgba(255,255,255,0.1);
  background: rgba(15, 30, 80, 0.5);
}

.overlay-btns {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

/* Level progress rows (level-complete overlay) */
.level-progress {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  max-width: 440px;
}
.lp-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  padding: 8px 14px;
  border-radius: 10px;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.12);
}
.lp-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  background: rgba(255,255,255,0.2);
  transition: background .3s;
}
.lp-dot.done   { background: var(--sand-light); box-shadow: 0 0 6px rgba(245,166,35,0.7); }
.lp-dot.active { background: #7ee8ff; box-shadow: 0 0 6px rgba(126,232,255,0.7); }
.lp-name  { flex: 1; color: var(--warm-white); text-align: left; }
.lp-name.locked { color: rgba(255,248,238,0.3); }
.lp-score { font-size: 11px; color: var(--sand-light); font-weight: 700; white-space: nowrap; }
.lp-score.empty { color: rgba(255,248,238,0.3); }

/* Level selector buttons — full-width list rows */
.overlay-levels {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  max-width: 440px;
}
.ovl-lvl-btn {
  font-family: 'Nunito', sans-serif;
  font-size: 13px;
  font-weight: 700;
  padding: 10px 16px;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.15);
  background: rgba(255,255,255,0.07);
  color: var(--warm-white);
  cursor: pointer;
  transition: all .15s;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  text-align: left;
}
.ovl-lvl-btn:hover:not(.locked) {
  border-color: var(--sand-light);
  background: rgba(245,166,35,0.15);
  color: var(--sand-light);
}
.ovl-lvl-btn.active {
  background: rgba(232,118,26,0.3);
  border-color: var(--sand-light);
  box-shadow: inset 0 0 0 1px var(--sand-light);
}
.ovl-lvl-btn.locked { opacity: 0.3; cursor: not-allowed; }
.ovl-lvl-btn .lvl-score { font-size: 11px; color: var(--sand-light); font-weight: 700; white-space: nowrap; }
.ovl-lvl-btn.locked .lvl-score { color: rgba(255,248,238,0.35); }

/* ══════════════════════════════════════════════════
   GIFT / POWER-UP CHOICE POPUP
   Reuses the overlay shell but stays translucent so the
   frozen level is still visible behind the choice.
   ══════════════════════════════════════════════════ */
#overlay.gift-modal {
  background: rgba(22, 45, 110, 0.72);
  /* Lighter blur than the full-screen overlays: the level behind is frozen,
     not finished, and should still read as the place you are standing in. */
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  justify-content: center;
}
#overlay.gift-modal .overlay-header,
#overlay.gift-modal .overlay-footer {
  border: none;
  background: none;
}
#overlay.gift-modal .overlay-body { flex: 0 1 auto; }
#overlay.gift-modal .overlay-footer { padding-top: 0; }

/* Title row: the game's own art sits beside an overlay heading — used by
   the gift popup and the level-complete screen. inline-flex means RTL puts
   the icon on the correct side without extra rules. */
.overlay-title {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.overlay-title-icon {
  width: 48px; height: 48px;
  flex-shrink: 0;
  display: block;
}

/* Locked-level marker, when the game opts into ui.lockedIcon. Sits inline
   in the level row where the score would otherwise be. */
.ui-lock-icon {
  width: 18px; height: 18px;
  display: inline-block;
  vertical-align: -4px;
}

.gift-cards {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
  align-items: stretch;
}

.gift-card {
  --pu-color: var(--sand-light);
  position: relative;
  font-family: 'Nunito', sans-serif;
  width: 152px;
  padding: 14px 10px 12px;
  border-radius: 16px;
  border: 2px solid rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.08);
  color: var(--warm-white);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  transition: transform .12s, border-color .12s, background .12s, box-shadow .12s;
}
.gift-card:hover,
.gift-card:focus-visible {
  border-color: var(--pu-color);
  background: rgba(255,255,255,0.14);
  transform: translateY(-3px);
  box-shadow: 0 8px 22px rgba(0,0,0,0.35);
  outline: none;
}
.gift-card:active { transform: translateY(0); }

.gift-card-num {
  position: absolute;
  top: 6px; inset-inline-start: 8px;
  font-size: 10px;
  font-weight: 900;
  width: 16px; height: 16px;
  line-height: 16px;
  text-align: center;
  border-radius: 50%;
  color: rgba(255,248,238,0.75);
  background: rgba(0,0,0,0.28);
}

.gift-card-icon {
  width: 64px; height: 64px;
  display: block;
}

.gift-card-name {
  font-size: 13px;
  font-weight: 800;
  line-height: 1.2;
  color: var(--pu-color);
  text-align: center;
}

.gift-keys {
  display: inline-block;
  unicode-bidi: isolate;
  font-weight: 800;
  color: rgba(255,248,238,0.85);
}

.gift-card-dur {
  font-size: 11px;
  font-weight: 700;
  color: rgba(255,248,238,0.6);
}

/* Text column of a card — keeps name, cost and description together so the
   phone layout can lay them beside the icon without extra markup. */
.gift-card-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

/* Optional explainer — only rendered when the game supplies one */
.gift-card-desc {
  font-size: 11px;
  line-height: 1.45;
  color: rgba(255,248,238,0.55);
  text-align: center;
  margin-top: 2px;
}

/* Phones: the three cards go in a column of compact rows so they all
   fit inside the (short) portrait play area without scrolling. */
@media (orientation: portrait) and (max-width: 900px) {
  .gift-cards { flex-direction: column; width: 100%; max-width: 300px; }
  .gift-card {
    width: 100%;
    flex-direction: row;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    padding-inline-start: 30px;
    text-align: start;
  }
  .gift-card-icon { width: 40px; height: 40px; flex-shrink: 0; }
  .gift-card-name { text-align: start; }
  .gift-card-desc { text-align: start; }
  /* Name, cost and description stack in the row's text column */
  .gift-card-body { flex: 1; display: flex; flex-direction: column; gap: 2px; }
  .gift-card-num  { top: 50%; transform: translateY(-50%); }
}

/* ══════════════════════════════════════════════════
   START SCREEN SHOWCASE
   ══════════════════════════════════════════════════ */

/* The character running the length of the title screen */
.player-strip {
  display: block;
  max-width: 100%;
}

/* Everything there is to collect, and what it is worth */
.reward-showcase {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  width: 100%;
  flex-shrink: 0;
}
/* In the level-complete body there is room to wrap, unlike the start
   screen's footer where a second row would push the button off. */
.overlay-body .reward-strip { flex-wrap: wrap; overflow-x: visible; }
.reward-showcase-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(255,248,238,0.45);
}
/* One row that scrolls sideways rather than wrapping — wrapping to a second
   row pushes the Start button off a 450px-tall screen. */
.reward-strip {
  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  gap: 6px;
  max-width: 100%;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
}
.reward-strip::-webkit-scrollbar { display: none; }
.reward-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  flex: 0 0 auto;
  padding: 3px 6px;
  border-radius: 8px;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.12);
}
.reward-chip-icon { width: 26px; height: 26px; display: block; }
.reward-chip-pts {
  font-size: 11px;
  font-weight: 800;
  color: var(--sand-light);
  white-space: nowrap;
}

/* ══════════════════════════════════════════════════
   ENEMY PRESENTATION (optional level intro)
   ══════════════════════════════════════════════════ */
.enemy-intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  max-width: 380px;
}

/* The pacing stage — a strip the enemy walks across */
.enemy-intro-stage {
  width: 240px; height: 92px;
  display: block;
  border-radius: 12px;
  background: rgba(0,0,0,0.16);
}

.enemy-intro-text {
  font-size: 13px;
  line-height: 1.6;
  text-align: center;
  color: rgba(255,248,238,0.72);
}

/* Key hints */
.key-row { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.key {
  font-size: 10px;
  padding: 4px 10px;
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 5px;
  background: rgba(255,255,255,0.08);
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--warm-white);
}
.key span { color: rgba(255,248,238,0.5); }

/* Generic overlay buttons */
.btn {
  font-family: 'Fredoka One', cursive;
  font-size: 14px;
  padding: 10px 26px;
  border-radius: 30px;
  border: none;
  background: var(--sand);
  color: var(--warm-white);
  box-shadow: 0 4px 0 var(--sand-dark), 0 6px 16px rgba(0,0,0,0.2);
  cursor: pointer;
  transition: transform .1s, box-shadow .1s;
  letter-spacing: 0.3px;
}
.btn:hover { background: var(--sand-light); }
.btn:active {
  transform: translateY(2px);
  box-shadow: 0 2px 0 var(--sand-dark), 0 3px 8px rgba(0,0,0,0.15);
}
.btn.primary { background: var(--sand); }
.btn.danger  { background: var(--red); box-shadow: 0 4px 0 #a01818, 0 6px 16px rgba(0,0,0,0.2); }
.btn.danger:hover { background: #f04040; }

/* ══════════════════════════════════════════════════
   TOUCH CONTROLS
   ══════════════════════════════════════════════════ */
#touch {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  /* Height grows by the bottom inset so the buttons keep their size and
     stay clear of a gesture bar. */
  height: calc(var(--touch) + var(--safe-bottom));
  display: none;
  align-items: center;
  justify-content: space-between;   /* move far left, jump far right */
  padding: 0 max(20px, env(safe-area-inset-right, 0px)) var(--safe-bottom) max(20px, env(safe-area-inset-left, 0px));
  background: linear-gradient(0deg, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0) 100%);
  z-index: 20;
  /* The bar itself must never eat a tap — only its buttons do. Otherwise
     it swallows whatever sits under it, which is what made the Start
     button unclickable in landscape. */
  pointer-events: none;
}
#touch button { pointer-events: auto; }
@media (pointer: coarse), (max-width: 800px) { #touch { display: flex; } }

/* While any overlay is up the controls step aside — hidden via
   visibility, not display, so the band keeps its size and the canvas
   doesn't jump between the menu and play. The bar itself stays put so
   the landscape band keeps its backdrop under the toolbar. No
   transition: a control must never be caught half-faded. */
body.overlay-visible #touch .dpad,
body.overlay-visible #touch .jump-btn { visibility: hidden; }

/* Left and right sit flush against each other as one joined control —
   a thumb rolls between them without crossing a gap. */
.dpad {
  display: flex;
  /* Physical controls: left is always on the left, even in RTL, where a
     flex row would otherwise swap the two arrows. */
  direction: ltr;
  gap: 0;
  border-radius: 22px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0,0,0,0.28);
}
.dpad-btn {
  width: 84px; height: 76px;
  border: none;
  border-radius: 0;
  background: rgba(255,255,255,0.20);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  color: white;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
  transition: background .08s;
}
.dpad-btn + .dpad-btn { border-left: 2px solid rgba(0,0,0,0.22); }
.dpad-btn svg {
  width: 34px; height: 34px;
  pointer-events: none;   /* taps always land on the button itself */
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.35));
}
.dpad-btn.pressed {
  background: rgba(245,166,35,0.62);
}

/* Jump — same footprint as one d-pad key, opposite thumb */
.jump-btn {
  width: 92px; height: 76px;
  border: none;
  border-radius: 22px;
  background: linear-gradient(180deg, var(--sand-light) 0%, var(--sand) 100%);
  box-shadow: 0 4px 0 var(--sand-dark), 0 6px 16px rgba(0,0,0,0.3);
  color: var(--brown);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
  transition: transform .08s, box-shadow .08s, background .08s;
}
.jump-btn svg {
  width: 36px; height: 36px;
  pointer-events: none;
}
.jump-btn.pressed {
  background: var(--sand);
  transform: translateY(3px);
  box-shadow: 0 1px 0 var(--sand-dark), 0 3px 8px rgba(0,0,0,0.22);
}

/* ══════════════════════════════════════════════════
   LANDSCAPE NAVIGATION BAND  (body.nav-band, set by
   scaleToStage when the pad is in use and the screen
   is wider than it is tall)

   One strip under the canvas holds everything: d-pad
   far left, jump far right, the whole toolbar in the
   middle. Nothing floats over the play area, so the
   canvas gets the entire space above the band.
   ══════════════════════════════════════════════════ */
body.nav-band #touch {
  height: calc(var(--nav-band) + var(--safe-bottom));
  background: linear-gradient(180deg, rgba(0,0,0,0.28) 0%, rgba(0,0,0,0.45) 100%);
}

body.nav-band #toolbar {
  top: auto; bottom: 0;
  height: calc(var(--nav-band) + var(--safe-bottom));
  /* left/right insets are set inline by scaleToStage — they track the
     real measured width of the d-pad and the jump key, on the correct
     side for the writing direction. */
  justify-content: center;
  gap: 8px;
  padding: 0 8px var(--safe-bottom);
  background: none;
  z-index: 21;
}

/* Compact toolbar: it now shares one strip with both controls, so every
   piece has to be able to give ground rather than overflow into its
   neighbours on a short phone. */
body.nav-band .hud-circle-btn { width: 38px; height: 38px; }
body.nav-band #toolbar > *,
body.nav-band .hud-centre > * { min-width: 0; }
body.nav-band .hud-pill { min-width: 0; padding: 4px 12px; flex-shrink: 1; }
/* An open overlay already hides the hearts; in the band they should give
   their space back too, not just turn invisible. */
body.nav-band.overlay-open .hud-lives { display: none; }
body.nav-band .hud-score-label,
body.nav-band .hud-timer { font-size: 14px; }
body.nav-band .star { font-size: 14px; }

/* The title sits this layout out entirely: the band is a strip shared
   with both controls, the menu already names the game, and mid-run the
   hearts are what the middle is for. They take it on their own, as a
   plain pill rather than a tab tucked under a banner. */
body.nav-band .hud-title-banner { display: none; }
body.nav-band .hud-centre { flex: 1 1 auto; }
body.nav-band .hud-lives {
  margin-top: 0;
  padding: 5px 11px;
  border-radius: 25px;
}
body.nav-band .heart { width: 22px; height: 22px; margin-right: 4px; }
body.nav-band .heart:last-child { margin-right: 0; }
body.nav-band .rtl .heart,
.rtl body.nav-band .heart { margin-right: 0; margin-left: 4px; }

/* A pill must clip rather than spill into its neighbour if it ever does
   get squeezed below its text. */
body.nav-band .hud-pill { overflow: hidden; }

/* The controls get a little shorter so the band stays slim on a phone
   held sideways, where vertical space is what's scarce. */
body.nav-band .dpad-btn { width: 82px; height: 62px; }
body.nav-band .jump-btn { width: 88px; height: 62px; }
body.nav-band .dpad-btn svg { width: 30px; height: 30px; }
body.nav-band .jump-btn svg { width: 32px; height: 32px; }

/* ── Narrow landscape (iPhone SE and friends) ──────────────────────
   Under ~740px the band can't hold the rest of the toolbar between the
   two controls without the pills colliding, so the stars go too — score,
   lives and timer are what a player actually reads mid-run. */
@media (max-width: 740px) {
  body.nav-band .hud-stars { display: none; }
  body.nav-band .hud-lives { padding: 5px 9px; }
  body.nav-band .heart { width: 17px; height: 17px; margin-right: 3px; }
  body.nav-band .hud-score-label,
  body.nav-band .hud-timer { font-size: 13px; }
  body.nav-band .hud-pill { padding: 3px 9px; }
  body.nav-band .hud-circle-btn { width: 34px; height: 34px; }
  body.nav-band #toolbar { gap: 6px; }
  body.nav-band .hud-right { gap: 6px; }
  body.nav-band .dpad-btn { width: 68px; }
  body.nav-band .jump-btn { width: 74px; }
}

/* ── Landscape menu: two columns ──────────────────────────────────
   A phone on its side is wide and short. Stacked header → list →
   footer left the list two rows tall and everything cramped, so the
   identity and the level list take the left half and the rewards,
   controls and Start take the right. */
body.nav-band #overlay:not(.gift-modal) {
  display: grid;
  /* minmax(0, …), not 1fr: a bare 1fr is minmax(auto, 1fr), so the widest
     item in a column (the row of reward chips) can push that column past
     its share — which is exactly how the right half ended up swallowing
     the left. With a 0 floor the halves stay equal and the content inside
     wraps instead. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas:
    "header aside"
    "body   aside";
  column-gap: 8px;
  align-items: stretch;
}
body.nav-band #overlay:not(.gift-modal) .overlay-header {
  grid-area: header;
  padding: 12px 16px 6px;
  border-bottom: none;
}
body.nav-band #overlay:not(.gift-modal) .overlay-body {
  grid-area: body;
  padding: 0 16px 14px;
  justify-content: flex-start;
}
body.nav-band #overlay:not(.gift-modal) .overlay-footer {
  grid-area: aside;
  justify-content: center;
  gap: 14px;
  padding: 14px 18px;
  border-top: none;
  border-left: 1px solid rgba(255,255,255,0.1);
  background: rgba(15, 30, 80, 0.35);
}
/* Start is the one thing a thumb reaches for — and with the items
   preview out of this column, it can take the room they were using. */
body.nav-band #overlay:not(.gift-modal) #ob-start {
  font-size: 19px !important;
  padding: 17px 56px !important;
  border-radius: 40px;
}
body.nav-band #overlay:not(.gift-modal) .overlay-levels,
body.nav-band #overlay:not(.gift-modal) .level-progress { max-width: none; }
body.nav-band #overlay:not(.gift-modal) h2 { font-size: clamp(18px, 3.4vw, 28px); }
/* A phone on its side has roughly 300px of height for the whole menu, and
   the items preview is the one thing a player doesn't need before
   starting — the level-complete tally of what was actually collected
   stays, in both orientations. */
body.nav-band .reward-preview { display: none; }

/* ── Gift popup in the band ───────────────────────────────────────
   Stacked (title → cards → hint) the cards had no height left and got
   cut off. Landscape turns the modal on its side instead: the heading
   and its icon move beside the cards, on one line with them, and the
   cards share the width that frees up. */
body.nav-band #overlay.gift-modal {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  grid-template-areas:
    "head cards"
    "foot cards";
  align-content: center;
  align-items: center;
  column-gap: 16px;
  padding: 10px 16px;
}
/* Both rows of the left column are capped, or the hint sentence's
   max-content width decides how much is left for the cards. */
body.nav-band #overlay.gift-modal .overlay-header,
body.nav-band #overlay.gift-modal .overlay-footer { max-width: 27vw; }
body.nav-band #overlay.gift-modal .overlay-header {
  grid-area: head;
  align-items: flex-start;
  text-align: start;
  padding: 0;
  gap: 2px;
}
body.nav-band #overlay.gift-modal .overlay-body {
  grid-area: cards;
  padding: 0;
  overflow: visible;
}
body.nav-band #overlay.gift-modal .overlay-footer {
  grid-area: foot;
  align-items: flex-start;
  text-align: start;
  padding: 4px 0 0;
}
body.nav-band #overlay.gift-modal .overlay-title { justify-content: flex-start; gap: 8px; }
body.nav-band #overlay.gift-modal .overlay-title-icon { width: 34px; height: 34px; }
body.nav-band #overlay.gift-modal h2 { font-size: 19px; }
body.nav-band #overlay.gift-modal .overlay-sub { font-size: 11px; line-height: 1.35; }
body.nav-band #overlay.gift-modal .overlay-detail { font-size: 10px; }

/* Cards share the remaining width instead of wrapping out of sight.
   width:100% matters — .overlay-body centres its children, so the row
   would otherwise shrink to fit and leave the column half empty. */
body.nav-band #overlay.gift-modal .gift-cards {
  flex-wrap: nowrap;
  gap: 8px;
  align-items: stretch;
  width: 100%;
}
body.nav-band #overlay.gift-modal .gift-card {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  padding: 10px 8px 9px;
  border-radius: 13px;
}
body.nav-band #overlay.gift-modal .gift-card-icon { width: 40px; height: 40px; }
body.nav-band #overlay.gift-modal .gift-card-name { font-size: 12px; }
body.nav-band #overlay.gift-modal .gift-card-desc { font-size: 10px; line-height: 1.3; }
body.nav-band #overlay.gift-modal .gift-card-num  { font-size: 10px; }

/* Everything in the right half wraps rather than forcing the column wider */
body.nav-band #overlay:not(.gift-modal) .overlay-header,
body.nav-band #overlay:not(.gift-modal) .overlay-body,
body.nav-band #overlay:not(.gift-modal) .overlay-footer { min-width: 0; }
body.nav-band #overlay:not(.gift-modal) .reward-strip {
  flex-wrap: wrap;
  justify-content: center;
  overflow-x: visible;
  row-gap: 6px;
}
body.nav-band #overlay:not(.gift-modal) .overlay-btns { width: 100%; }

/* ── "Turn your phone" note ───────────────────────────────────────
   Portrait plays fine — landscape just shows more, so this is a hint,
   not a wall. Shown only on a touch screen held upright; the class is
   re-evaluated on every rotation. */
.rotate-hint { display: none; }
body.touch-portrait .rotate-hint {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 2px;
  padding: 7px 14px;
  border-radius: 20px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.14);
  font-size: 12px;
  line-height: 1.35;
  color: rgba(255,248,238,0.78);
  text-align: center;
}
.rotate-hint svg {
  width: 18px; height: 18px;
  flex-shrink: 0;
  color: var(--sand-light);
}

/* ══════════════════════════════════════════════════
   PORTRAIT / PHONE HUD
   Two rows: title on top, lives + timer below, so the
   bar stays narrow enough for a phone screen.
   ══════════════════════════════════════════════════ */
@media (orientation: portrait) and (max-width: 900px) {
  #toolbar {
    height: auto;
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "pause title music"
      "score lives timer";
    align-items: center;
    gap: 6px 8px;
    /* The status-bar inset is added to the top padding — this is the case
       that bites in an app WebView, where the page starts under the bar. */
    padding: calc(8px + var(--safe-top)) 10px 10px;
  }

  /* Lift the title and the hearts out of .hud-centre so each can be
     placed on its own row of the toolbar grid. */
  .hud-centre { display: contents; }

  /* start/end are direction-aware, so RTL mirrors the bar on its own */
  #btnPause { grid-area: pause; justify-self: start; }
  .hud-right { grid-area: music; justify-self: end; }
  .hud-title-banner { grid-area: title; justify-self: center; max-width: 100%; padding: 4px 16px; }
  .hud-lives  { grid-area: lives; justify-self: center; margin-top: 0; padding: 5px 10px; }
  #hudScore   { grid-area: score; justify-self: start; }
  .hud-timer  { grid-area: timer; justify-self: end; }

  #gameTitle {
    font-size: 16px;
    white-space: normal;
    line-height: 1.2;
    display: block;
    text-align: center;
  }

    .reward-chip-icon { width: 22px; height: 22px; }
  .reward-chip    { padding: 2px 5px; }
  .reward-strip   { justify-content: flex-start; }

  .hud-circle-btn { width: 40px; height: 40px; }
  .hud-pill { min-width: 0; padding: 4px 12px; }
  .hud-score-label, .hud-timer { font-size: 15px; }
  .star { font-size: 15px; }
  .heart { width: 24px; height: 24px; margin-right: 4px; }
  .heart:last-child { margin-right: 0; }
}

/* ══════════════════════════════════════════════════
   PORTRAIT MENU  (body.touch-portrait)

   A phone held upright is narrow enough that the menu
   has to use every pixel of it: full-bleed wrappers,
   nothing that can scroll out of sight sideways, and
   the reading order a player needs — what you collect,
   the button that starts it, then how to play.
   ══════════════════════════════════════════════════ */
body.touch-portrait .overlay-body {
  width: 100%;
  padding: 10px 8px;
}
body.touch-portrait .overlay-footer {
  width: 100%;
  padding: 10px 8px 14px;
  gap: 8px;
}
body.touch-portrait .overlay-header { padding: 14px 10px 10px; }

/* The footer is a flex column, so order rearranges it without touching
   the markup (which stays in its desktop reading order). */
body.touch-portrait .overlay-footer .reward-showcase { order: 1; }
body.touch-portrait .overlay-footer .overlay-btns    { order: 2; }
body.touch-portrait .overlay-footer .key-row         { order: 3; }
body.touch-portrait .overlay-footer .rotate-hint     { order: 4; }

/* Every child spans the width rather than sitting in a centred box */
body.touch-portrait .overlay-levels,
body.touch-portrait .level-progress,
body.touch-portrait .reward-showcase,
body.touch-portrait .overlay-btns { width: 100%; max-width: none; }

/* Items wrap onto a second row instead of scrolling off the right edge,
   and sit closer together so they usually don't have to. */
body.touch-portrait .reward-strip {
  flex-wrap: wrap;
  justify-content: center;
  overflow-x: visible;
  gap: 3px;
}
body.touch-portrait .reward-chip { gap: 2px; padding: 2px 5px; }

/* A start button that can never be clipped, and is a bigger target */
body.touch-portrait #ob-start {
  width: 100%;
  max-width: 300px;
  padding: 13px 20px !important;
  font-size: 16px !important;
}
body.touch-portrait .overlay-btns .btn { max-width: 100%; }

/* The gift popup has the same "can't see the last card" problem upright,
   just milder — the heading was eating the room the third card needed. */
body.touch-portrait #overlay.gift-modal .overlay-header { padding: 10px 12px 4px; gap: 2px; }
body.touch-portrait #overlay.gift-modal .overlay-title-icon { width: 34px; height: 34px; }
body.touch-portrait #overlay.gift-modal h2 { font-size: 20px; }
body.touch-portrait #overlay.gift-modal .overlay-sub { font-size: 12px; }
body.touch-portrait #overlay.gift-modal .gift-card { padding: 7px 10px; gap: 10px; }
body.touch-portrait #overlay.gift-modal .gift-card-desc { font-size: 11px; line-height: 1.3; }
body.touch-portrait #overlay.gift-modal .gift-cards { gap: 8px; }

/* Short phones (and anything under ~700px tall): the menu is taller than
   the space it has, and a footer that overflows takes the Start button
   off the bottom with it. Give back the height the running character and
   the paddings are using rather than letting anything get clipped. */
@media (max-height: 700px) {
  body.touch-portrait .player-strip {
    width: auto !important;
    height: auto !important;
    max-height: 76px;
  }
  body.touch-portrait #overlay h2 { font-size: 20px; }
  body.touch-portrait .overlay-header { padding: 8px 10px 6px; gap: 2px; }
  body.touch-portrait .overlay-body   { padding: 6px 8px; }
  body.touch-portrait .overlay-footer { gap: 6px; padding: 8px 8px 10px; }
  body.touch-portrait #ob-start {
    padding: 11px 18px !important;
    font-size: 15px !important;
  }
  body.touch-portrait .rotate-hint { padding: 5px 10px; font-size: 11px; }

  /* Smaller item chips pack onto fewer rows, which is where most of the
     reclaimed height comes from — and every chip still shows. */
  body.touch-portrait .reward-chip-icon { width: 20px; height: 20px; }
  body.touch-portrait .reward-chip { padding: 2px 4px; gap: 2px; }
  body.touch-portrait .reward-chip-pts { font-size: 11px; }
  body.touch-portrait .reward-showcase { gap: 3px; }
  body.touch-portrait .reward-showcase-label { font-size: 9px; }
}

/* Shorter still — the level list is the one thing that must not vanish */
@media (max-height: 620px) {
  body.touch-portrait .player-strip { max-height: 58px; }
  body.touch-portrait #overlay h2 { font-size: 18px; }
}

/* ══════════════════════════════════════════════════
   RTL SUPPORT (Arabic, Hebrew, Persian, Urdu)
   Activated when <html dir="rtl" class="rtl"> is set
   by ui-texts.js based on the detected language.
   ══════════════════════════════════════════════════ */

/* Toolbar: mirror the order of the HUD elements */
.rtl #toolbar {
  flex-direction: row-reverse;
}

/* Score pill: keep number after label reading right-to-left */
.rtl .hud-score-label {
  direction: rtl;
}

/* Title banner ribbon tails swap sides */
.rtl .hud-title-banner::before {
  left: auto;
  right: -50px;
  background-image: url('../img/ribbon-right.png');
}
.rtl .hud-title-banner::after {
  right: auto;
  left: -50px;
  background-image: url('../img/ribbon-left.png');
}

/* Hearts row: mirror so the "lost" heart sits on the correct side */
.rtl .hud-lives {
  flex-direction: row-reverse;
  padding: 20px 15px 3px 10px;  /* mirror the asymmetric padding */
}
.rtl .heart {
  margin-right: 0;
  margin-left: 10px;
}

/* Overlay text alignment */
.rtl .overlay-header,
.rtl .overlay-sub,
.rtl .overlay-detail {
  direction: rtl;
}

/* Level list rows: name on the right, score on the left */
.rtl .lp-row,
.rtl .ovl-lvl-btn {
  flex-direction: row-reverse;
  text-align: right;
}
.rtl .lp-name {
  text-align: right;
}

/* Key hints row mirrors */
.rtl .key-row {
  direction: rtl;
}
.rtl .key {
  flex-direction: row-reverse;
}

/* Touch controls: D-pad on the right, jump button on the left for RTL.
   dir="rtl" already runs the flex row right-to-left, so space-between
   mirrors the two controls on its own — adding row-reverse here would
   flip them a second time and undo the mirroring. (.dpad sets
   direction: ltr so ◀ and ▶ keep pointing the way the player moves.) */
/* Keep the left/right arrows pointing the correct physical direction
   — the buttons control physical movement, so we do NOT swap their icons,
   only their container position. The dpad internal order stays the same. */

/* Overlay buttons keep centred layout — no change needed */

/* Timer: numbers stay LTR even in RTL (clock format is universal) */
.rtl .hud-timer span {
  direction: ltr;
  display: inline-block;
}

/* Score value stays LTR (numbers) */
.rtl #hudScoreVal {
  direction: ltr;
  display: inline-block;
}

/* Portrait HUD: dir="rtl" already mirrors the grid columns, so only the
   heart spacing needs undoing here */
@media (orientation: portrait) and (max-width: 900px) {
  .rtl .hud-lives { padding: 5px 10px; }
  .rtl .heart { margin-right: 0; margin-left: 4px; }
  .rtl .heart:last-child { margin-left: 0; }
}
