:root {
  color-scheme: dark;
  --bg: #111f2a;
  --panel: #172935;
  --panel-2: #1b3040;
  --ink: #f8fbfd;
  --muted: #8fa1ae;
  --muted-2: #627582;
  --track: #51616c;
  --green: #e7be52;
  --danger: #ff6e72;

  --shell-max: 620px;
  /* 10% slimmer than the previous cards, while preserving their exact height. */
  --card-w: clamp(61.2px, 18.63vw, 100.8px);
  --card-h: clamp(87.04px, 26.496vw, 143.36px);
  --card-radius: clamp(12px, 3.3vw, 20px);
  --stack-step: clamp(28px, 8.2vw, 46px);
  --card-shadow-y: clamp(5px, 1.6vw, 8px);
}

* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; background: var(--bg); }
body {
  min-height: 100svh;
  overflow: hidden;
  color: var(--ink);
  background: var(--bg);
  font-family: "Quicksand", ui-rounded, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-weight: 600;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}
button { font: inherit; color: inherit; }
button:focus-visible { outline: 3px solid rgba(255,255,255,.95); outline-offset: 3px; }

.app {
  width: 100%;
  min-height: 100svh;
  display: grid;
  place-items: center;
  background: var(--bg);
}

.game-shell {
  width: min(100%, var(--shell-max));
  height: 100svh;
  min-height: 540px;
  padding:
    max(16px, env(safe-area-inset-top))
    clamp(14px, 4.5vw, 30px)
    max(13px, env(safe-area-inset-bottom));
  display: grid;
  grid-template-rows: auto minmax(250px, 1fr) 16px auto;
  gap: 8px;
  overflow: hidden;
}

/* HUD */
.hud {
  position: relative;
  z-index: 8;
  min-height: 146px;
  padding-top: 2px;
}
.best-score {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: clamp(20px, 6vw, 29px);
  line-height: 1;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.crown {
  color: #ffd635;
  font-size: 1.28em;
  line-height: .8;
  transform: translateY(-1px);
}
.pause-button {
  position: absolute;
  z-index: 20;
  pointer-events: auto;
  top: -2px;
  right: -6px;
  width: 52px;
  height: 52px;
  border: 0;
  padding: 0;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  cursor: pointer;
}
.pause-button span {
  width: 7px;
  height: 31px;
  border-radius: 999px;
  background: #fff;
}
.score {
  padding-top: 42px;
  text-align: center;
  font-size: clamp(48px, 14vw, 82px);
  line-height: .9;
  letter-spacing: -2px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.level-block { margin-top: 18px; }
.level-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 7px;
}
.level-meta strong {
  font-size: clamp(16px, 4.5vw, 23px);
  line-height: 1;
  letter-spacing: .4px;
}
.level-meta span {
  color: #9aabb6;
  font-size: clamp(12px, 3.5vw, 16px);
  font-weight: 700;
}
.progress-track {
  height: 9px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--track);
}
.progress-fill {
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--green);
  transition: width .28s cubic-bezier(.2,.8,.2,1);
}

/* Board: all piles START on exactly the same top line. */
.board-zone {
  position: relative;
  min-height: 0;
  overflow: hidden;
}
.board {
  height: 100%;
  min-height: 250px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: stretch;
  gap: clamp(5px, 1.8vw, 11px);
  padding-top: clamp(8px, 2vh, 14px);
}
.lane {
  position: relative;
  min-width: 0;
  height: 100%;
  cursor: pointer;
  border-radius: var(--card-radius);
  transition: transform .12s ease, background-color .12s ease;
  touch-action: manipulation;
}
.lane:hover { background: rgba(255,255,255,.018); }
.pile {
  position: absolute;
  top: 0;
  left: 50%;
  width: var(--card-w);
  height: 100%;
  transform: translateX(-50%);
  pointer-events: none;
}
.empty-hint {
  position: absolute;
  top: 3px;
  left: 50%;
  width: var(--card-w);
  height: var(--card-h);
  transform: translateX(-50%);
  display: grid;
  place-items: center;
  border: 2px dashed rgba(154,171,182,.16);
  border-radius: var(--card-radius);
  color: rgba(154,171,182,.18);
  font-size: clamp(20px, 6vw, 32px);
  font-weight: 700;
}

/* Cards: NO border. One hard shadow directly below, with ZERO blur. */
.card {
  --face: #e7e7e7;
  --card-ink: #414141;
  position: absolute;
  top: calc(var(--stack-index, 0) * var(--stack-step));
  left: 0;
  width: var(--card-w);
  height: var(--card-h);
  border: 0;
  border-radius: var(--card-radius);
  background: transparent;
  color: var(--card-ink);
  box-shadow: 0 var(--card-shadow-y) 0 rgba(3, 10, 17, .36);
  transform-origin: center center;
  perspective: 700px;
  will-change: transform, opacity;
}
.card-inner {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  transform-style: preserve-3d;
}
.card-face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.card-front { background: var(--face); }
.card-back {
  display: grid;
  place-items: center;
  background: #314554;
  color: rgba(255,255,255,.38);
  transform: rotateY(180deg);
}
.card-back span {
  font-size: clamp(24px, 8vw, 42px);
  line-height: 1;
}
.value {
  position: absolute;
  top: 8%;
  left: 9%;
  font-size: clamp(23px, 7vw, 39px);
  line-height: .9;
  letter-spacing: -1.7px;
  font-weight: 700;
}
.fruit-art {
  position: absolute;
  inset: 27% 7% 8%;
  display: grid;
  place-items: center;
}
.fruit-art img {
  width: min(88%, 72px);
  height: auto;
  display: block;
  object-fit: contain;
  image-rendering: auto;
  filter: drop-shadow(0 4px 0 rgba(3, 10, 17, .10));
  pointer-events: none;
}
.under-card { filter: saturate(.97) brightness(.99); }

.tier-0 { --face: #d6b7f5; --card-ink: #60349f; }
.tier-1 { --face: #c9e98b; --card-ink: #3b7228; }
.tier-2 { --face: #ff8d73; --card-ink: #b33224; }
.tier-3 { --face: #ff746a; --card-ink: #ba2421; }
.tier-4 { --face: #ffe189; --card-ink: #9c650c; }
.tier-5 { --face: #f0b45e; --card-ink: #7b4f0d; }
.tier-6 { --face: #86d6cf; --card-ink: #246b67; }
.tier-7 { --face: #8fb9f2; --card-ink: #2e62a5; }
.tier-8 { --face: #d6a0d8; --card-ink: #743776; }
.tier-9 { --face: #c3cad4; --card-ink: #4b5563; }
.tier-10 { --face: #ffd34f; --card-ink: #725600; }

/* lane feedback is deliberately minimal: cards remain visually clean */
.match-lane:not(.blocked-lane) .card:last-of-type { transform: translateY(-2px); }
.drag-valid { background: rgba(255,255,255,.035); }
.drag-match { background: rgba(119,232,120,.07); transform: translateY(-2px); }
.drag-blocked { background: rgba(255,110,114,.05); }
.blocked-lane { cursor: not-allowed; }

.combo {
  position: absolute;
  left: 50%;
  top: 18px;
  transform: translateX(-50%);
  pointer-events: none;
  opacity: 0;
  font-size: clamp(17px, 5vw, 26px);
  font-weight: 700;
  letter-spacing: -.4px;
}
.combo.show { animation: comboPop .65s ease both; }

.separator {
  width: 100%;
  height: 4px;
  align-self: center;
  border-radius: 999px;
  opacity: .72;
  background: repeating-linear-gradient(90deg, #82909a 0 22px, transparent 22px 42px);
}

/* Queue */
.queue-zone { padding-top: 1px; }
.queue-labels {
  width: min(62vw, 306px);
  margin: 0 auto 6px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(38px, 12vw, 70px);
  text-align: center;
  color: #8294a0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.7px;
}
.queue-labels span:first-child { color: #eaf0f3; }
.queue-row {
  min-height: calc(var(--card-h) + 9px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(11px, 3vw, 20px);
}
.queue-slot {
  position: relative;
  width: var(--card-w);
  height: var(--card-h);
  flex: 0 0 var(--card-w);
  border: 0;
  padding: 0;
  background: transparent;
}
.queue-slot .card {
  top: 0;
  left: 0;
  --stack-index: 0;
}
.current-slot {
  cursor: grab;
  touch-action: none;
}
.current-slot:active { cursor: grabbing; }
.next-slot {
  transform: scale(.88);
  transform-origin: center bottom;
  opacity: .74;
}
.queue-arrow {
  align-self: center;
  margin-inline: -4px;
  color: #536875;
  font-size: clamp(30px, 9vw, 46px);
  font-weight: 700;
  line-height: 1;
  transform: translateY(3px);
}
.hint {
  min-height: 16px;
  margin: 7px 0 0;
  text-align: center;
  color: #637785;
  font-size: 11px;
  font-weight: 700;
}

/* overlays */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 22px;
  background: rgba(8, 16, 22, .78);
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility .2s ease;
}
.overlay[aria-hidden="false"] { opacity: 1; visibility: visible; }
.welcome { background: var(--bg); }
.panel {
  width: min(90vw, 380px);
  padding: 28px;
  border: 0;
  border-radius: 26px;
  background: var(--panel);
  box-shadow: 0 9px 0 rgba(4, 11, 16, .34);
  text-align: center;
}
.welcome-panel {
  padding-inline: 8px;
  background: transparent;
  box-shadow: none;
}
.brand-icon { margin-bottom: 2px; font-size: 60px; }
.welcome h1 {
  margin: 0 0 9px;
  font-size: clamp(50px, 15vw, 72px);
  line-height: .95;
  letter-spacing: -3px;
}
.welcome p {
  max-width: 310px;
  margin: 0 auto 24px;
  color: #93a5b0;
  font-size: 14px;
  line-height: 1.45;
  font-weight: 700;
}
.merge-demo {
  height: 124px;
  margin: 0 auto 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 17px;
}
.demo-stack { position: relative; width: 68px; height: 98px; }
.demo-card {
  position: relative;
  width: 68px;
  height: 86px;
  border-radius: 13px;
  display: grid;
  place-items: center;
  box-shadow: 0 5px 0 rgba(3,10,17,.34);
  font-weight: 700;
}
.demo-card b { position: absolute; top: 8px; left: 8px; font-size: 19px; }
.demo-card span { font-size: 30px; transform: translateY(7px); }
.demo-stack .demo-card { position: absolute; left: 0; }
.demo-stack .demo-card:first-child { top: 0; z-index: 2; }
.demo-stack .back-demo { top: 14px; z-index: 1; }
.demo-8 { background: #ff8d73; color: #b33224; }
.demo-16 { background: #ff746a; color: #ba2421; }
.demo-arrow { color: #697d89; font-size: 26px; font-weight: 700; }
.eyebrow {
  color: #8396a2;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 2px;
}
.panel h2 {
  margin: 6px 0 23px;
  font-size: 37px;
  line-height: 1;
  letter-spacing: -1.5px;
}
.primary-button,
.secondary-button {
  width: 100%;
  min-height: 52px;
  border-radius: 16px;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}
.primary-button {
  border: 0;
  background: #f1c754;
  color: #35230a;
  box-shadow: 0 5px 0 #b8871d;
}
.primary-button:active { transform: translateY(3px); box-shadow: 0 2px 0 #b8871d; }
.secondary-button {
  margin-top: 11px;
  border: 0;
  background: #213746;
  color: #eef4f6;
  box-shadow: 0 4px 0 #0e1d27;
}
.setting-row {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid #29404e;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #c9d4da;
  font-weight: 700;
}
.switch {
  width: 50px;
  height: 29px;
  border: 0;
  border-radius: 999px;
  padding: 3px;
  background: #425661;
  cursor: pointer;
}
.switch span {
  display: block;
  width: 23px;
  height: 23px;
  border-radius: 50%;
  background: #fff;
  transform: translateX(0);
  transition: transform .18s ease;
}
.switch[aria-checked="true"] { background: #d4ab3f; }
.switch[aria-checked="true"] span { transform: translateX(21px); }
.result-line {
  padding: 11px 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  border-top: 1px solid #29404e;
  color: #91a4af;
}
.result-line strong { color: #fff; font-size: 25px; }
.result-button { margin-top: 22px; }
.toast {
  position: fixed;
  left: 50%;
  top: 18%;
  z-index: 70;
  padding: 8px 13px;
  border-radius: 999px;
  background: #f7fafb;
  color: #172732;
  transform: translate(-50%, -8px);
  opacity: 0;
  pointer-events: none;
  font-size: 12px;
  font-weight: 700;
}
.toast.show { animation: toast .82s ease both; }

/* drag */
.drag-ghost {
  position: fixed !important;
  z-index: 100 !important;
  margin: 0 !important;
  pointer-events: none;
  /* JS writes left/top as the pointer coordinates. The card is centered around them exactly. */
  transform-origin: 50% 50%;
  transform: translate(-50%, -50%) rotate(var(--drag-tilt, 0deg)) scale(var(--drag-scale, 1.035));
  box-shadow: 0 calc(var(--card-shadow-y) + 5px) 0 rgba(3, 10, 17, .42);
  opacity: .98;
  will-change: left, top, transform;
}
.drag-ghost.drag-release {
  opacity: 0;
  transition: transform 115ms cubic-bezier(.2,.78,.25,1), opacity 100ms ease-out, box-shadow 100ms ease-out;
  box-shadow: 0 calc(var(--card-shadow-y) + 1px) 0 rgba(3, 10, 17, .32);
}
.drag-ghost.drag-return {
  transition:
    left 175ms cubic-bezier(.18,.82,.22,1),
    top 175ms cubic-bezier(.18,.82,.22,1),
    transform 175ms cubic-bezier(.18,.82,.22,1),
    box-shadow 175ms ease;
  box-shadow: 0 var(--card-shadow-y) 0 rgba(3, 10, 17, .36);
}
/* The PLAY card itself is moved into the drag layer; nothing remains here. */
.current-slot.dragging::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--card-radius);
  background: rgba(255,255,255,.018);
  pointer-events: none;
}

/* motion */
.card.flip-in .card-inner { animation: flipIn .48s cubic-bezier(.2,.78,.25,1) both; }
.card.deal-in { animation: dealIn .27s cubic-bezier(.2,.85,.3,1.16) both; }
.card.merge-out { animation: mergeOut .14s ease-in both; }
.card.merge-in { animation: mergeIn .3s cubic-bezier(.18,.9,.28,1.25) both; }
.card.shake { animation: shake .26s ease both; }

@keyframes flipIn {
  0% { transform: perspective(700px) rotateY(180deg) scale(.9); }
  58% { transform: perspective(700px) rotateY(-8deg) scale(1.03); }
  100% { transform: perspective(700px) rotateY(0) scale(1); }
}
@keyframes dealIn {
  0% { opacity: .15; transform: translateY(-24px) scale(.94); }
  76% { opacity: 1; transform: translateY(3px) scale(1.01); }
  100% { opacity: 1; transform: none; }
}
@keyframes mergeOut {
  to { opacity: 0; transform: translateY(-8px) scale(.72); }
}
@keyframes mergeIn {
  0% { transform: scale(.74); }
  64% { transform: scale(1.09); }
  100% { transform: none; }
}
@keyframes shake {
  20% { transform: translateX(-5px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}
@keyframes comboPop {
  0% { opacity: 0; transform: translate(-50%, 8px) scale(.8); }
  25% { opacity: 1; transform: translate(-50%, 0) scale(1.08); }
  72% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -24px) scale(.96); }
}
@keyframes toast {
  0%, 100% { opacity: 0; transform: translate(-50%, -8px); }
  18%, 72% { opacity: 1; transform: translate(-50%, 0); }
}

/* Short portrait screens */
@media (max-height: 700px) and (orientation: portrait) {
  :root {
    --card-w: clamp(54px, 16.83vw, 77.4px);
    --card-h: clamp(76.8px, 23.936vw, 110.08px);
    --stack-step: clamp(24px, 6.5vw, 33px);
  }
  .game-shell {
    min-height: 500px;
    grid-template-rows: auto minmax(205px, 1fr) 13px auto;
    gap: 5px;
  }
  .hud { min-height: 118px; }
  .score { padding-top: 35px; font-size: clamp(42px, 11vw, 58px); }
  .level-block { margin-top: 12px; }
  .board { min-height: 205px; padding-top: 4px; }
  .hint { margin-top: 4px; }
}

/* Landscape keeps the same game but redistributes the HUD/board/queue. */
@media (orientation: landscape) and (max-height: 620px) {
  :root {
    --shell-max: 980px;
    --card-w: clamp(52.2px, 7.92vw, 79.2px);
    --card-h: clamp(74.24px, 11.264vw, 112.64px);
    --stack-step: clamp(24px, 4.4vh, 34px);
  }
  .game-shell {
    width: min(100%, var(--shell-max));
    grid-template-columns: .9fr 1.55fr .85fr;
    grid-template-rows: 1fr;
    gap: 22px;
    padding-inline: 24px;
  }
  .hud {
    grid-column: 1;
    grid-row: 1;
    min-height: 0;
    align-self: center;
  }
  .best-score { top: -44px; }
  .pause-button { top: -52px; left: 62px; right: auto; }
  .score { padding-top: 0; }
  .board-zone { grid-column: 2; grid-row: 1; }
  .board { padding-top: 12px; }
  .separator { display: none; }
  .queue-zone {
    grid-column: 3;
    grid-row: 1;
    align-self: center;
  }
  .queue-row { gap: 7px; }
  .queue-arrow { display: none; }
  .queue-labels { width: 100%; gap: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- GAME JUICE: tactile, flat, no blurred glow ---------- */
.score {
  transform-origin: 50% 70%;
  will-change: transform;
}
.score.score-bump { animation: scoreBump .28s cubic-bezier(.16,.9,.28,1.35) both; }
.level-meta strong { transform-origin: left center; }
.level-meta strong.level-pop { animation: levelPop .46s cubic-bezier(.16,.9,.22,1.25) both; }
.progress-track { transform-origin: center; will-change: transform; }
.progress-track.progress-bump { animation: progressBump .25s cubic-bezier(.2,.85,.25,1.2) both; }
.progress-fill.progress-pop { animation: progressPop .34s cubic-bezier(.16,.9,.28,1.3) both; }
.progress-track.level-flash { animation: levelTrack .52s cubic-bezier(.2,.8,.2,1) both; }

/* Matching pair: newest card snaps upward into the one below it. */
.card.merge-top {
  z-index: 30 !important;
  animation: mergeTopSnap .18s cubic-bezier(.28,.02,.2,1) both;
}
.card.merge-base {
  z-index: 29 !important;
  animation: mergeBaseSquash .18s cubic-bezier(.28,.02,.2,1) both;
}
.card.merge-in {
  z-index: 40 !important;
  animation: mergePunch .31s cubic-bezier(.12,.9,.24,1.32) both;
}

/* Flat merge FX layer. */
.merge-fx {
  position: absolute;
  z-index: 24;
  width: 0;
  height: 0;
  pointer-events: none;
  color: var(--card-ink);
}
.merge-ring {
  position: absolute;
  left: 0;
  top: 0;
  width: 22px;
  height: 22px;
  border: 4px solid var(--face);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(.2);
  opacity: .95;
  animation: mergeRing .38s ease-out both;
}
.merge-particle {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--size, 6px);
  height: var(--size, 6px);
  border-radius: 2px;
  background: var(--face);
  box-shadow: 0 2px 0 rgba(2,8,13,.28);
  transform: translate(-50%, -50%) scale(.4);
  animation: mergeParticle .48s cubic-bezier(.12,.7,.22,1) var(--delay, 0ms) both;
}
.merge-particle:nth-of-type(3n) { border-radius: 50%; }
.merge-points {
  position: absolute;
  left: 0;
  top: 0;
  padding: 5px 9px 6px;
  border-radius: 9px;
  background: var(--face);
  color: var(--card-ink);
  box-shadow: 0 4px 0 rgba(2,8,13,.34);
  white-space: nowrap;
  font-size: clamp(16px, 5vw, 25px);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -.7px;
  transform: translate(-50%, -50%);
  animation: mergePoints .7s cubic-bezier(.16,.9,.22,1) both;
}
.merge-chain-tag {
  position: absolute;
  left: 0;
  top: 0;
  color: #fff;
  text-shadow: 0 3px 0 rgba(3,10,17,.34);
  font-size: clamp(14px, 4vw, 21px);
  line-height: 1;
  font-weight: 700;
  transform: translate(22px, -32px) rotate(7deg) scale(.5);
  animation: chainTag .6s cubic-bezier(.16,.9,.22,1.3) .05s both;
}

/* Tiny whole-board impact. Enough to feel the hit, not enough to move aim. */
.game-shell.impact { animation: shellImpact .18s ease-out both; }
.game-shell.impact-strong { animation: shellImpactStrong .22s ease-out both; }
.game-shell.level-impact { animation: levelImpact .38s cubic-bezier(.2,.8,.2,1) both; }

/* Current card gets a subtle kick after the queue advances. */
.current-slot .card.flip-in { animation: queueKick .42s cubic-bezier(.16,.88,.2,1.25); }
.current-slot .card.flip-in .card-inner { animation: flipIn .42s cubic-bezier(.16,.88,.2,1.08) both; }

/* The freshly generated NEXT card also enters every time the queue advances. */
.next-slot .card.next-in {
  animation: nextCardIn .46s cubic-bezier(.14,.86,.18,1.22) both;
}
.next-slot .card.next-in .card-inner {
  animation: nextCardFlip .46s cubic-bezier(.14,.86,.18,1.05) both;
}

.combo {
  top: 10px;
  padding: 5px 10px 6px;
  border-radius: 10px;
  background: #f7fafb;
  color: #172732;
  box-shadow: 0 4px 0 rgba(3,10,17,.32);
}
.combo.show { animation: comboJuice .72s cubic-bezier(.16,.88,.22,1.2) both; }

@keyframes mergeTopSnap {
  0% { opacity: 1; transform: translateY(0) rotate(0) scale(1); }
  48% { opacity: 1; transform: translateY(calc(var(--stack-step) * -.76)) rotate(-2deg) scale(.96, 1.04); }
  72% { opacity: 1; transform: translateY(calc(var(--stack-step) * -1)) rotate(1deg) scale(1.08, .90); }
  100% { opacity: 0; transform: translateY(calc(var(--stack-step) * -1)) scale(.64); }
}
@keyframes mergeBaseSquash {
  0% { transform: scale(1); }
  55% { transform: translateY(2px) scale(1.07, .92); }
  78% { transform: translateY(-2px) scale(.95, 1.06); }
  100% { opacity: 0; transform: scale(.76); }
}
@keyframes mergePunch {
  0% { opacity: .3; transform: translateY(5px) rotate(-4deg) scale(.58); }
  42% { opacity: 1; transform: translateY(-4px) rotate(1.5deg) scale(1.15, .88); }
  67% { transform: translateY(1px) rotate(-.7deg) scale(.94, 1.08); }
  84% { transform: translateY(-1px) scale(1.035, .97); }
  100% { opacity: 1; transform: none; }
}
@keyframes mergeRing {
  0% { opacity: .95; transform: translate(-50%, -50%) scale(.18); }
  72% { opacity: .55; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(4.4); }
}
@keyframes mergeParticle {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.25) rotate(0); }
  12% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.82) rotate(var(--spin)); }
}
@keyframes mergePoints {
  0% { opacity: 0; transform: translate(-50%, -34%) scale(.55); }
  18% { opacity: 1; transform: translate(-50%, -62%) scale(1.13, .9); }
  36% { transform: translate(-50%, -76%) scale(.96, 1.05); }
  72% { opacity: 1; transform: translate(-50%, -116%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -155%) scale(.92); }
}
@keyframes chainTag {
  0% { opacity: 0; transform: translate(13px, -19px) rotate(14deg) scale(.45); }
  32% { opacity: 1; transform: translate(24px, -37px) rotate(5deg) scale(1.2); }
  65% { opacity: 1; transform: translate(24px, -41px) rotate(5deg) scale(1); }
  100% { opacity: 0; transform: translate(24px, -58px) rotate(1deg) scale(.9); }
}
@keyframes scoreBump {
  0% { transform: scale(1); }
  38% { transform: translateY(-2px) scale(1.12, .90); }
  62% { transform: translateY(1px) scale(.96, 1.07); }
  100% { transform: none; }
}
@keyframes progressBump {
  0% { transform: scaleY(1); }
  45% { transform: scaleY(1.55); }
  100% { transform: scaleY(1); }
}
@keyframes progressPop {
  0% { transform: scaleX(.98); transform-origin: right center; }
  50% { transform: scaleX(1.04); transform-origin: right center; }
  100% { transform: scaleX(1); transform-origin: right center; }
}
@keyframes levelTrack {
  0%, 100% { transform: scaleY(1); }
  34% { transform: scaleY(1.7); }
  62% { transform: scaleY(.9); }
}
@keyframes levelPop {
  0% { transform: scale(1); }
  32% { transform: translateY(-3px) scale(1.13, .9); }
  60% { transform: translateY(1px) scale(.96, 1.07); }
  100% { transform: none; }
}
@keyframes shellImpact {
  0%, 100% { transform: translate(0,0); }
  25% { transform: translate(0, 2px); }
  50% { transform: translate(-1px, -1px); }
  75% { transform: translate(1px, 0); }
}
@keyframes shellImpactStrong {
  0%, 100% { transform: translate(0,0); }
  18% { transform: translate(-2px, 2px); }
  38% { transform: translate(2px, -2px); }
  58% { transform: translate(-1px, 1px); }
  76% { transform: translate(1px, 0); }
}
@keyframes levelImpact {
  0%, 100% { transform: scale(1); }
  42% { transform: scale(1.008); }
  72% { transform: scale(.997); }
}
@keyframes queueKick {
  0% { transform: translateX(34px) translateY(5px) rotate(5deg) scale(.88); opacity: .12; }
  48% { transform: translateX(-3px) translateY(-2px) rotate(-1.4deg) scale(1.045, .97); opacity: 1; }
  72% { transform: translateX(1px) translateY(1px) rotate(.5deg) scale(.985, 1.02); }
  100% { transform: none; opacity: 1; }
}
@keyframes nextCardIn {
  0% { opacity: 0; transform: translateX(22px) translateY(8px) rotate(7deg) scale(.72); }
  42% { opacity: 1; transform: translateX(-2px) translateY(-2px) rotate(-1.5deg) scale(1.055, .96); }
  68% { transform: translateX(1px) translateY(1px) rotate(.6deg) scale(.985, 1.02); }
  100% { opacity: 1; transform: none; }
}
@keyframes nextCardFlip {
  0% { transform: rotateY(-34deg) rotateX(5deg); }
  52% { transform: rotateY(4deg) rotateX(-1deg); }
  100% { transform: none; }
}
@keyframes comboJuice {
  0% { opacity: 0; transform: translate(-50%, 8px) rotate(-5deg) scale(.55); }
  22% { opacity: 1; transform: translate(-50%, -2px) rotate(2deg) scale(1.18, .9); }
  45% { transform: translate(-50%, 0) rotate(0) scale(.96, 1.05); }
  72% { opacity: 1; transform: translate(-50%, -5px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -27px) scale(.9); }
}

@media (prefers-reduced-motion: reduce) {
  .merge-particle, .merge-ring, .merge-points, .merge-chain-tag { display: none !important; }
}

/* ---------- CARD-SOLITAIRE BALANCE PASS ---------- */
:root {
  /* Keeps the physical death line comparable across screen sizes: ~7 safe cards. */
  --board-h: clamp(240px, 76vw, 425px);
}

.game-shell {
  grid-template-rows: auto var(--board-h) 16px auto;
  align-content: center;
}

.board-zone {
  height: var(--board-h);
}

.separator {
  position: relative;
  z-index: 6;
}

/* There are no fake full/blocked columns anymore. Height is the only danger. */
.blocked-lane,
.drag-blocked { cursor: pointer; background: transparent; }

.danger-lane .card:last-of-type {
  animation: dangerCard .52s cubic-bezier(.2,.8,.2,1) both;
}

/* Three compact bottom targets: current, next and the two-use emergency discard. */
.queue-labels {
  width: min(78vw, 390px);
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(8px, 2.5vw, 16px);
}

.queue-row {
  gap: clamp(8px, 2.5vw, 16px);
}

.discard-slot {
  position: relative;
  width: var(--card-w);
  height: var(--card-h);
  flex: 0 0 var(--card-w);
  border: 2px dashed rgba(151, 168, 179, .38);
  border-radius: var(--card-radius);
  padding: 0;
  background: rgba(255,255,255,.018);
  color: #93a6b2;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 8px;
  cursor: pointer;
  transform: scale(.88);
  transform-origin: center bottom;
  transition: transform .13s ease, opacity .13s ease, background-color .13s ease;
  touch-action: manipulation;
}

.discard-slot .discard-icon {
  display: block;
  font-size: clamp(34px, 10vw, 54px);
  line-height: .7;
  font-weight: 700;
}

.discard-slot strong {
  font-size: clamp(11px, 3vw, 14px);
  letter-spacing: .8px;
  font-variant-numeric: tabular-nums;
}

.discard-slot:hover:not(:disabled),
.discard-slot.drag-over {
  transform: scale(.93) translateY(-2px);
  background: rgba(255,255,255,.05);
}

.discard-slot:disabled,
.discard-slot.exhausted {
  opacity: .25;
  cursor: default;
}

.discard-slot.discard-pop { animation: discardPop .28s cubic-bezier(.16,.9,.28,1.28) both; }
.discard-slot.discard-shake { animation: discardShake .28s ease both; }

/* 2048 clears the complete pile instead of becoming a permanent blocker. */
.card.lane-clear {
  z-index: 45 !important;
  animation: laneClear .36s cubic-bezier(.2,.76,.2,1) both;
}

.game-shell.danger-impact { animation: dangerImpact .28s ease-out both; }
.game-shell.clear-impact { animation: clearImpact .44s cubic-bezier(.16,.9,.22,1.18) both; }

@keyframes dangerCard {
  0%, 100% { transform: translateY(0); }
  46% { transform: translateY(2px) scale(.99, 1.01); }
}

@keyframes discardPop {
  0% { transform: scale(.88); }
  45% { transform: scale(.78) rotate(-4deg); }
  72% { transform: scale(.94) rotate(1deg); }
  100% { transform: scale(.88); }
}

@keyframes discardShake {
  20% { transform: scale(.88) translateX(-4px); }
  40% { transform: scale(.88) translateX(4px); }
  65% { transform: scale(.88) translateX(-2px); }
  100% { transform: scale(.88) translateX(0); }
}

@keyframes laneClear {
  0% { opacity: 1; transform: scale(1) rotate(0); }
  35% { opacity: 1; transform: translateY(-5px) scale(1.08, .93) rotate(var(--clear-rot, 0deg)); }
  100% { opacity: 0; transform: translateY(-34px) scale(.7) rotate(5deg); }
}

@keyframes dangerImpact {
  0%, 100% { transform: translate(0,0); }
  22% { transform: translate(-3px, 1px); }
  44% { transform: translate(3px, 0); }
  66% { transform: translate(-2px, -1px); }
}

@keyframes clearImpact {
  0%, 100% { transform: scale(1); }
  32% { transform: scale(1.012); }
  58% { transform: scale(.994); }
  78% { transform: scale(1.004); }
}

@media (max-height: 700px) and (orientation: portrait) {
  :root { --board-h: clamp(205px, 68vw, 280px); }
  .game-shell {
    grid-template-rows: auto var(--board-h) 13px auto;
    align-content: center;
  }
  .board-zone { height: var(--board-h); }
  .queue-labels { margin-bottom: 4px; }
  .queue-row { gap: clamp(7px, 2vw, 12px); }
}

@media (orientation: landscape) and (max-height: 620px) {
  :root { --board-h: clamp(220px, 54vh, 320px); }
  .game-shell {
    grid-template-columns: .82fr 1.5fr 1.05fr;
    grid-template-rows: 1fr;
    align-content: stretch;
  }
  .board-zone {
    height: var(--board-h);
    align-self: center;
  }
  .queue-labels {
    width: 100%;
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;
    font-size: 8px;
    letter-spacing: 1px;
  }
  .queue-row {
    display: grid;
    grid-template-columns: repeat(3, var(--card-w));
    min-height: var(--card-h);
    gap: 5px;
  }
  .discard-slot { width: var(--card-w); height: var(--card-h); }
}

/* =========================================================
   FRONT-END FLOW / AUDIO SETTINGS / PRESENTATION PASS
   ========================================================= */

/* The board exists behind the front-end screens, but it never flashes on boot. */
.game-shell {
  opacity: 0;
  transform: scale(.992);
  pointer-events: none;
  transition: opacity .09s linear, transform .12s cubic-bezier(.2,.78,.2,1);
}
.game-shell.is-playing {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.game-shell[aria-hidden="true"] { pointer-events: none; }

/* Lower the playable piles a little without changing card height. */
.board {
  padding-top: clamp(20px, 3.2vh, 29px);
}

/* Proper round dots instead of square-ended gradient dashes. */
.separator {
  height: 8px;
  border: 0;
  border-radius: 0;
  opacity: .76;
  background:
    radial-gradient(circle, #8b99a2 0 3px, transparent 3.25px)
    left center / 18px 8px repeat-x;
}

/* ---------- Loading ---------- */
.loading-screen {
  z-index: 120;
  background: var(--bg);
  transition: opacity .3s ease, visibility .3s ease;
}
.loading-stage {
  width: min(100%, 520px);
  height: 100%;
  min-height: 420px;
  position: relative;
  display: grid;
  place-items: center;
}
.loading-title-wrap {
  display: grid;
  justify-items: center;
  opacity: 0;
  transform: translateY(9px) scale(.97);
  animation: bootTitleIn .68s cubic-bezier(.18,.82,.22,1) .1s forwards;
}
.loading-mark,
.menu-mark {
  font-size: clamp(46px, 13vw, 66px);
  line-height: 1;
  margin-bottom: 8px;
}
.brand-logo {
  width: min(86vw, 520px);
  height: auto;
  display: block;
  object-fit: contain;
  filter: drop-shadow(0 12px 28px rgba(0,0,0,.26));
}
.loading-logo {
  width: min(82vw, 500px);
}
.menu-logo {
  width: min(82vw, 500px);
}
.loading-title-wrap h1,
.menu-title-wrap h1 {
  margin: 0;
  font-size: clamp(54px, 16vw, 78px);
  line-height: .9;
  font-weight: 700;
  letter-spacing: -2.6px;
}
.loading-bottom {
  position: absolute;
  left: clamp(22px, 7vw, 42px);
  right: clamp(22px, 7vw, 42px);
  bottom: max(34px, calc(env(safe-area-inset-bottom) + 24px));
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 12px;
  opacity: 0;
  transform: translateY(8px);
  animation: bootBarIn .5s ease .38s forwards;
}
.loading-track {
  height: 8px;
  overflow: hidden;
  border-radius: 999px;
  background: #3f515d;
}
.loading-fill {
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--green);
  transition: width .08s linear;
}
.loading-bottom span {
  width: 38px;
  color: #9aabb6;
  text-align: right;
  font-size: 11px;
  line-height: 1;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.loading-screen.loading-complete .loading-title-wrap {
  animation: bootTitleOut .25s ease forwards;
}
.loading-screen.loading-complete .loading-bottom {
  animation: bootBarOut .22s ease forwards;
}

/* ---------- Minimal main menu ---------- */
.main-menu {
  z-index: 90;
  background: var(--bg);
  transition: opacity .3s ease, visibility .3s ease;
}
.menu-stack {
  width: min(86vw, 360px);
  min-height: min(72vh, 560px);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
}
.menu-title-wrap {
  width: 100%;
  display: block;
  text-align: center;
}
.menu-title-center {
  position: relative;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%);
  display: grid;
  justify-items: center;
  gap: 4px;
}
.menu-logo {
  margin-inline: auto;
}
.menu-best {
  margin-top: 19px;
  display: grid;
  gap: 3px;
}
.menu-best span {
  color: #748895;
  font-size: 10px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: 1.8px;
}
.menu-best strong {
  color: #fff;
  font-size: clamp(23px, 7vw, 31px);
  line-height: 1;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.menu-actions {
  width: 100%;
  margin-top: clamp(70px, 14vh, 118px);
}
.menu-actions .secondary-button { margin-top: 13px; }
.main-menu[aria-hidden="false"] .menu-title-wrap {
  animation: menuTitleIn .55s cubic-bezier(.16,.84,.22,1) .08s both;
}
.main-menu[aria-hidden="false"] .menu-actions {
  animation: menuButtonsIn .5s cubic-bezier(.16,.84,.22,1) .19s both;
}

.menu-sponsor-logo {
  position: absolute;
  left: 50%;
  bottom: max(8px, env(safe-area-inset-bottom));
  width: min(76vw, 330px);
  height: auto;
  display: block;
  object-fit: contain;
  transform: translateX(-50%);
  pointer-events: none;
  user-select: none;
}

@media (max-height: 620px) {
  .menu-sponsor-logo {
    width: min(62vw, 270px);
    bottom: max(5px, env(safe-area-inset-bottom));
  }
}

/* ---------- Settings ---------- */
.settings-screen { z-index: 105; }
.settings-panel {
  width: min(90vw, 390px);
  padding: 27px 26px 24px;
}
.settings-panel h2 { margin-bottom: 28px; }
.slider-setting {
  display: block;
  padding: 13px 0 15px;
  text-align: left;
}
.slider-setting + .slider-setting {
  border-top: 1px solid #29404e;
}
.slider-setting > span {
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.slider-setting strong {
  color: #dce5e9;
  font-size: 14px;
  font-weight: 700;
}
.slider-setting b {
  min-width: 42px;
  color: #8fa3af;
  text-align: right;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.slider-setting input[type="range"] {
  --fill: 50%;
  width: 100%;
  height: 22px;
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
}
.slider-setting input[type="range"]::-webkit-slider-runnable-track {
  height: 7px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--green) 0 var(--fill), #42545f var(--fill) 100%);
}
.slider-setting input[type="range"]::-webkit-slider-thumb {
  width: 20px;
  height: 20px;
  margin-top: -6.5px;
  border: 0;
  border-radius: 50%;
  appearance: none;
  -webkit-appearance: none;
  background: #f8fbfd;
  box-shadow: 0 3px 0 rgba(3,10,17,.34);
}
.slider-setting input[type="range"]::-moz-range-track {
  height: 7px;
  border: 0;
  border-radius: 999px;
  background: #42545f;
}
.slider-setting input[type="range"]::-moz-range-progress {
  height: 7px;
  border-radius: 999px;
  background: var(--green);
}
.slider-setting input[type="range"]::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border: 0;
  border-radius: 50%;
  background: #f8fbfd;
  box-shadow: 0 3px 0 rgba(3,10,17,.34);
}
.settings-back { margin-top: 20px; }
.text-button {
  width: 100%;
  margin-top: 18px;
  border: 0;
  padding: 10px;
  background: transparent;
  color: #8396a2;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.35px;
  cursor: pointer;
}
.text-button:hover { color: #dbe5ea; }

/* ---------- Juicy game entrance ---------- */
.game-enter .best-score { animation: hudLeftIn .32s cubic-bezier(.16,.86,.2,1.18) 0s both; }
.game-enter .pause-button { animation: hudRightIn .32s cubic-bezier(.16,.86,.2,1.18) .015s both; }
.game-enter .score { animation: scoreEnter .38s cubic-bezier(.16,.9,.2,1.24) .02s both; }
.game-enter .level-block { animation: hudUpIn .3s cubic-bezier(.2,.82,.22,1) .035s both; }
.game-enter .lane {
  animation: laneBuild .38s cubic-bezier(.14,.88,.2,1.18) both;
}
.game-enter .lane:nth-child(1) { animation-delay: .025s; }
.game-enter .lane:nth-child(2) { animation-delay: .045s; }
.game-enter .lane:nth-child(3) { animation-delay: .065s; }
.game-enter .lane:nth-child(4) { animation-delay: .085s; }
.game-enter .separator { animation: lineBuild .28s cubic-bezier(.2,.8,.2,1) .08s both; }
.game-enter .queue-labels { animation: queueBuild .3s ease .09s both; }
.game-enter .queue-row { animation: queueBuild .36s cubic-bezier(.16,.86,.2,1.15) .105s both; }

@keyframes bootTitleIn {
  from { opacity: 0; transform: translateY(9px) scale(.97); }
  to { opacity: 1; transform: none; }
}
@keyframes bootBarIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
@keyframes bootTitleOut {
  to { opacity: 0; transform: translateY(-8px) scale(.985); }
}
@keyframes bootBarOut {
  to { opacity: 0; transform: translateY(7px); }
}
@keyframes menuTitleIn {
  from { opacity: 0; transform: translateY(-9px) scale(.975); }
  to { opacity: 1; transform: none; }
}
@keyframes menuButtonsIn {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}
@keyframes hudLeftIn {
  from { opacity: 0; transform: translate(-18px,-8px) rotate(-4deg); }
  to { opacity: 1; transform: none; }
}
@keyframes hudRightIn {
  from { opacity: 0; transform: translate(18px,-8px) rotate(4deg); }
  to { opacity: 1; transform: none; }
}
@keyframes scoreEnter {
  0% { opacity: 0; transform: translateY(-10px) scale(.72); }
  58% { opacity: 1; transform: translateY(2px) scale(1.08,.93); }
  78% { transform: translateY(-1px) scale(.97,1.04); }
  100% { opacity: 1; transform: none; }
}
@keyframes hudUpIn {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
@keyframes laneBuild {
  0% { opacity: 0; transform: translateY(34px) rotate(2deg) scale(.9); }
  62% { opacity: 1; transform: translateY(-4px) rotate(-.7deg) scale(1.018,.98); }
  82% { transform: translateY(1px) rotate(.2deg) scale(.992,1.01); }
  100% { opacity: 1; transform: none; }
}
@keyframes lineBuild {
  from { opacity: 0; transform: scaleX(.15); }
  to { opacity: .76; transform: scaleX(1); }
}
@keyframes queueBuild {
  0% { opacity: 0; transform: translateY(28px) scale(.94); }
  70% { opacity: 1; transform: translateY(-3px) scale(1.015); }
  100% { opacity: 1; transform: none; }
}

/* Keep the lowered piles proportional on tiny portrait screens. */
@media (max-height: 700px) and (orientation: portrait) {
  .board { padding-top: clamp(11px, 2vh, 17px); }
  .menu-actions { margin-top: clamp(48px, 10vh, 75px); }
}

@media (orientation: landscape) and (max-height: 620px) {
  .board { padding-top: 16px; }
  .loading-stage { width: min(100%, 760px); }
  .menu-stack {
    width: min(62vw, 430px);
    min-height: 86vh;
  }
  .menu-mark { font-size: 42px; }
  .menu-title-wrap h1 { font-size: 58px; }
  .menu-actions { margin-top: 28px; }
}

@media (prefers-reduced-motion: reduce) {
  .loading-title-wrap,
  .loading-bottom,
  .main-menu[aria-hidden="false"] .menu-title-wrap,
  .main-menu[aria-hidden="false"] .menu-actions,
  .game-enter .best-score,
  .game-enter .pause-button,
  .game-enter .score,
  .game-enter .level-block,
  .game-enter .lane,
  .game-enter .separator,
  .game-enter .queue-labels,
  .game-enter .queue-row {
    animation-duration: .01ms !important;
    animation-delay: 0ms !important;
  }
}

@media (max-width: 420px) {
  .brand-logo { width: min(88vw, 460px); }
  .fruit-art img { width: min(86%, 64px); }
}


/* ---------- First-run tutorial ---------- */
.tutorial-layer {
  position: fixed;
  inset: 0;
  z-index: 115;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility .2s ease;
}
.tutorial-layer[aria-hidden="false"] {
  opacity: 1;
  visibility: visible;
}
.tutorial-layer.modal { pointer-events: auto; }
.tutorial-layer.interactive { pointer-events: none; }

.tutorial-scrim {
  position: absolute;
  inset: 0;
  background: rgba(6, 14, 20, .56);
  pointer-events: none;
}
/* During guided interaction, the spotlight itself provides the dimming mask.
   Keeping this layer transparent makes the highlighted control fully visible. */
.tutorial-layer.interactive .tutorial-scrim { background: transparent; }

.tutorial-spotlight {
  position: fixed;
  z-index: 116;
  left: 0;
  top: 0;
  width: 64px;
  height: 64px;
  border-radius: 22px;
  border: 3px solid rgba(255,255,255,.98);
  box-shadow: 0 0 0 9999px rgba(6, 14, 20, .56), 0 8px 0 rgba(4, 11, 16, .18);
  opacity: 0;
  pointer-events: none;
  transform: translate3d(0,0,0);
  transition: left .22s ease, top .22s ease, width .22s ease, height .22s ease, opacity .2s ease;
}
.tutorial-layer.interactive .tutorial-spotlight { opacity: 1; }

.tutorial-hand {
  position: fixed;
  z-index: 118;
  width: clamp(54px, 12vw, 82px);
  height: auto;
  transform-origin: 28% 20%;
  opacity: 0;
  pointer-events: none;
  filter: drop-shadow(0 8px 18px rgba(0,0,0,.34));
  transition: left .22s ease, top .22s ease, opacity .2s ease;
}
.tutorial-layer.interactive .tutorial-hand { opacity: 1; }
.tutorial-hand.hand-bob {
  animation: tutorialHandBob .78s ease-in-out infinite alternate;
}
.tutorial-hand.drag-demo {
  animation: tutorialDragGesture 1.55s cubic-bezier(.2,.72,.18,1) infinite;
}
.tutorial-hand.tap-demo {
  animation: tutorialTapGesture .92s cubic-bezier(.2,.8,.2,1) infinite;
}

/* Tutorial copy stays centered near the top so it never fights the hand/card area. */
.tutorial-bubble {
  position: fixed;
  z-index: 119;
  left: 50%;
  right: auto;
  top: max(76px, calc(env(safe-area-inset-top) + 62px));
  bottom: auto;
  width: min(calc(100vw - 28px), 360px);
  margin: 0;
  padding: 16px 18px 15px;
  transform: translateX(-50%);
  border-radius: 22px;
  background: var(--panel);
  box-shadow: 0 10px 0 rgba(4, 11, 16, .34);
  pointer-events: auto;
}
.tutorial-step {
  color: #93a5b0;
  font-size: 10px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: 1.6px;
}
.tutorial-bubble h3 {
  margin: 8px 0 8px;
  font-size: clamp(24px, 6.6vw, 32px);
  line-height: .95;
  letter-spacing: -1.2px;
}
.tutorial-bubble p {
  margin: 0;
  color: #d5e0e6;
  font-size: 14px;
  line-height: 1.42;
  font-weight: 700;
}
.tutorial-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: 16px;
}
.tutorial-primary { min-width: 138px; }
.tutorial-skip { margin-left: auto; }

/* Raise the highlighted real control above normal HUD content. */
.tutorial-focus {
  position: relative;
  z-index: 114 !important;
  opacity: 1 !important;
  visibility: visible !important;
}
.pause-button.tutorial-focus {
  filter: drop-shadow(0 4px 0 rgba(0,0,0,.2));
}

@keyframes tutorialHandBob {
  from { transform: translateY(0) rotate(-2deg); }
  to { transform: translateY(7px) rotate(2deg); }
}
@keyframes tutorialDragGesture {
  0% { opacity: 0; transform: translate3d(0,12px,0) scale(.96) rotate(-2deg); }
  10% { opacity: 1; }
  22% { transform: translate3d(0,0,0) scale(1) rotate(-2deg); }
  34% { transform: translate3d(0,0,0) scale(.88) rotate(-2deg); }
  72% { opacity: 1; transform: translate3d(var(--tutorial-dx,0px), var(--tutorial-dy,-180px), 0) scale(.88) rotate(2deg); }
  86% { transform: translate3d(var(--tutorial-dx,0px), var(--tutorial-dy,-180px), 0) scale(1) rotate(1deg); }
  100% { opacity: 0; transform: translate3d(var(--tutorial-dx,0px), var(--tutorial-dy,-180px), 0) scale(1) rotate(1deg); }
}
@keyframes tutorialTapGesture {
  0%, 100% { transform: translateY(0) scale(1); }
  42% { transform: translateY(-5px) scale(1); }
  58% { transform: translateY(2px) scale(.86); }
  72% { transform: translateY(0) scale(1); }
}


/* PLAY: tactile on pointer-down, transition begins on pointer-up. */
#playBtn {
  touch-action: manipulation;
  transition: transform .07s ease-out, box-shadow .07s ease-out, opacity .12s ease;
}
#playBtn.play-pressed {
  transform: translateY(4px) scale(.982);
  box-shadow: 0 1px 0 #b8871d;
}
.main-menu.play-starting-now #playBtn {
  transform: translateY(1px) scale(.994);
  box-shadow: 0 3px 0 #b8871d;
}

/* V19: JS/WAAPI owns the PLAY exit. Keep this class structural only so
   CSS cannot coalesce or override the compositor animation. */
.main-menu.play-leaving {
  visibility: visible !important;
  pointer-events: none !important;
  transition: none !important;
}
.main-menu.play-leaving .menu-title-wrap,
.main-menu.play-leaving .menu-actions {
  animation: none !important;
  transition: none !important;
}

@media (orientation: landscape) and (max-height: 620px) {
  .tutorial-bubble {
    top: max(18px, calc(env(safe-area-inset-top) + 12px));
    width: min(calc(100vw - 40px), 330px);
    padding: 13px 16px 12px;
  }
  .tutorial-bubble h3 { margin: 6px 0; font-size: 24px; }
  .tutorial-bubble p { font-size: 12px; line-height: 1.34; }
}


/* Pause tutorial: duplicate the real control above the tutorial mask so it can
   never disappear behind a stacking context created by the game shell. */
.tutorial-pause-clone {
  position: fixed;
  z-index: 122;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 16px;
  background: transparent;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: scale(.92);
  transition: opacity .16s ease, transform .2s cubic-bezier(.16,.86,.2,1.18), visibility .16s ease;
}
.tutorial-pause-clone span {
  width: 7px;
  height: 31px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 3px 0 rgba(3,10,17,.28);
}
.tutorial-pause-clone.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: scale(1.08);
  animation: tutorialPausePulse .9s ease-in-out infinite alternate;
}
.tutorial-layer.pause-step .tutorial-spotlight {
  border-color: rgba(119,232,120,.98);
  box-shadow: 0 0 0 9999px rgba(6,14,20,.62), 0 0 0 5px rgba(119,232,120,.18);
}
@keyframes tutorialPausePulse {
  from { transform: scale(1.04); }
  to { transform: scale(1.13); }
}

/* =========================================================
   DECK PICK / CARD-BACK PASS
   ========================================================= */

/* Recenter labels so every queue slot has its own perfectly aligned title. */
.queue-labels {
  width: auto;
  max-width: none;
  margin: 0 auto 6px;
  display: grid;
  grid-template-columns: repeat(4, var(--card-w));
  justify-content: center;
  gap: clamp(8px, 2.5vw, 16px);
}
.queue-labels span {
  width: var(--card-w);
  text-align: center;
}
.queue-row {
  display: grid;
  grid-template-columns: repeat(4, var(--card-w));
  justify-content: center;
  min-height: calc(var(--card-h) + 22px);
  gap: clamp(8px, 2.5vw, 16px);
}

/* Deck / chooser rebuilt from the debug trace. */

/* Visual only. Do NOT change positioning of .card-back here: it is a card FACE. */
.card-back,
.deck-card-back {
  overflow: hidden;
  border-radius: var(--card-radius);
  background-color: #62778d !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'%3E%3Cpath d='M-2 4L4-2M0 18L18 0M14 20L20 14' stroke='%23b7c5d2' stroke-opacity='.16' stroke-width='2'/%3E%3C/svg%3E") !important;
  border: 3px solid #afbecc !important;
  color: transparent;
}

/* Critical: the reverse is a full-size FACE, not a normal-flow child. */
.card .card-back {
  position: absolute !important;
  inset: 0 !important;
  width: auto !important;
  height: auto !important;
}
.card-back::before,
.deck-card-back::before {
  content: '';
  position: absolute;
  inset: 8px;
  border-radius: calc(var(--card-radius) - 10px);
  border: 2px solid rgba(214, 224, 233, .72);
  background: transparent;
}
.card-back::after,
.deck-card-back::after {
  content: '';
  position: absolute;
  inset: 14px;
  border-radius: calc(var(--card-radius) - 15px);
  border: 1px solid rgba(214, 224, 233, .28);
}
.card-back span { display: none; }

.discard-slot {
  position: relative;
  width: var(--card-w);
  height: var(--card-h);
  flex: 0 0 var(--card-w);
  border: 2px dashed rgba(151, 168, 179, .38);
  border-radius: var(--card-radius);
  padding: 0;
  background: rgba(255,255,255,.018);
  color: #93a6b2;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 8px;
  cursor: pointer;
  transform: scale(.88);
  transform-origin: center bottom;
  transition: transform .13s ease, opacity .13s ease, background-color .13s ease;
  touch-action: manipulation;
}
.deck-slot {
  position: relative;
  width: var(--card-w);
  height: var(--card-h);
  flex: 0 0 var(--card-w);
  border: 0;
  border-radius: var(--card-radius);
  padding: 0;
  background: transparent;
  color: #93a6b2;
  display: block;
  overflow: visible;
  cursor: pointer;
  transform: none;
  transform-origin: center bottom;
  transition: transform .13s ease, opacity .13s ease;
  touch-action: manipulation;
}
.discard-slot:hover:not(:disabled),
.discard-slot.drag-over {
  transform: scale(.93) translateY(-2px);
  background: rgba(255,255,255,.05);
}
.deck-slot:hover:not(:disabled) { transform: translateY(-3px) scale(1.015); }
.deck-slot:disabled,
.deck-slot.disabled,
.discard-slot:disabled,
.discard-slot.exhausted {
  opacity: .25;
  cursor: default;
}
.deck-slot strong,
.discard-slot strong {
  position: absolute;
  left: 50%;
  bottom: -14px;
  transform: translateX(-50%);
  font-size: clamp(11px, 3vw, 14px);
  letter-spacing: .8px;
  font-variant-numeric: tabular-nums;
}

/* The deck is literally four full-size reversed cards with a tiny offset. */
.deck-card {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--card-w);
  height: var(--card-h);
  border-radius: var(--card-radius);
  box-shadow: 0 var(--card-shadow-y) 0 rgba(3, 10, 17, .28);
  transform-origin: center center;
  pointer-events: none;
}
.deck-card-1 { transform: translate(0, 0) rotate(0deg); z-index: 4; }
.deck-card-2 { transform: translate(-4px, -3px) rotate(-2.2deg); z-index: 3; }
.deck-card-3 { transform: translate(4px, -6px) rotate(3deg); z-index: 2; }
.deck-card-4 { transform: translate(-2px, -9px) rotate(-1deg); z-index: 1; }

.deck-chooser {
  position: fixed;
  inset: 0;
  z-index: 96;
  display: grid;
  place-items: center;
  padding: 20px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .18s ease, visibility .18s ease;
}
.deck-chooser[aria-hidden="false"] {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.deck-chooser-scrim {
  position: absolute;
  inset: 0;
  background: rgba(7, 14, 20, .68);
}
.deck-chooser-panel {
  position: relative;
  z-index: 1;
  width: min(96vw, 620px);
  display: grid;
  justify-items: center;
  gap: 18px;
}
.deck-chooser-copy {
  max-width: 440px;
  text-align: center;
}
.deck-chooser-copy h3 {
  margin: 5px 0 8px;
  font-size: clamp(28px, 7vw, 38px);
  line-height: .95;
  letter-spacing: -1.4px;
}
.deck-chooser-copy p {
  margin: 0;
  color: #b6c4cc;
  font-size: 13px;
  line-height: 1.45;
  font-weight: 700;
}

.deck-choice-row {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, var(--card-w));
  grid-template-rows: repeat(2, var(--card-h));
  justify-content: center;
  gap: clamp(18px, 4.2vw, 26px);
  width: calc(var(--card-w) * 2 + clamp(18px, 4.2vw, 26px));
  height: calc(var(--card-h) * 2 + clamp(18px, 4.2vw, 26px));
  perspective: 1200px;
}
.deck-choice-row.is-dealing { pointer-events: none; }

.choice-card {
  position: relative;
  width: var(--card-w);
  height: var(--card-h);
  border: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  opacity: 0;
  transform: none;
  transform-style: preserve-3d;
  will-change: transform, opacity;
}
.choice-card.is-ready { opacity: 1; }
.choice-card .card {
  position: relative;
  inset: auto;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  --stack-index: 0;
  transform: translateZ(18px) translateY(var(--card-lift, 0px));
  transition: transform .12s ease-out, opacity .18s ease;
  transform-style: preserve-3d;
  will-change: transform;
}
.choice-card .card-inner {
  transform-style: preserve-3d;
  will-change: transform;
}
.choice-card.is-facedown .card-inner { transform: rotateY(180deg); }
.choice-card:hover { z-index: 4; }
.choice-card:hover .card {
  --card-lift: -6px;
}
.choice-card.is-resolving { pointer-events: none; z-index: 8; }

.choice-card[data-tilt] { transform-style: preserve-3d; }
.choice-card.is-ready .card {
  box-shadow: 0 var(--card-shadow-y) 0 rgba(3, 10, 17, .36), 0 12px 22px rgba(3, 10, 17, .12);
}

@media (orientation: landscape) and (max-height: 620px) {
  .queue-labels {
    grid-template-columns: repeat(4, var(--card-w));
    gap: 5px;
    font-size: 8px;
    letter-spacing: 1px;
  }
  .queue-row {
    grid-template-columns: repeat(4, var(--card-w));
    min-height: var(--card-h);
    gap: 5px;
  }
}

@media (max-width: 390px) {
  .deck-choice-row { gap: 12px; }
  .deck-chooser-copy p { font-size: 12px; }
}

/* V8: compact deck choice prompt. */
.deck-chooser-copy-simple { margin-bottom: 2px; }
.deck-chooser-copy-simple h3 { margin: 0; letter-spacing: 1.2px; }


/* V11 typography: chunkier Quicksand without making every line equally loud. */
body { font-weight: 600; }
button, input, label { font-weight: 700; }
.queue-labels, .level-meta, .eyebrow, .menu-best span, .tutorial-step,
.deck-chooser-copy-simple h3, .deck-slot strong, .discard-slot strong { font-weight: 700; }
.deck-chooser-copy p, .tutorial-bubble p, .hint, .welcome p { font-weight: 600; }

/* V12 typography: maximum real Quicksand weight everywhere. */
html, body, button, input, label, p, span, strong, h1, h2, h3, h4, h5, h6,
.best-score, .score, .level-meta, .queue-labels, .eyebrow, .menu-best,
.tutorial-step, .tutorial-bubble, .deck-chooser-copy, .deck-chooser-copy-simple,
.deck-slot, .discard-slot, .primary-button, .secondary-button, .text-button {
  font-weight: 700 !important;
}

/* V13 PLAY paint stability: keep the two transition surfaces compositor-ready. */
.game-shell {
  will-change: opacity, transform;
}
.main-menu.play-leaving {
  will-change: opacity;
}
.main-menu.play-leaving .menu-title-wrap,
.main-menu.play-leaving .menu-actions {
  will-change: opacity, transform;
}

/* V14 — springy hover/touch polish. Hover only where a real hover device exists. */
:root {
  --ui-spring: cubic-bezier(.18, 1.45, .34, 1);
  --ui-snap: cubic-bezier(.2, .82, .2, 1);
}

button {
  -webkit-tap-highlight-color: transparent;
}

.primary-button,
.secondary-button,
.text-button,
.pause-button,
.tutorial-pause-clone,
.discard-slot,
.deck-slot {
  transform-origin: 50% 72%;
}

.primary-button,
.secondary-button {
  transition:
    transform .24s var(--ui-spring),
    box-shadow .18s var(--ui-snap),
    filter .18s ease,
    opacity .14s ease;
}

.secondary-button {
  box-shadow: 0 4px 0 #0e1d27;
}

.text-button {
  transition:
    transform .22s var(--ui-spring),
    color .15s ease,
    opacity .15s ease;
}

.pause-button,
.tutorial-pause-clone {
  transition: transform .25s var(--ui-spring), opacity .15s ease;
}
.pause-button span,
.tutorial-pause-clone span {
  transition: transform .22s var(--ui-spring);
  transform-origin: center;
}

.discard-slot,
.deck-slot {
  transition:
    transform .25s var(--ui-spring),
    opacity .14s ease,
    background-color .14s ease,
    border-color .14s ease;
}

.current-slot .card {
  transition: transform .22s var(--ui-spring), box-shadow .18s ease;
}

.slider-setting input[type="range"]::-webkit-slider-thumb {
  transition: transform .2s var(--ui-spring), box-shadow .16s ease;
}
.slider-setting input[type="range"]::-moz-range-thumb {
  transition: transform .2s var(--ui-spring), box-shadow .16s ease;
}

@media (hover: hover) and (pointer: fine) {
  .primary-button:hover:not(:disabled) {
    transform: translateY(-4px) scale(1.025);
    box-shadow: 0 8px 0 #b8871d;
    filter: brightness(1.035);
  }

  .secondary-button:hover:not(:disabled) {
    transform: translateY(-4px) scale(1.022);
    box-shadow: 0 7px 0 #0e1d27;
    filter: brightness(1.08);
  }

  .text-button:hover:not(:disabled) {
    transform: translateY(-2px) scale(1.035);
    color: #eef5f8;
  }

  .pause-button:hover,
  .tutorial-pause-clone:hover {
    transform: translateY(-3px) scale(1.12) rotate(2deg);
  }
  .pause-button:hover span:first-child,
  .tutorial-pause-clone:hover span:first-child {
    transform: translateX(-1.5px) scaleY(1.05);
  }
  .pause-button:hover span:last-child,
  .tutorial-pause-clone:hover span:last-child {
    transform: translateX(1.5px) scaleY(1.05);
  }

  .discard-slot:hover:not(:disabled):not(.exhausted) {
    transform: translateY(-6px) scale(.95) rotate(-1deg);
    background: rgba(255,255,255,.065);
    border-color: rgba(181,198,208,.58);
  }

  .deck-slot:hover:not(:disabled):not(.disabled) {
    transform: translateY(-7px) scale(1.045) rotate(1deg);
  }
  .deck-slot:hover:not(:disabled):not(.disabled) .deck-card-1 {
    transform: translate(0,-2px) rotate(0deg);
  }
  .deck-slot:hover:not(:disabled):not(.disabled) .deck-card-2 {
    transform: translate(-7px,-6px) rotate(-5deg);
  }
  .deck-slot:hover:not(:disabled):not(.disabled) .deck-card-3 {
    transform: translate(7px,-11px) rotate(6deg);
  }
  .deck-card {
    transition: transform .27s var(--ui-spring);
  }

  .current-slot:not(.dragging):hover .card {
    transform: translateY(-7px) scale(1.035) rotate(-1deg);
    box-shadow: 0 calc(var(--card-shadow-y) + 3px) 0 rgba(3,10,17,.31);
  }

  .slider-setting input[type="range"]:hover::-webkit-slider-thumb {
    transform: scale(1.18);
    box-shadow: 0 4px 0 rgba(3,10,17,.34);
  }
  .slider-setting input[type="range"]:hover::-moz-range-thumb {
    transform: scale(1.18);
    box-shadow: 0 4px 0 rgba(3,10,17,.34);
  }
}

/* Touch/click squash: fast down, spring back. */
.primary-button:active:not(:disabled) {
  transform: translateY(3px) scale(.975);
  box-shadow: 0 2px 0 #b8871d;
  transition-duration: .055s;
}
.secondary-button:active:not(:disabled) {
  transform: translateY(3px) scale(.975);
  box-shadow: 0 1px 0 #0e1d27;
  transition-duration: .055s;
}
.text-button:active:not(:disabled) {
  transform: translateY(1px) scale(.95);
  transition-duration: .055s;
}
.pause-button:active,
.tutorial-pause-clone:active {
  transform: translateY(2px) scale(.91);
  transition-duration: .055s;
}
.discard-slot:active:not(:disabled):not(.exhausted) {
  transform: translateY(2px) scale(.84);
  transition-duration: .055s;
}
.deck-slot:active:not(:disabled):not(.disabled) {
  transform: translateY(2px) scale(.93);
  transition-duration: .055s;
}
.current-slot:not(.dragging):active .card {
  transform: translateY(2px) scale(.965);
  transition-duration: .055s;
}
.slider-setting input[type="range"]:active::-webkit-slider-thumb {
  transform: scale(.9);
}
.slider-setting input[type="range"]:active::-moz-range-thumb {
  transform: scale(.9);
}

/* Preserve the custom instant PLAY press/paint path over generic hover rules. */
#playBtn.play-pressed {
  transform: translateY(4px) scale(.97) !important;
  box-shadow: 0 1px 0 #b8871d !important;
  transition-duration: .055s !important;
}
.main-menu.play-starting-now #playBtn {
  transform: translateY(1px) scale(.992) !important;
  box-shadow: 0 3px 0 #b8871d !important;
}

@media (prefers-reduced-motion: reduce) {
  .primary-button,
  .secondary-button,
  .text-button,
  .pause-button,
  .tutorial-pause-clone,
  .discard-slot,
  .deck-slot,
  .deck-card,
  .current-slot .card {
    transition-duration: .01ms !important;
  }
}


/* V15 — bouncy hover pass for the actual game cards + deck pile. */
.card {
  transition:
    transform .24s var(--ui-spring),
    box-shadow .18s var(--ui-snap),
    filter .16s ease;
}

/* Keep deal/merge animations in charge while they are running. */
.card.deal-in,
.card.merge-out,
.card.merge-in,
.card.merge-top,
.card.merge-base,
.card.lane-clear,
.card.shake,
.card.flip-in,
.card.next-in {
  transition: none;
}

.deck-card {
  transition:
    transform .3s var(--ui-spring),
    box-shadow .18s var(--ui-snap),
    filter .16s ease;
}

.deck-slot strong {
  transition: transform .24s var(--ui-spring), color .14s ease;
}

@media (hover: hover) and (pointer: fine) {
  /* Only the playable/top card of each pile reacts, not every buried card. */
  .lane:not(.drag-valid):not(.drag-match):not(.drag-blocked) .card:last-of-type:hover {
    transform: translateY(-8px) scale(1.045) rotate(-1.2deg);
    box-shadow: 0 calc(var(--card-shadow-y) + 4px) 0 rgba(3,10,17,.31);
    filter: brightness(1.025);
    z-index: 30 !important;
  }

  /* Current card: a little stronger than V14 so the hover reads instantly. */
  .current-slot:not(.dragging):hover .card {
    transform: translateY(-9px) scale(1.05) rotate(-1.2deg);
    box-shadow: 0 calc(var(--card-shadow-y) + 4px) 0 rgba(3,10,17,.31);
    filter: brightness(1.025);
  }

  /* NEXT is still non-interactive, but gets a soft preview hover. */
  .next-slot:hover .card {
    transform: translateY(-5px) scale(1.028) rotate(1deg);
    box-shadow: 0 calc(var(--card-shadow-y) + 2px) 0 rgba(3,10,17,.30);
    filter: brightness(1.02);
  }

  /* The deck/shuffle pile fans out and pops instead of only moving the wrapper. */
  .deck-slot:hover:not(:disabled):not(.disabled) {
    transform: translateY(-8px) scale(1.05) rotate(.8deg);
  }
  .deck-slot:hover:not(:disabled):not(.disabled) .deck-card-1 {
    transform: translate(0,-5px) rotate(-.5deg) scale(1.015);
    filter: brightness(1.035);
  }
  .deck-slot:hover:not(:disabled):not(.disabled) .deck-card-2 {
    transform: translate(-10px,-9px) rotate(-6deg) scale(1.005);
  }
  .deck-slot:hover:not(:disabled):not(.disabled) .deck-card-3 {
    transform: translate(10px,-13px) rotate(7deg) scale(.995);
  }
  .deck-slot:hover:not(:disabled):not(.disabled) strong {
    transform: translateX(-50%) translateY(2px) scale(1.08);
    color: #dce8ef;
  }

  /* Pick-one cards already use VanillaTilt; add the bouncy lift without glare. */
  .choice-card.is-ready:hover .card {
    transform: translateY(-6px) scale(1.035);
    box-shadow: 0 calc(var(--card-shadow-y) + 4px) 0 rgba(3,10,17,.31);
    filter: brightness(1.025);
  }
}

/* Click/touch squash for board cards and deck pile. */
.lane .card:last-of-type:active {
  transform: translateY(2px) scale(.965);
  transition-duration: .055s;
}
.next-slot:active .card {
  transform: translateY(1px) scale(.975);
  transition-duration: .055s;
}
.deck-slot:active:not(:disabled):not(.disabled) .deck-card-1 {
  transform: translate(0,2px) rotate(0deg) scale(.975);
  transition-duration: .055s;
}
.deck-slot:active:not(:disabled):not(.disabled) .deck-card-2 {
  transform: translate(-3px,-1px) rotate(-2deg) scale(.975);
  transition-duration: .055s;
}
.deck-slot:active:not(:disabled):not(.disabled) .deck-card-3 {
  transform: translate(3px,-3px) rotate(3deg) scale(.975);
  transition-duration: .055s;
}


/* V16 — Joker deck: picked power-up replaces the pile until used. */
.deck-slot.has-joker {
  transform: none;
}
.deck-slot.has-joker .stored-joker-card {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  --stack-index: 0;
  transform: scale(.9);
  transform-origin: center bottom;
  cursor: pointer;
}

.joker-card .joker-front {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 10px 7px;
  text-align: center;
  color: #eff7fb;
  background: #30495c;
  border: 3px solid #a9c4d3;
}
.joker-card .joker-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: #d4e5ed;
  color: #284254;
  font-size: 25px;
  line-height: 1;
  font-weight: 700;
}
.joker-card .joker-title {
  font-size: clamp(10px, 2.5vw, 13px);
  line-height: 1;
  letter-spacing: .2px;
  font-weight: 700;
}
.joker-card .joker-desc {
  display: block;
  max-width: 92%;
  font-size: clamp(7px, 1.9vw, 10px);
  line-height: 1.12;
  color: #c7d8e1;
  font-weight: 700;
}

/* Tiny identity accents, still flat/soft. */
.joker-clear-line .joker-front { background: #36566a; }
.joker-wrong-out .joker-front { background: #5a4657; }
.joker-top-sweep .joker-front { background: #405369; }
.joker-fresh-pair .joker-front { background: #3e5b55; }
.joker-match-up .joker-front { background: #56513f; }
.joker-trim-tall .joker-front { background: #4f485e; }

.choice-card.joker-choice .card {
  transform: translateZ(18px);
}
.choice-card.joker-choice.is-ready:hover .card {
  transform: translateY(-5px) scale(1.025);
}

.deck-slot.has-joker:hover:not(:disabled):not(.disabled) {
  transform: translateY(-5px) scale(1.025) rotate(.4deg);
}
.deck-slot.has-joker:hover .stored-joker-card {
  transform: scale(.93) translateY(-2px);
  filter: brightness(1.035);
}
.deck-slot.has-joker:active .stored-joker-card {
  transform: scale(.865) translateY(2px);
  transition-duration: .055s;
}

.joker-transfer-card {
  box-shadow: 0 var(--card-shadow-y) 0 rgba(3,10,17,.35), 0 15px 30px rgba(3,10,17,.18);
}

.board.joker-targeting .lane {
  cursor: crosshair;
  transition: transform .2s var(--ui-spring), opacity .15s ease;
}
.board.joker-targeting .lane:has(.card) {
  transform: translateY(-3px);
}
.board.joker-targeting .lane:empty {
  opacity: .5;
}
@media (hover: hover) and (pointer: fine) {
  .board.joker-targeting .lane:has(.card):hover {
    transform: translateY(-7px) scale(1.025);
  }
}

.game-shell.joker-impact .board-zone {
  animation: jokerBoardKick .34s cubic-bezier(.18,1.25,.3,1);
}
@keyframes jokerBoardKick {
  0% { transform: scale(1); }
  40% { transform: scale(1.018); }
  100% { transform: scale(1); }
}

/* Main-menu hover stays bouncy but no longer grows so much. */
@media (hover: hover) and (pointer: fine) {
  .main-menu .primary-button:hover:not(:disabled) {
    transform: translateY(-2px) scale(1.012);
    box-shadow: 0 6px 0 #b8871d;
  }
  .main-menu .secondary-button:hover:not(:disabled) {
    transform: translateY(-2px) scale(1.01);
    box-shadow: 0 5px 0 #0e1d27;
  }
}


/* V17 — PLAY card hover fix.
   The old queueKick animation used fill-mode: both, which kept ownership of
   transform after finishing and silently blocked the draggable card hover. */
.current-slot .card {
  transition:
    transform .24s var(--ui-spring),
    box-shadow .18s var(--ui-snap),
    filter .16s ease;
}

@media (hover: hover) and (pointer: fine) {
  .current-slot:not(.dragging):hover .card:not(.flip-in) {
    transform: translateY(-10px) scale(1.055) rotate(-1.15deg);
    box-shadow: 0 calc(var(--card-shadow-y) + 5px) 0 rgba(3,10,17,.31);
    filter: brightness(1.035);
  }
}

.current-slot:not(.dragging):active .card:not(.flip-in) {
  transform: translateY(2px) scale(.965) rotate(0deg);
  transition-duration: .055s;
}


/* V18 — full-size readable stored joker + smoother deck landing. */
.deck-slot.has-joker {
  width: var(--card-w);
  height: var(--card-h);
  transform: none;
}

.deck-slot.has-joker .stored-joker-card {
  inset: 0;
  width: var(--card-w);
  height: var(--card-h);
  transform: translateY(0) scale(1);
  transform-origin: center center;
  transition:
    transform .24s var(--ui-spring),
    filter .16s ease,
    box-shadow .18s ease;
}

/* Keep the information dense enough to read even at the small mobile card size. */
.joker-card .joker-front {
  gap: clamp(3px, .8vw, 5px);
  padding: clamp(6px, 1.6vw, 10px) clamp(4px, 1.25vw, 7px);
}

.joker-card .joker-icon {
  width: clamp(30px, 8.2vw, 40px);
  height: clamp(30px, 8.2vw, 40px);
  border-radius: clamp(9px, 2.4vw, 12px);
  font-size: clamp(20px, 5.8vw, 27px);
  flex: 0 0 auto;
}

.joker-card .joker-title {
  width: 100%;
  font-size: clamp(9px, 2.55vw, 13.5px);
  line-height: 1.02;
  letter-spacing: 0;
  font-weight: 700;
  text-wrap: balance;
}

.joker-card .joker-desc {
  max-width: 100%;
  font-size: clamp(7.25px, 2vw, 10.5px);
  line-height: 1.08;
  font-weight: 700;
  text-wrap: balance;
}

/* Stored joker must be visually the same size as the draggable PLAY card. */
.deck-slot.has-joker .joker-icon {
  width: clamp(31px, 8.5vw, 41px);
  height: clamp(31px, 8.5vw, 41px);
}

@media (hover: hover) and (pointer: fine) {
  .deck-slot.has-joker:hover:not(:disabled):not(.disabled) {
    transform: translateY(-7px) scale(1.035) rotate(.45deg);
  }
  .deck-slot.has-joker:hover .stored-joker-card {
    transform: translateY(0) scale(1);
    filter: brightness(1.045);
  }
}

.deck-slot.has-joker:active .stored-joker-card {
  transform: translateY(2px) scale(.965);
}

/* While the picked joker is travelling, the old deck recedes instead of popping. */
.deck-slot.is-receiving-joker {
  pointer-events: none;
}
.deck-slot.is-receiving-joker .deck-card {
  will-change: transform, opacity;
}

.joker-transfer-card {
  will-change: transform, opacity;
  backface-visibility: hidden;
  transform-style: preserve-3d;
}


/* V19 — transfer owns one physical joker card only. */
.deck-chooser[aria-hidden="true"] {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}
.joker-transfer-card {
  will-change: transform;
  backface-visibility: hidden;
  transform-style: preserve-3d;
}


/* V20 — four-card magazine depletes one-by-one, then stays empty for the picked joker. */
.deck-slot.is-dealing-cards,
.deck-slot.is-depleted {
  pointer-events: none;
}
.deck-slot.is-depleted:not(.has-joker)::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 2px dashed rgba(163, 184, 198, .18);
  border-radius: var(--card-radius);
  background: rgba(255,255,255,.012);
  pointer-events: none;
}
.deck-slot.is-depleted:not(.has-joker) .deck-card {
  opacity: 0;
  visibility: hidden;
}

@media (hover: hover) and (pointer: fine) {
  .deck-slot:hover:not(:disabled):not(.disabled) .deck-card-4 {
    transform: translate(-4px,-13px) rotate(-2deg);
  }
}

/* Keep pause touch input direct and diagnosable on mobile. */
.pause-button {
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}


/* V21 — lane hover: light starts at the top and fades smoothly to transparent. */
.lane {
  isolation: isolate;
  background: transparent !important;
}
.lane::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  background: linear-gradient(
    to bottom,
    rgba(255,255,255,.085) 0%,
    rgba(255,255,255,.052) 20%,
    rgba(255,255,255,.022) 44%,
    rgba(255,255,255,0) 78%
  );
  transition: opacity .16s cubic-bezier(.2,.8,.2,1);
}
.lane .pile,
.lane .empty-hint {
  z-index: 1;
}
@media (hover:hover) and (pointer:fine) {
  .lane:hover::before { opacity: 1; }
}

/* While joker is physically travelling, nothing may paint a replacement in the deck slot. */
.deck-slot.is-receiving-joker > .deck-card,
.deck-slot.is-receiving-joker > .stored-joker-card {
  pointer-events: none;
}


/* V22 — lane hover reads from the TOP of the lane and dissolves downward. */
.lane::before {
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(255,255,255,.115) 0%,
    rgba(255,255,255,.082) 12%,
    rgba(255,255,255,.046) 30%,
    rgba(255,255,255,.018) 52%,
    rgba(255,255,255,.004) 70%,
    rgba(255,255,255,0) 88%
  );
  transition: opacity .18s cubic-bezier(.2,.8,.2,1);
}
@media (hover:hover) and (pointer:fine) {
  .lane:hover::before { opacity: 1; }
}

/* The stored joker is the exact picked node; neutralize chooser-only styling. */
.deck-slot .stored-joker-card.choice-stage-card {
  transform: none !important;
}


/* =========================================================
   V25 — 3-slot bottom queue: NEXT tucked behind PLAY
   ========================================================= */
.queue-zone {
  padding-top: 2px;
  overflow: visible;
}

/* Old top labels are gone. Captions now live below each target. */
.queue-labels { display: none !important; }

.queue-row {
  width: 100%;
  min-height: calc(var(--card-h) + 29px);
  display: grid !important;
  grid-template-columns: calc(var(--card-w) + clamp(18px, 4.2vw, 26px)) var(--card-w) var(--card-w) !important;
  align-items: end;
  justify-content: center;
  gap: clamp(20px, 5.4vw, 36px) !important;
  overflow: visible;
}

.queue-cell {
  position: relative;
  min-width: 0;
  display: grid;
  grid-template-rows: var(--card-h) 22px;
  justify-items: center;
  align-items: end;
  overflow: visible;
}

.queue-caption {
  align-self: end;
  display: block;
  margin-top: 7px;
  color: #8799a5;
  font-size: clamp(9px, 2.2vw, 11px);
  line-height: 1;
  letter-spacing: 1.35px;
  text-align: center;
  font-weight: 700 !important;
  white-space: nowrap;
}
.queue-cards-cell .queue-caption { color: #eef5f8; }

.queue-card-stack {
  position: relative;
  width: calc(var(--card-w) + clamp(18px, 4.2vw, 26px));
  height: var(--card-h);
  overflow: visible;
}

.queue-card-stack > .queue-slot {
  position: absolute;
  top: 0;
  width: var(--card-w);
  height: var(--card-h);
  margin: 0;
}

.queue-card-stack > .current-slot {
  right: 0;
  left: auto;
  z-index: 3;
}

.queue-card-stack > .next-slot {
  left: 0;
  right: auto;
  top: clamp(8px, 2.4vw, 13px);
  z-index: 1;
  opacity: .82;
  transform: scale(.78) !important;
  transform-origin: left bottom;
  pointer-events: none;
  filter: brightness(.92) saturate(.94);
}

.next-slot .card {
  transform: none !important;
  transition: filter .16s ease;
}

/* Current stays the hero and still has the draggable hover. */
@media (hover:hover) and (pointer:fine) {
  .queue-card-stack:hover .next-slot .card {
    filter: brightness(1.025);
  }
  .current-slot:not(.dragging):hover .card:not(.flip-in):not(.queue-promoting) {
    transform: translateY(-9px) scale(1.045) rotate(-.8deg);
  }
}

.card.queue-promoting,
.card.queue-new-next {
  will-change: transform, opacity;
}

/* The stored joker keeps the SAME visible identity/name it had in PICK ONE. */
.deck-slot.has-joker .stored-joker-card .joker-title {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  font-size: clamp(10px, 2.7vw, 14px);
  line-height: 1.02;
}
.deck-slot.has-joker .stored-joker-card .joker-desc {
  font-size: clamp(7px, 1.8vw, 9.5px);
  line-height: 1.05;
  opacity: .84;
}

/* More breathing room between the three bottom actions on compact screens too. */
@media (max-width: 390px) {
  .queue-row {
    gap: clamp(14px, 4vw, 22px) !important;
    grid-template-columns: calc(var(--card-w) + 18px) var(--card-w) var(--card-w) !important;
  }
  .queue-card-stack { width: calc(var(--card-w) + 18px); }
  .queue-card-stack > .next-slot { top: 8px; transform: scale(.76) !important; }
}

@media (orientation: landscape) and (max-height: 620px) {
  .queue-row {
    grid-template-columns: calc(var(--card-w) + 18px) var(--card-w) var(--card-w) !important;
    gap: 14px !important;
    min-height: calc(var(--card-h) + 20px);
  }
  .queue-cell { grid-template-rows: var(--card-h) 18px; }
  .queue-caption { margin-top: 4px; font-size: 8px; }
  .queue-card-stack { width: calc(var(--card-w) + 18px); }
}


/* V26 — Joker identity stays on-card; explanation lives in a hover bubble. */
.joker-card .joker-front {
  gap: clamp(7px, 1.6vw, 11px);
  padding: clamp(8px, 2vw, 12px) clamp(6px, 1.5vw, 9px);
}

.joker-card .joker-title {
  font-size: clamp(10.5px, 2.85vw, 15px);
  line-height: 1.02;
  max-width: 94%;
  text-wrap: balance;
}

/* Description is deliberately not printed on the face anymore. */
.joker-card .joker-desc { display: none !important; }

.choice-card.joker-choice,
.deck-slot.has-joker {
  overflow: visible !important;
}

.choice-card.joker-choice::after,
.deck-slot.has-joker::after {
  content: attr(data-joker-help);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 12px);
  z-index: 80;
  width: max-content;
  max-width: min(190px, 48vw);
  padding: 8px 10px;
  border-radius: 11px;
  background: #13232e;
  border: 2px solid rgba(173, 205, 220, .26);
  box-shadow: 0 5px 0 rgba(3, 10, 17, .3);
  color: #eef7fb;
  font: 700 clamp(10px, 2.45vw, 12px)/1.2 'Quicksand', sans-serif;
  letter-spacing: 0;
  text-align: center;
  white-space: normal;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 7px) scale(.94);
  transform-origin: 50% 100%;
  transition:
    opacity .12s ease,
    transform .2s var(--ui-spring),
    visibility 0s linear .14s;
}

.choice-card.joker-choice::before,
.deck-slot.has-joker::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  z-index: 81;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: #13232e;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateX(-50%) rotate(45deg) scale(.7);
  transition: opacity .1s ease, transform .18s var(--ui-spring), visibility 0s linear .14s;
}

@media (hover: hover) and (pointer: fine) {
  .choice-card.joker-choice.is-ready:hover::after,
  .deck-slot.has-joker:hover::after,
  .choice-card.joker-choice.is-ready:focus-visible::after,
  .deck-slot.has-joker:focus-visible::after {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0) scale(1);
    transition-delay: .07s, .07s, 0s;
  }

  .choice-card.joker-choice.is-ready:hover::before,
  .deck-slot.has-joker:hover::before,
  .choice-card.joker-choice.is-ready:focus-visible::before,
  .deck-slot.has-joker:focus-visible::before {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) rotate(45deg) scale(1);
    transition-delay: .07s, .07s, 0s;
  }
}

/* =========================================================
   V28 — bottom queue spacing + full-size discard
   ========================================================= */
.queue-zone {
  padding-bottom: max(10px, env(safe-area-inset-bottom));
}

.queue-cell {
  grid-template-rows: var(--card-h) 30px;
}

.queue-caption {
  margin-top: 7px;
  padding-bottom: 8px;
}

/* DISCARD uses the exact same physical footprint as a normal PLAY card. */
.discard-slot {
  width: var(--card-w);
  height: var(--card-h);
  transform: none;
  gap: clamp(7px, 2vw, 10px);
}

.discard-slot:hover:not(:disabled):not(.exhausted),
.discard-slot.drag-over {
  transform: translateY(-3px) scale(1.015);
}

/* Counter belongs inside the card, directly under the X. */
.discard-slot strong {
  position: static;
  left: auto;
  bottom: auto;
  transform: none;
  display: block;
  margin: 0;
  line-height: 1;
}

.discard-slot .discard-icon {
  margin: 0;
}

@media (orientation: landscape) and (max-height: 620px) {
  .queue-zone { padding-bottom: max(6px, env(safe-area-inset-bottom)); }
  .queue-cell { grid-template-rows: var(--card-h) 24px; }
  .queue-caption { margin-top: 4px; padding-bottom: 5px; }
}

/* =========================================================
   V29 — Joker help only after the picked card has fully landed
   ========================================================= */
/* The card face always keeps its identity/name. The helper copy never replaces it. */
.joker-card .joker-title {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
}

/* PICK ONE cards never show the help bubble, even after being dealt/revealed. */
.choice-card.joker-choice::before,
.choice-card.joker-choice::after {
  content: none !important;
  display: none !important;
}

/* A stored joker only exposes help once its landing bounce is completely finished. */
.deck-slot.has-joker:not(.is-joker-settled)::before,
.deck-slot.has-joker:not(.is-joker-settled)::after {
  content: none !important;
  display: none !important;
}

.deck-slot.has-joker.is-joker-settled::after {
  content: attr(data-joker-help);
}

@media (hover: hover) and (pointer: fine) {
  .deck-slot.has-joker.is-joker-settled:hover::after,
  .deck-slot.has-joker.is-joker-settled:focus-visible::after {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0) scale(1);
    transition-delay: .07s, .07s, 0s;
  }

  .deck-slot.has-joker.is-joker-settled:hover::before,
  .deck-slot.has-joker.is-joker-settled:focus-visible::before {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) rotate(45deg) scale(1);
    transition-delay: .07s, .07s, 0s;
  }
}

/* =========================================================
   V30 — portrait space pass
   Use the viewport instead of vertically centering a fixed-height game.
   ========================================================= */
@media (orientation: portrait) {
  :root {
    /* Keep the board generous without handing out too many free cards. */
    --stack-step: clamp(30px, 6.6svh, 66px);
  }

  .app {
    align-items: stretch;
  }

  .game-shell {
    padding-top: max(2px, env(safe-area-inset-top));
    padding-bottom: max(0px, env(safe-area-inset-bottom));
    padding-left: clamp(10px, 3vw, 18px);
    padding-right: clamp(10px, 3vw, 18px);
    grid-template-rows: auto minmax(0, 1fr) 4px auto;
    gap: 0;
    align-content: stretch;
  }

  .hud {
    min-height: clamp(108px, 13svh, 122px);
    padding-top: 0;
  }

  .best-score { top: -1px; }
  .pause-button { top: -6px; }

  .score {
    padding-top: clamp(24px, 3.4svh, 32px);
    margin-bottom: 0;
  }

  .level-block {
    margin-top: clamp(7px, 1.1svh, 11px);
  }

  .level-meta { margin-bottom: 4px; }

  .board-zone {
    min-height: 0;
    height: 100%;
    align-self: stretch;
  }

  .board {
    height: 100%;
    min-height: 0;
    padding-top: 2px;
    padding-bottom: 0;
    gap: clamp(5px, 1.8vw, 10px);
  }

  .empty-hint {
    top: 0;
  }

  .separator {
    height: 4px;
    align-self: center;
    background-size: 16px 4px;
    margin: 0;
  }

  .queue-zone {
    padding-top: 0;
    padding-bottom: max(0px, env(safe-area-inset-bottom));
  }

  .queue-row {
    min-height: calc(var(--card-h) + 18px);
  }

  .queue-cell {
    grid-template-rows: var(--card-h) 18px;
  }

  .queue-caption {
    margin-top: 2px;
    padding-bottom: 0;
  }
}

@media (orientation: portrait) and (max-height: 700px) {
  .game-shell {
    grid-template-rows: auto minmax(0, 1fr) 3px auto;
  }

  .hud { min-height: 104px; }
  .score { padding-top: 22px; }
  .level-block { margin-top: 6px; }
  .queue-row { min-height: calc(var(--card-h) + 16px); }
  .queue-cell { grid-template-rows: var(--card-h) 16px; }
  .queue-caption { margin-top: 1px; }
}


/* =========================================================
   V31 — joker name never disappears
   ========================================================= */
/* Keep the card name physically printed on the face at all times.
   A bottom chip makes it readable in PICK ONE, in flight, and stored in DECK. */
.joker-card .joker-front {
  position: relative;
  justify-content: flex-start;
  padding-top: clamp(8px, 2vw, 12px);
  padding-bottom: clamp(26px, 6.8vw, 34px);
}

.joker-card .joker-icon {
  margin-top: auto;
  margin-bottom: auto;
}

.joker-card .joker-title {
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 7px;
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  padding: 4px 6px;
  border-radius: 10px;
  background: rgba(8, 20, 29, .24);
  border: 1px solid rgba(255,255,255,.12);
  color: #f5fbff;
  text-align: center;
  font-size: clamp(9px, 2.45vw, 13px);
  line-height: 1;
  letter-spacing: .15px;
  font-weight: 700;
  text-wrap: balance;
  box-shadow: none;
  z-index: 2;
}

.choice-card.joker-choice .joker-title,
.deck-slot.has-joker .stored-joker-card .joker-title,
.joker-transfer-card .joker-title {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
}


/* =========================================================
   V32 — tighter portrait spacing, board consumes the free height
   ========================================================= */
@media (orientation: portrait) {
  .game-shell {
    padding-top: max(2px, env(safe-area-inset-top));
    padding-bottom: max(0px, env(safe-area-inset-bottom));
    grid-template-rows: auto minmax(0, 1fr) 6px auto;
    gap: 2px;
  }

  .hud {
    min-height: clamp(102px, 12.8svh, 116px);
    padding-top: 0;
  }

  .best-score { top: 0; }
  .pause-button { top: -8px; }

  .score {
    padding-top: clamp(24px, 3.2svh, 30px);
    font-size: clamp(46px, 13.2vw, 78px);
  }

  .level-block { margin-top: clamp(7px, 1.2svh, 11px); }
  .level-meta { margin-bottom: 4px; }

  .board-zone {
    min-height: 0;
    height: auto;
    align-self: stretch;
  }

  .board {
    min-height: 0;
    height: 100%;
    padding-top: clamp(2px, .45svh, 6px);
    gap: clamp(6px, 2vw, 12px);
    align-items: stretch;
  }

  .separator {
    height: 4px;
    background-size: 16px 4px;
    align-self: center;
  }

  .queue-zone {
    padding-top: 0;
    padding-bottom: max(0px, env(safe-area-inset-bottom));
  }

  .queue-row {
    min-height: calc(var(--card-h) + 18px);
    align-items: end;
  }

  .queue-cell {
    grid-template-rows: var(--card-h) 18px;
  }

  .queue-caption {
    margin-top: 2px;
    padding-bottom: 0;
  }
}

@media (orientation: portrait) and (max-height: 700px) {
  .game-shell {
    grid-template-rows: auto minmax(0, 1fr) 5px auto;
    gap: 1px;
  }

  .hud { min-height: 98px; }
  .score { padding-top: 22px; }
  .level-block { margin-top: 6px; }
  .board { padding-top: 1px; }
  .queue-row { min-height: calc(var(--card-h) + 16px); }
  .queue-cell { grid-template-rows: var(--card-h) 16px; }
  .queue-caption { margin-top: 1px; }
}


/* =========================================================
   V33 — locked joker look + 3-zone portrait layout
   ========================================================= */
/* Use the provided webp as the shared joker icon in every state. */
.joker-card .joker-icon {
  display: block;
  width: clamp(42px, 11.5vw, 58px) !important;
  height: clamp(42px, 11.5vw, 58px) !important;
  min-width: 0;
  min-height: 0;
  flex: 0 0 auto;
  margin: auto;
  border-radius: 0 !important;
  background: center / contain no-repeat url('../assets/joker-icon.webp') !important;
  box-shadow: none !important;
  font-size: 0 !important;
  color: transparent !important;
}

/* Keep the stored joker visually congruent with the picked/revealed one. */
.choice-card.joker-choice .joker-front,
.joker-transfer-card .joker-front,
.deck-slot.has-joker .stored-joker-card .joker-front {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 0;
  padding: clamp(8px, 2vw, 12px) clamp(6px, 1.8vw, 9px) clamp(30px, 7.5vw, 36px);
  text-align: center;
  color: #eff7fb;
  background: #5a7488 !important;
  border: 3px solid #a9c4d3;
}

.choice-card.joker-choice .joker-title,
.joker-transfer-card .joker-title,
.deck-slot.has-joker .stored-joker-card .joker-title {
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 7px;
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  padding: 4px 6px;
  border-radius: 10px;
  background: rgba(8, 20, 29, .24);
  border: 1px solid rgba(255,255,255,.12);
  color: #f5fbff;
  text-align: center;
  font-size: clamp(9px, 2.35vw, 12px) !important;
  line-height: 1;
  letter-spacing: .1px;
  font-weight: 700;
  white-space: normal;
  text-wrap: balance;
  overflow: visible;
  z-index: 2;
}

.deck-slot.has-joker .stored-joker-card {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  transform: none !important;
  transform-origin: center center;
  filter: none;
}

.deck-slot.has-joker .stored-joker-card .card-inner {
  transform: rotateY(0deg) !important;
}

.deck-slot.has-joker .stored-joker-card .joker-desc,
.choice-card.joker-choice .joker-desc,
.joker-transfer-card .joker-desc {
  display: none !important;
}

/* Portrait: split cleanly into 3 parts — top UI, board, bottom queue. */
@media (orientation: portrait) {
  .app {
    align-items: stretch;
  }

  .game-shell {
    padding-top: max(4px, env(safe-area-inset-top));
    padding-right: 10px;
    padding-bottom: max(2px, env(safe-area-inset-bottom));
    padding-left: 10px;
    grid-template-rows: auto minmax(0, 1fr) auto;
    gap: 0;
  }

  .hud {
    min-height: 112px;
    padding-top: 0;
    margin: 0;
  }

  .best-score {
    top: 2px;
    left: 0;
  }

  .pause-button {
    top: 0;
    right: 0;
  }

  .score {
    padding-top: 20px;
    margin: 0;
    font-size: clamp(50px, 14vw, 80px);
  }

  .level-block {
    margin-top: 4px;
  }

  .level-meta {
    margin-bottom: 4px;
  }

  .board-zone {
    min-height: 0;
    height: auto;
    padding-top: 0;
    align-self: stretch;
  }

  .board {
    min-height: 0;
    height: 100%;
    padding-top: 6px;
    padding-bottom: 0;
    align-items: stretch;
    gap: clamp(8px, 2.2vw, 12px);
  }

  .separator {
    display: none;
  }

  .queue-zone {
    padding-top: 8px;
    padding-bottom: max(2px, env(safe-area-inset-bottom));
    overflow: visible;
  }

  .queue-row {
    min-height: calc(var(--card-h) + 24px);
    align-items: start;
    gap: clamp(16px, 5vw, 26px) !important;
  }

  .queue-cell {
    grid-template-rows: var(--card-h) 18px;
    align-items: start;
  }

  .queue-card-stack {
    height: var(--card-h);
  }

  .queue-caption {
    margin-top: 4px;
    padding-bottom: 0;
    align-self: start;
  }
}

@media (orientation: portrait) and (max-height: 720px) {
  .game-shell {
    padding-top: max(2px, env(safe-area-inset-top));
    padding-bottom: max(0px, env(safe-area-inset-bottom));
  }

  .hud {
    min-height: 102px;
  }

  .score {
    padding-top: 18px;
    font-size: clamp(46px, 13vw, 72px);
  }

  .board {
    padding-top: 4px;
  }

  .queue-zone {
    padding-top: 6px;
  }

  .queue-row {
    min-height: calc(var(--card-h) + 20px);
  }

  .queue-cell {
    grid-template-rows: var(--card-h) 16px;
  }

  .queue-caption {
    margin-top: 2px;
  }
}


/* =========================================================
   V34 — REAL 3-ZONE LAYOUT
   Direct shell children are now exactly HUD / BOARD / QUEUE.
   This intentionally does NOT depend on viewport orientation: the game shell
   itself is portrait even when hosted inside a wide desktop browser.
   ========================================================= */
@media (min-height: 621px) {
  .app {
    min-height: 100svh;
    align-items: stretch;
    justify-items: center;
  }

  .game-shell {
    width: min(100%, var(--shell-max));
    height: 100svh;
    min-height: 0;
    padding: max(8px, env(safe-area-inset-top)) 10px 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
    gap: 0;
    row-gap: 0;
    align-content: stretch;
    align-items: stretch;
    overflow: hidden;
  }

  /* ZONE 1 — UI. Natural height only; no fake spacer above or below. */
  .hud {
    position: relative;
    min-height: 0;
    height: auto;
    padding: 0;
    margin: 0;
  }

  .best-score {
    top: 0;
    left: 0;
  }

  .pause-button {
    top: -4px;
    right: -4px;
  }

  .score {
    padding-top: clamp(22px, 2.8svh, 30px);
    margin: 0;
    font-size: clamp(48px, 13vw, 78px);
  }

  .level-block {
    margin-top: clamp(5px, .9svh, 9px);
    margin-bottom: 8px;
  }

  .level-meta {
    margin-bottom: 4px;
  }

  /* ZONE 2 — BOARD. It owns EVERY remaining pixel between UI and decks. */
  .board-zone {
    position: relative;
    min-height: 0;
    height: auto;
    margin: 0;
    padding: 0;
    overflow: hidden;
    align-self: stretch;
  }

  .board {
    width: 100%;
    height: 100%;
    min-height: 0;
    margin: 0;
    padding: 8px 0 6px;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: clamp(7px, 1.8vw, 12px);
    align-items: stretch;
  }

  .lane,
  .pile {
    height: 100%;
  }

  /* The dotted death line belongs to the BOARD instead of stealing a 4th row. */
  .separator {
    display: block;
    position: absolute;
    z-index: 6;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 4px;
    margin: 0;
    padding: 0;
    background-size: 18px 4px;
    pointer-events: none;
  }

  /* ZONE 3 — DECKS. Exactly 8px internal top padding, then normal card height. */
  .queue-zone {
    min-height: 0;
    height: auto;
    margin: 0;
    padding: 8px 0 max(0px, env(safe-area-inset-bottom));
    overflow: visible;
    align-self: end;
  }

  .queue-row {
    width: 100%;
    min-height: calc(var(--card-h) + 18px);
    margin: 0;
    align-items: start;
    justify-content: center;
    gap: clamp(16px, 4.7vw, 28px) !important;
  }

  .queue-cell {
    grid-template-rows: var(--card-h) 18px;
    align-items: start;
  }

  .queue-card-stack,
  .discard-slot,
  .deck-slot {
    height: var(--card-h);
  }

  .queue-caption {
    margin-top: 3px;
    padding: 0;
    align-self: start;
  }
}

@media (min-height: 621px) and (max-height: 760px) {
  .game-shell {
    padding-top: max(5px, env(safe-area-inset-top));
  }

  .score {
    padding-top: 18px;
    font-size: clamp(45px, 12vw, 68px);
  }

  .level-block {
    margin-top: 4px;
    margin-bottom: 6px;
  }

  .board {
    padding-top: 6px;
  }

  .queue-zone {
    padding-top: 7px;
  }

  .queue-row {
    min-height: calc(var(--card-h) + 16px);
  }

  .queue-cell {
    grid-template-rows: var(--card-h) 16px;
  }

  .queue-caption {
    margin-top: 2px;
  }
}

/* =========================================================
   V36 — roomier bottom controls
   More breathing room around PLAY / DISCARD / DECK and a slightly
   larger card-to-label gap.
   ========================================================= */
.queue-zone {
  padding-top: 18px !important;
  padding-bottom: 24px !important;
}

.queue-row {
  min-height: calc(var(--card-h) + 24px) !important;
}

.queue-cell {
  grid-template-rows: var(--card-h) 22px !important;
}

.queue-caption {
  margin-top: 7px !important;
  padding-bottom: 0 !important;
}


/* V36.1 — exact requested patch on V36 */
.separator {
  display: none !important;
}

.queue-caption {
  padding-top: 8px !important;
}


/* =========================================================
   V38 — stored joker title alignment + discard jokers
   ========================================================= */
.joker-discard-reset .joker-front { background: #4d6578 !important; }
.joker-discard-plus .joker-front { background: #536f64 !important; }

/* The title uses exactly the same centered geometry before, during and after landing. */
.choice-card.joker-choice .joker-title,
.joker-transfer-card .joker-title,
.deck-slot.has-joker .stored-joker-card .joker-title {
  left: 6px !important;
  right: 6px !important;
  bottom: 7px !important;
  width: auto !important;
  min-height: 24px;
  margin: 0 !important;
  padding: 4px 6px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  text-align: center !important;
  text-indent: 0 !important;
  white-space: normal !important;
  line-height: 1.02 !important;
  transform: none !important;
  box-sizing: border-box;
}

.deck-slot.has-joker .stored-joker-card,
.deck-slot.has-joker .stored-joker-card .card-inner,
.deck-slot.has-joker .stored-joker-card .joker-front {
  box-sizing: border-box;
}


/* =========================================================
   V39 — stored jokers can be dragged and used
   ========================================================= */
.deck-slot.has-joker .stored-joker-card {
  touch-action: none;
  cursor: grab;
}

.deck-slot.has-joker.joker-dragging {
  cursor: grabbing;
}

.deck-slot.has-joker.joker-dragging::before,
.deck-slot.has-joker.joker-dragging::after {
  display: none !important;
}

.joker-drag-ghost {
  cursor: grabbing;
  filter: brightness(1.035);
}

/* Lane jokers: only the lane under the card is advertised as the drop target. */
.board.joker-drag-lane .lane {
  transition: background .16s ease, transform .18s var(--ui-spring), opacity .16s ease;
}

.board.joker-drag-lane .lane.joker-drop-valid {
  background: linear-gradient(
    to bottom,
    rgba(119,232,120,.16) 0%,
    rgba(119,232,120,.08) 30%,
    rgba(119,232,120,.02) 62%,
    rgba(119,232,120,0) 90%
  );
  transform: translateY(-3px);
}

.board.joker-drag-lane .lane.joker-drop-invalid {
  background: linear-gradient(
    to bottom,
    rgba(255,110,114,.13) 0%,
    rgba(255,110,114,.05) 38%,
    rgba(255,110,114,0) 88%
  );
}

/* General jokers can be released anywhere; the board subtly confirms that. */
.board.joker-drag-general {
  background: linear-gradient(
    to bottom,
    rgba(255,255,255,.025),
    rgba(255,255,255,0) 70%
  );
}

/* =========================================================
   V40 — finite deck rewards + true empty deck slot
   ========================================================= */
.deck-slot.deck-empty {
  opacity: 1 !important;
  pointer-events: none;
  cursor: default;
}

.deck-slot.deck-empty::before {
  content: '' !important;
  display: block !important;
  position: absolute;
  inset: 0;
  border: 2px solid rgba(163, 184, 198, .10);
  border-radius: var(--card-radius);
  background: rgba(255,255,255,.008);
  box-shadow: none;
  opacity: 1;
  visibility: visible;
  transform: none;
}

.deck-slot.deck-empty::after {
  content: none !important;
  display: none !important;
}

.deck-slot.deck-empty .deck-card,
.deck-slot.deck-empty .stored-joker-card {
  display: none !important;
}


/* =========================================================
   V42 — drag lane hover parity + joker title 1:1
   ========================================================= */
/* While PLAY is physically over a lane, use the exact same top-down light
   treatment as pointer hover. The existing drag-match/drag-valid semantics
   stay intact; this only mirrors the visual hover feedback. */
.lane.drag-valid::before,
.lane.drag-match::before {
  opacity: 1 !important;
}

/* Keep the joker identity label literally identical in PICK ONE, in flight,
   and after landing in DECK. One line everywhere; no stored-state reflow. */
.choice-card.joker-choice .joker-title,
.joker-transfer-card .joker-title,
.deck-slot.has-joker .stored-joker-card .joker-title {
  position: absolute !important;
  left: 6px !important;
  right: 6px !important;
  bottom: 7px !important;
  width: auto !important;
  min-height: 24px !important;
  margin: 0 !important;
  padding: 4px 5px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  flex-wrap: nowrap !important;
  text-align: center !important;
  text-indent: 0 !important;
  white-space: nowrap !important;
  text-wrap: nowrap !important;
  overflow: visible !important;
  font-size: clamp(8px, 2.15vw, 11px) !important;
  line-height: 1 !important;
  letter-spacing: 0 !important;
  font-weight: 700 !important;
  transform: none !important;
  box-sizing: border-box !important;
}
