/* ============================================================
   BOOT
   ============================================================ */
.boot {
  align-items: center;
  justify-content: center;
  background: radial-gradient(120% 80% at 50% 30%, #4E8F1E, #1C3410 70%);
}
.boot__inner { display: flex; flex-direction: column; align-items: center; gap: var(--sp-5); width: min(78%, 300px); }
.boot__logo {
  width: 100%;
  animation: boot-land var(--t-slow) var(--ease-pop) both;
  filter: drop-shadow(0 10px 20px rgba(0, 0, 0, .45));
}
@keyframes boot-land {
  from { opacity: 0; transform: translateY(-40px) scale(.7) rotate(-6deg); }
  to { opacity: 1; transform: none; }
}
.boot__bar {
  position: relative;
  width: 100%;
  height: 16px;
  border-radius: var(--r-pill);
  overflow: hidden;
  background: rgba(10, 24, 4, .7);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, .6), 0 0 0 3px var(--brine);
}
.boot__fill {
  height: 100%;
  width: 0%;
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, var(--dill-lit), var(--dill-deep));
  transition: width 200ms var(--ease-out);
}
.boot__hint { font-weight: 800; font-size: var(--step-0); color: rgba(255, 249, 236, .8); }

/* ============================================================
   MENU — built around the mascot hero shot
   ============================================================ */
.menu {
  justify-content: space-between;
  padding: calc(var(--safe-t) + var(--sp-3)) var(--sp-4) calc(var(--safe-b) + var(--sp-4));
  overflow: hidden;
}

/* The art is its own layer so it can breathe without moving the UI. Oversized on
   every side, so the drift never pulls an edge into frame. */
.menu__art {
  position: absolute;
  inset: -3%;
  background-size: cover;
  background-position: center;
  will-change: transform;
  /* Breathes at half the logo's distance and half its speed, so the screen is
     never quite still without anything actually drawing attention. */
  animation: art-bob 9s ease-in-out infinite;
}
@keyframes art-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3.5px); }
}

.menu__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* The mascot's sky is bright and his ground is dark, so the scrim only has to
     firm up the very top (for the HUD) and the very bottom (for the button). */
  background: linear-gradient(
    180deg,
    rgba(14, 40, 60, .42) 0%,
    rgba(20, 40, 8, 0) 22%,
    rgba(20, 40, 8, 0) 58%,
    rgba(18, 34, 8, .55) 80%,
    rgba(12, 26, 4, .95) 100%
  );
}

.menu > *:not(.menu__art):not(.menu__scrim) { position: relative; z-index: 1; }

.menu__top { display: flex; justify-content: center; }
/* Never wrap: a second row of chips dropped straight onto the level path. */
.hud { display: flex; gap: clamp(4px, 1.8cqw, 8px); align-items: center; justify-content: center; flex-wrap: nowrap; min-width: 0; }

/* Logo pinned high and kept modest: the mascot's raised mallet clears it above,
   and his face clears it below. He is the hero here, not the lettering. */
.menu__hero {
  display: flex;
  justify-content: center;
  margin-top: 0;
}
.menu__logowrap {
  position: relative;
  width: min(74%, 292px);
  will-change: transform;
  animation: logo-bob 4.5s ease-in-out infinite;
}
.menu__logo {
  width: 100%;
  filter: drop-shadow(0 10px 20px rgba(0, 0, 0, .55));
}
@keyframes logo-bob {
  0%, 100% { transform: translateY(0) rotate(-.5deg); }
  50% { transform: translateY(-7px) rotate(.5deg); }
}

/* A gloss travelling across the lettering. Masked to the logo's own alpha, so it
   follows the letters instead of sweeping a rectangle over them. */
.menu__shine {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg,
    transparent 42%,
    rgba(255, 255, 255, .0) 45%,
    rgba(255, 255, 255, .85) 50%,
    rgba(255, 255, 255, .0) 55%,
    transparent 58%);
  background-size: 300% 100%;
  background-repeat: no-repeat;
  -webkit-mask-image: url('../assets/img/ui/logo.png');
  mask-image: url('../assets/img/ui/logo.png');
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  animation: logo-shine 5s ease-in-out infinite;
}
@keyframes logo-shine {
  0%, 62% { background-position: 200% 0; }
  100% { background-position: -140% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .menu__logowrap, .menu__art { animation: none; }
  .menu__shine { animation: none; opacity: 0; }
}

.menu__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  margin-top: auto;
  margin-bottom: var(--sp-4);
}
.menu__play { min-width: 68%; animation: play-pulse 2.6s var(--ease-out) infinite; }
@keyframes play-pulse {
  0%, 88%, 100% { transform: scale(1); }
  94% { transform: scale(1.045); }
}
@media (prefers-reduced-motion: reduce) { .menu__play { animation: none; } }
.menu__progress { font-weight: 800; font-size: var(--step-0); color: rgba(255, 249, 236, .9); text-shadow: 0 1px 4px rgba(0, 0, 0, .8); }

.menu__nav { display: flex; justify-content: center; gap: var(--sp-4); }
.menu__navbtn {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  background: rgba(34, 64, 14, .6);
  box-shadow: inset 0 0 0 2px rgba(245, 230, 200, .28);
  transition: transform var(--t-fast) var(--ease-pop);
}
.menu__navbtn:active { transform: translateY(2px) scale(.96); }
.menu__navicon { font-size: 22px; line-height: 1; }
.menu__navlabel { font-size: var(--step--1); font-weight: 800; color: var(--kraft); }
.menu__badge {
  position: absolute;
  top: 4px; right: 4px;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--gingham);
  box-shadow: 0 0 0 2px var(--cream);
  animation: badge-throb 1.4s ease-in-out infinite;
}
@keyframes badge-throb { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.35); } }

/* ============================================================
   MAP
   ============================================================ */
.map { overflow: hidden; }
.map__scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Above the backdrop scrim so the nodes and path stay interactive. */
  z-index: 2;
}
.map__scroll::-webkit-scrollbar { display: none; }

/* The valley art is pinned to the screen, not to the ~12,000px trail: tiling it
   left a hard sky-meets-ground seam, and `cover` on the full trail zoomed it to
   mush. The trail scrolls over a static backdrop instead. */
.map {
  background-size: cover;
  background-position: center;
}
.map::before {
  /* The art is bright and high-contrast; this scrim is what lets nodes read. */
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 60% at 50% 50%, rgba(18, 38, 8, .12), rgba(18, 38, 8, .5)),
    linear-gradient(180deg, rgba(18, 38, 8, .5) 0%, rgba(18, 38, 8, .18) 30%, rgba(18, 38, 8, .5) 100%);
  pointer-events: none;
  z-index: 1;
}

.map__trail { position: relative; width: 100%; }

.map__path { position: absolute; inset: 0; width: 100%; height: 100%; }
.map__path-base { fill: none; stroke: rgba(34, 64, 14, .55); stroke-width: 9; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.map__path-dash {
  fill: none;
  stroke: var(--kraft);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1 14;
  vector-effect: non-scaling-stroke;
  opacity: .75;
}

.map__node {
  position: absolute;
  /* Centre with `transform`, not the `translate` property: the :active press
     animation is a `transform`, and the two DON'T override each other — they
     stack. With both applied, pressing shifted the node half its own width up and
     left, out from under the finger, so the tap landed on empty space. This is
     why the hit area felt tiny and exact. */
  transform: translate(-50%, -50%);
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--cream);
  /* A jar lid: ridged rim, domed top. */
  background:
    repeating-conic-gradient(from 0deg, rgba(0, 0, 0, .16) 0deg 4deg, transparent 4deg 8deg),
    radial-gradient(circle at 38% 32%, #FFFFFF55, transparent 55%),
    linear-gradient(180deg, var(--world-tint, var(--dill)), color-mix(in srgb, var(--world-tint, var(--dill)) 55%, #000));
  box-shadow: 0 4px 0 rgba(24, 44, 10, .85), 0 8px 16px rgba(0, 0, 0, .45), inset 0 0 0 3px rgba(255, 249, 236, .5);
  text-shadow: 0 2px 0 rgba(0, 0, 0, .5);
  transition: transform var(--t-fast) var(--ease-pop);
}
/* Press feedback keeps the centring transform and adds to it, so the node stays
   put under the finger and just nudges down a touch. */
.map__node:active { transform: translate(-50%, -50%) translateY(3px) scale(.95); transform-origin: center; }
.map__node[data-state='locked'] {
  filter: grayscale(.85) brightness(.62);
  color: rgba(255, 249, 236, .7);
}
/* The next level is where the eye should land: bigger, ringed in amber, and
   pulsing. The ring is persistent so it still reads between pulse beats. */
.map__node[data-state='next'] {
  width: 66px;
  height: 66px;
  z-index: 3;
  font-size: var(--step-2);
  box-shadow:
    0 4px 0 rgba(24, 44, 10, .85),
    0 8px 20px rgba(0, 0, 0, .5),
    inset 0 0 0 3px rgba(255, 249, 236, .6),
    0 0 0 4px var(--amber),
    0 0 22px rgba(255, 182, 39, .7);
}
.map__node .stars { position: absolute; bottom: -11px; display: flex; gap: 1px; }

.map__pulse {
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 3px solid var(--amber);
  animation: node-pulse 1.8s var(--ease-out) infinite;
  pointer-events: none;
}
@keyframes node-pulse {
  0% { transform: scale(.85); opacity: .9; }
  100% { transform: scale(1.5); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .map__pulse { animation: none; opacity: .6; } }

.map__sign {
  position: absolute;
  left: 50%;
  translate: -50% 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--sp-2) var(--sp-5);
  border-radius: var(--r-md);
  background: linear-gradient(180deg, #C98B4E, var(--crate) 60%, var(--crate-deep));
  box-shadow: 0 5px 0 rgba(60, 36, 15, .8), 0 12px 24px rgba(0, 0, 0, .45), inset 0 2px 0 rgba(255, 255, 255, .3);
  z-index: 2;
  white-space: nowrap;
}
.map__sign::before, .map__sign::after {
  /* Nail heads — it's a board nailed to a post. */
  content: '';
  position: absolute;
  top: 7px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgba(40, 24, 8, .7);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35);
}
.map__sign::before { left: 9px; }
.map__sign::after { right: 9px; }
.map__signname { font-family: var(--font-display); font-size: var(--step-1); color: var(--cream); text-shadow: 0 2px 0 rgba(0, 0, 0, .5); }
.map__signrange, .map__signlock { font-size: var(--step--1); font-weight: 800; color: rgba(255, 249, 236, .85); }
.map__sign[data-locked='1'] { filter: saturate(.5) brightness(.85); }
.map__signlock { color: var(--amber); }

.map__top {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: var(--z-hud);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: calc(var(--safe-t) + var(--sp-2)) var(--sp-3) var(--sp-3);
  background: linear-gradient(180deg, rgba(18, 38, 8, .92), rgba(18, 38, 8, 0));
}
.map__top .hud { flex: 1; justify-content: flex-end; }

.stars { display: flex; gap: 2px; }
.stars .star { transition: filter var(--t-mid), transform var(--t-mid) var(--ease-pop); }
.stars .star[data-on='0'] { filter: grayscale(1) brightness(.45); }
.stars[data-animate='1'] .star[data-on='1'] { animation: star-pop var(--t-slow) var(--ease-pop) both; }
@keyframes star-pop {
  from { transform: scale(0) rotate(-90deg); opacity: 0; }
  60% { transform: scale(1.35) rotate(10deg); }
  to { transform: scale(1) rotate(0); opacity: 1; }
}

/* ============================================================
   LEVEL INTRO
   ============================================================ */
.intro { align-items: center; justify-content: center; }
.intro__scrim { position: absolute; inset: 0; background: rgba(10, 22, 4, .72); backdrop-filter: blur(5px); }
.intro__card {
  position: relative;
  width: min(88%, 340px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  text-align: center;
  animation: modal-pop var(--t-slow) var(--ease-pop) both;
}
.intro__world { font-weight: 900; font-size: var(--step--1); letter-spacing: .14em; text-transform: uppercase; color: var(--dill-deep); }
.intro__level { font-family: var(--font-display); font-size: var(--step-4); color: var(--brine); line-height: 1; }

.intro__goal { width: 100%; }
.intro__goallabel { display: block; font-size: var(--step--1); font-weight: 900; letter-spacing: .1em; text-transform: uppercase; color: var(--crate-deep); }
.intro__goaltext { font-size: var(--step-1); font-weight: 800; color: var(--brine); }

.intro__moves { display: flex; align-items: baseline; gap: var(--sp-1); }
.intro__movesnum { font-family: var(--font-display); font-size: var(--step-3); color: var(--dill-deep); }
.intro__moveslabel { font-weight: 900; color: var(--brine-soft); }

.intro__boosters { width: 100%; }
.intro__boosterlabel { display: block; font-size: var(--step--1); font-weight: 900; letter-spacing: .1em; text-transform: uppercase; color: var(--crate-deep); margin-bottom: var(--sp-2); }
.intro__boosterrow { display: flex; gap: var(--sp-2); justify-content: center; }

.boosterchip {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--sp-2);
  width: 88px;
  border-radius: var(--r-md);
  background: rgba(34, 64, 14, .08);
  box-shadow: inset 0 0 0 2px rgba(34, 64, 14, .22);
  transition: transform var(--t-fast) var(--ease-pop), box-shadow var(--t-fast);
}
.boosterchip[data-on='1'] {
  background: rgba(111, 191, 46, .22);
  box-shadow: inset 0 0 0 3px var(--dill), 0 0 14px rgba(111, 191, 46, .5);
  transform: translateY(-3px);
}
.boosterchip:disabled { opacity: .45; }
.boosterchip__icon { width: 40px; height: 40px; }
.boosterchip__name { font-size: var(--step--1); font-weight: 900; color: var(--brine); }
.boosterchip__count { font-size: var(--step--1); font-weight: 800; color: var(--crate-deep); }

.intro__back { font-weight: 800; color: var(--brine-soft); text-decoration: underline; padding: var(--sp-1); }

/* ============================================================
   GAME
   ============================================================ */
.game {
  padding: calc(var(--safe-t) + var(--sp-2)) var(--sp-3) calc(var(--safe-b) + var(--sp-2));
  gap: clamp(3px, 1.2cqw, 8px);
}
.game__vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(115% 80% at 50% 45%, rgba(12, 28, 4, .28), rgba(12, 28, 4, .86));
  pointer-events: none;
}
.game > *:not(.game__vignette) { position: relative; z-index: 1; }

.game__top {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: clamp(3px, 1.2cqw, 8px) var(--sp-3);
  border-radius: var(--r-md);
  flex: none;
}
.game__moves { display: flex; flex-direction: column; align-items: center; line-height: 1; }
.game__movesnum {
  font-family: var(--font-display);
  font-size: var(--step-3);
  color: var(--cream);
  text-shadow: 0 2px 0 rgba(0, 0, 0, .5);
  font-variant-numeric: tabular-nums;
  transition: color var(--t-mid);
}
.game__movesnum[data-low='1'] { color: #FF9A88; animation: moves-warn 1s ease-in-out infinite; }
@keyframes moves-warn { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
.game__moveslabel { font-size: var(--step--1); font-weight: 900; color: rgba(255, 249, 236, .7); text-transform: uppercase; letter-spacing: .08em; }

.game__scorebox { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; line-height: 1; }
/* The number is the thing the player watches, so it outranks its own label. */
.game__scorelabel {
  font-size: 9px;
  font-weight: 900;
  color: rgba(255, 249, 236, .6);
  text-transform: uppercase;
  letter-spacing: .1em;
}
.game__scorenum {
  font-family: var(--font-display);
  font-size: var(--step-3);
  color: var(--amber);
  text-shadow: 0 2px 0 rgba(0, 0, 0, .5);
  font-variant-numeric: tabular-nums;
}

.game__meterrow { padding: 0 var(--sp-1); }

.game__goalstrip {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: clamp(4px, 1.4cqw, 8px) var(--sp-3);
  border-radius: var(--r-md);
  flex: none;
}
.game__goalcol { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
/* A quiet eyebrow: which level you're on, static context above the live objective. */
.game__level {
  font-size: var(--step--1);
  font-weight: 900;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--crate-deep);
}
.game__goallabel { font-size: var(--step--1); font-weight: 900; color: var(--brine); line-height: 1.2; }
.game__objective { display: flex; gap: var(--sp-2); flex: none; }

.goalpip {
  display: flex;
  align-items: center;
  gap: 3px;
  padding: 3px 8px 3px 3px;
  border-radius: var(--r-pill);
  background: rgba(34, 64, 14, .1);
  box-shadow: inset 0 0 0 2px rgba(34, 64, 14, .18);
  font-weight: 900;
  font-size: var(--step--1);
  color: var(--brine);
  font-variant-numeric: tabular-nums;
  transition: background var(--t-mid), transform var(--t-mid) var(--ease-pop);
}
.goalpip[data-done='1'] { background: rgba(111, 191, 46, .35); box-shadow: inset 0 0 0 2px var(--dill); }
.goalpip__icon { width: 24px; height: 24px; }
.goalpip__glyph { font-size: 16px; width: 24px; text-align: center; }

.game__boardwrap { flex: 1; min-height: 0; display: grid; place-items: center; }
.game__canvas { width: 100%; height: 100%; touch-action: none; }
.game__canvas[data-armed='1'] { cursor: crosshair; }

/* Kept tight on purpose: every pixel spent here is a pixel taken off the board,
   and the board is the game. Still >=44px tall for thumbs. */
.game__boosters { display: flex; justify-content: center; gap: clamp(8px, 3cqw, 14px); flex: none; }
.gbooster {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: clamp(3px, 1.4cqw, 6px);
  min-height: 44px;
  padding: clamp(4px, 1.4cqw, 7px) clamp(8px, 2.8cqw, 13px);
  border-radius: var(--r-md);
  background: linear-gradient(180deg, var(--cream), var(--kraft-dim));
  box-shadow: 0 4px 0 rgba(110, 68, 31, .8), 0 8px 16px rgba(0, 0, 0, .35), inset 0 2px 0 rgba(255, 255, 255, .6);
  transition: transform var(--t-fast) var(--ease-pop), box-shadow var(--t-fast);
}
.gbooster:active { transform: translateY(3px); box-shadow: 0 1px 0 rgba(110, 68, 31, .8); }
.gbooster[data-armed='1'] {
  box-shadow: 0 4px 0 var(--amber-deep), 0 0 0 3px var(--amber), 0 0 18px rgba(255, 182, 39, .7);
  transform: translateY(-2px);
}
.gbooster__icon { width: clamp(24px, 7.4cqw, 34px); height: clamp(24px, 7.4cqw, 34px); flex: none; }
.gbooster__label { font-size: var(--step--1); font-weight: 900; color: var(--brine); white-space: nowrap; }
.gbooster__count {
  position: absolute;
  top: -6px; right: -6px;
  min-width: clamp(17px, 4.4cqw, 21px); height: clamp(17px, 4.4cqw, 21px);
  padding: 0 4px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--dill);
  color: var(--cream);
  font-size: var(--step--1);
  font-weight: 900;
  box-shadow: 0 2px 0 var(--dill-deep), 0 0 0 2px var(--cream);
}
.gbooster__count[data-zero='1'] { background: var(--crate); box-shadow: 0 2px 0 var(--crate-deep), 0 0 0 2px var(--cream); }

/* ============================================================
   RESULT
   ============================================================ */
.result { align-items: center; justify-content: center; }
.result__scrim { position: absolute; inset: 0; background: rgba(10, 22, 4, .78); backdrop-filter: blur(5px); }
.result[data-won='1'] .result__scrim {
  background: radial-gradient(90% 60% at 50% 40%, rgba(111, 191, 46, .34), rgba(10, 22, 4, .86));
}
.result__card { position: relative; width: min(88%, 330px); animation: modal-pop var(--t-slow) var(--ease-pop) both; }
.result__inner { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); text-align: center; }
.result__title { font-family: var(--font-display); font-size: var(--step-3); color: var(--brine); line-height: 1.1; }
.result__sub { font-weight: 800; color: var(--brine-soft); font-size: var(--step-0); }
.result__score { display: flex; flex-direction: column; }
.result__scorelabel { font-size: var(--step--1); font-weight: 900; letter-spacing: .12em; text-transform: uppercase; color: var(--crate-deep); }
.result__scorenum { font-family: var(--font-display); font-size: var(--step-3); color: var(--dill-deep); font-variant-numeric: tabular-nums; }
.result__reward {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-pill);
  background: rgba(255, 182, 39, .22);
  box-shadow: inset 0 0 0 2px var(--amber);
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--amber-deep);
}
.result__coin { width: 26px; height: 26px; }
.result__firstclear { font-family: var(--font-ui); font-size: var(--step--1); font-weight: 800; color: var(--crate-deep); }
.result__actions { display: flex; flex-direction: column; gap: var(--sp-2); width: 100%; margin-top: var(--sp-1); }
.btn__coin { width: 22px; height: 22px; }

/* ============================================================
   SHOP
   ============================================================ */
.shop { background: radial-gradient(120% 70% at 50% 0%, #3E6B0C, #1C3410 70%); }
.shop__top {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: calc(var(--safe-t) + var(--sp-3)) var(--sp-3) var(--sp-2);
}
.shop__title { flex: 1; font-family: var(--font-display); font-size: var(--step-2); color: var(--cream); text-shadow: 0 3px 0 rgba(0, 0, 0, .45); }
.shop__top .hud { flex: none; }
.shop__scroll { flex: 1; overflow-y: auto; padding: var(--sp-3) var(--sp-3) calc(var(--safe-b) + var(--sp-5)); }
.shop__section { margin-bottom: var(--sp-5); }
.shop__heading {
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--kraft);
  margin-bottom: var(--sp-2);
  text-shadow: 0 2px 0 rgba(0, 0, 0, .4);
}
.shop__grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--sp-3); }

.shopcard {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-1);
  padding: var(--sp-4) var(--sp-3) var(--sp-3);
  text-align: center;
}
.shopcard__icon { width: 56px; height: 56px; }
.shopcard__name { font-family: var(--font-display); font-size: var(--step-1); color: var(--brine); }
.shopcard__blurb { font-size: var(--step--1); font-weight: 700; color: var(--brine-soft); min-height: 2.4em; line-height: 1.2; }
.shopcard .btn { margin-top: var(--sp-1); }
.shopcard__owned {
  position: absolute;
  top: 8px; left: 8px;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: rgba(34, 64, 14, .12);
  font-size: var(--step--1);
  font-weight: 900;
  color: var(--brine-soft);
}
.shopcard__tag {
  position: absolute;
  top: -9px; left: 50%;
  translate: -50% 0;
  padding: 2px 10px;
  border-radius: var(--r-pill);
  background: var(--gingham);
  color: var(--cream);
  font-size: var(--step--1);
  font-weight: 900;
  white-space: nowrap;
  box-shadow: 0 2px 0 var(--gingham-deep);
}

/* ============================================================
   DAILY
   ============================================================ */
.daily {
  /* Gold, not purple: this is the reward screen, and amber is the game's
     currency colour everywhere else. */
  background: radial-gradient(125% 75% at 50% 0%, #B4791A, #3E6B0C 55%, #1C3410 85%);
  padding: calc(var(--safe-t) + var(--sp-3)) var(--sp-3) calc(var(--safe-b) + var(--sp-4));
  gap: var(--sp-3);
}
.daily__top { display: flex; align-items: center; gap: var(--sp-2); }
.daily__title { flex: 1; text-align: center; font-family: var(--font-display); font-size: var(--step-2); color: var(--cream); text-shadow: 0 3px 0 rgba(0, 0, 0, .45); }
.daily__sub { text-align: center; font-weight: 800; font-size: var(--step-0); color: rgba(255, 249, 236, .82); }

.daily__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); flex: 1; align-content: center; }
.dailycard {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  min-height: 116px;
  padding: var(--sp-3) var(--sp-2);
  border-radius: var(--r-md);
  background: linear-gradient(180deg, var(--cream), var(--kraft-dim));
  box-shadow: 0 4px 0 rgba(110, 68, 31, .6), inset 0 2px 0 rgba(255, 255, 255, .6);
  text-align: center;
}
.dailycard[data-big='1'] {
  grid-column: span 3;
  flex-direction: row;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-3);
  min-height: 96px;
  /* Day 7 is the payoff — it should look like the prize, not another tile. */
  background: linear-gradient(180deg, #FFE9A8, #F3C25A);
  box-shadow: 0 4px 0 var(--amber-deep), inset 0 2px 0 rgba(255, 255, 255, .7);
}
.dailycard[data-big='1'] .dailycard__icon { width: 52px; height: 52px; }
.dailycard[data-big='1'] .dailycard__label { font-size: var(--step-1); }
.dailycard[data-state='ready'] {
  box-shadow: 0 4px 0 var(--amber-deep), 0 0 0 3px var(--amber), 0 0 22px rgba(255, 182, 39, .65);
  animation: daily-ready 1.6s ease-in-out infinite;
}
@keyframes daily-ready { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) { .dailycard[data-state='ready'] { animation: none; } }
/* Upcoming days should read as prizes worth coming back for, not as disabled
   controls — only *claimed* days get greyed out. */
.dailycard[data-state='future'] { opacity: .92; }
.dailycard[data-state='claimed'] { opacity: .62; filter: saturate(.35); }
.dailycard[data-state='claimed'] .dailycard__icon { filter: grayscale(.8); }
.dailycard__day { font-size: var(--step--1); font-weight: 900; letter-spacing: .08em; text-transform: uppercase; color: var(--crate-deep); }
.dailycard__icon { width: 42px; height: 42px; }
.dailycard__label { font-family: var(--font-display); font-size: var(--step-0); color: var(--brine); }
.dailycard__tick {
  position: absolute;
  top: 4px; right: 6px;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--dill);
  color: var(--cream);
  font-size: 12px;
  font-weight: 900;
}
.daily__action { display: flex; justify-content: center; }
.daily__action .btn { min-width: 66%; }

/* ============================================================
   SETTINGS
   ============================================================ */
.settings {
  background: radial-gradient(120% 70% at 50% 0%, #3E6B0C, #1C3410 70%);
  padding-top: calc(var(--safe-t) + var(--sp-3));
}
.settings__top { display: flex; align-items: center; gap: var(--sp-2); padding: 0 var(--sp-3) var(--sp-2); }
.settings__title { flex: 1; text-align: center; font-family: var(--font-display); font-size: var(--step-2); color: var(--cream); text-shadow: 0 3px 0 rgba(0, 0, 0, .45); }
.settings__scroll { flex: 1; overflow-y: auto; padding: var(--sp-3) var(--sp-3) calc(var(--safe-b) + var(--sp-5)); display: flex; flex-direction: column; gap: var(--sp-3); }
.settings__panel { display: flex; flex-direction: column; gap: var(--sp-2); }
.settings__heading { font-family: var(--font-display); font-size: var(--step-1); color: var(--brine); }
.settings__note { font-size: var(--step--1); font-weight: 700; color: var(--brine-soft); }
.settings__row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); min-height: 44px; }
.settings__label { font-weight: 800; font-size: var(--step-0); color: var(--brine); }
.settings__stat { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3); padding: 3px 0; border-bottom: 1px dashed rgba(110, 68, 31, .28); }
.settings__stat:last-of-type { border-bottom: 0; }
.settings__statlabel { font-weight: 700; font-size: var(--step-0); color: var(--brine-soft); }
.settings__statvalue { font-family: var(--font-display); font-size: var(--step-0); color: var(--dill-deep); font-variant-numeric: tabular-nums; }
.settings__version { text-align: center; font-size: var(--step--1); font-weight: 700; color: rgba(245, 230, 200, .5); }

.switch { position: relative; display: inline-block; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch__track {
  display: block;
  width: 58px; height: 32px;
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, #B9A57F, #8C7A56);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, .4);
  transition: background var(--t-mid);
}
.switch__thumb {
  position: absolute;
  top: 3px; left: 3px;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: linear-gradient(180deg, #FFF, #DCCFB3);
  box-shadow: 0 2px 4px rgba(0, 0, 0, .4);
  transition: transform var(--t-mid) var(--ease-pop);
}
.switch input:checked + .switch__track { background: linear-gradient(180deg, var(--dill-lit), var(--dill-deep)); }
.switch input:checked + .switch__track .switch__thumb { transform: translateX(26px); }
.switch input:focus-visible + .switch__track { outline: 3px solid var(--sky); outline-offset: 3px; }

/* A card that is alone in its section spans the grid and lays out horizontally,
   rather than sitting in one column with a hole beside it. */
.shopcard--wide {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--sp-3);
  text-align: left;
  padding: var(--sp-3) var(--sp-4);
}
.shopcard--wide .shopcard__icon { width: 48px; height: 48px; grid-row: span 2; }
.shopcard--wide .shopcard__name { align-self: end; }
.shopcard--wide .shopcard__blurb { min-height: 0; align-self: start; grid-column: 2; }
.shopcard--wide .btn { grid-column: 3; grid-row: 1 / span 2; margin-top: 0; }

/* First-run hint: sits over the board, gets out of the way on the first match. */
.game__boardwrap { position: relative; }
.game__hint {
  position: absolute;
  left: var(--sp-3);
  right: var(--sp-3);
  bottom: var(--sp-2);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  background: rgba(34, 64, 14, .92);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .2);
  text-align: center;
  pointer-events: none;
  animation: hint-in var(--t-slow) var(--ease-pop) both 400ms;
}
.game__hint[data-gone='1'] { animation: hint-out var(--t-mid) var(--ease-in) both; }
.game__hintline { font-family: var(--font-display); font-size: var(--step-0); color: var(--cream); }
.game__hintsub { font-size: var(--step--1); font-weight: 700; color: rgba(255, 249, 236, .75); }
@keyframes hint-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes hint-out { to { opacity: 0; transform: translateY(10px); } }

/* The cheat panel is deliberately marked out as not-part-of-the-game. */
.settings__cheats {
  box-shadow: 0 6px 0 rgba(110, 68, 31, .5), 0 14px 34px rgba(0, 0, 0, .35),
              inset 0 2px 0 rgba(255, 255, 255, .7), 0 0 0 3px var(--grape);
}
.settings__cheats .settings__heading { color: var(--grape); }

/* ============================================================
   Win banner — "TARGET HIT!" then "BRINE RUSH"
   Sits in the gap above the board; on short screens it overlaps the top of the
   grid, which is fine — it's a brief, celebratory moment, not persistent chrome.
   ============================================================ */
.winbanner {
  position: absolute;
  left: 50%;
  top: 6%;
  transform: translate(-50%, -20px);
  z-index: 5;
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: clamp(8px, 2.6cqw, 14px) clamp(18px, 6cqw, 34px);
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, var(--dill-lit), var(--dill) 55%, var(--dill-deep));
  box-shadow:
    0 6px 0 var(--dill-deep),
    0 14px 30px rgba(0, 0, 0, .5),
    inset 0 2px 0 rgba(255, 255, 255, .45),
    0 0 0 3px var(--brine);
  pointer-events: none;
  text-align: center;
  white-space: nowrap;
}
.winbanner[data-show='hit'], .winbanner[data-show='rush'] { display: flex; }
.winbanner[data-show='rush'] {
  background: linear-gradient(180deg, #FFD877, var(--amber) 55%, var(--amber-deep));
  box-shadow:
    0 6px 0 var(--amber-deep),
    0 14px 34px rgba(120, 70, 0, .5),
    inset 0 2px 0 rgba(255, 255, 255, .5),
    0 0 0 3px var(--brine),
    0 0 26px rgba(255, 182, 39, .8);
}
.winbanner__title {
  font-family: var(--font-display);
  font-size: clamp(20px, 6.6cqw, 34px);
  line-height: 1;
  color: var(--cream);
  text-shadow: 0 3px 0 rgba(34, 64, 14, .8), 0 5px 12px rgba(0, 0, 0, .5);
  letter-spacing: .02em;
}
.winbanner[data-show='rush'] .winbanner__title {
  color: #5B3200;
  text-shadow: 0 2px 0 rgba(255, 255, 255, .4), 0 4px 10px rgba(120, 70, 0, .4);
}
.winbanner__sub {
  font-family: var(--font-ui);
  font-weight: 900;
  font-size: clamp(11px, 3.2cqw, 15px);
  color: var(--cream);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
}
.winbanner[data-show='rush'] .winbanner__sub { color: #6E441F; text-shadow: 0 1px 0 rgba(255, 255, 255, .35); }

/* The stamp: slams in oversized and settles, like a rubber stamp hitting paper. */
.winbanner--stamp { animation: banner-stamp 520ms var(--ease-pop) both; }
@keyframes banner-stamp {
  0% { transform: translate(-50%, -20px) scale(2.4) rotate(-8deg); opacity: 0; }
  55% { transform: translate(-50%, -20px) scale(.86) rotate(2deg); opacity: 1; }
  100% { transform: translate(-50%, -20px) scale(1) rotate(-1.5deg); opacity: 1; }
}
/* A quick throb per rush blast. */
.winbanner--pulse { animation: banner-pulse 180ms var(--ease-out) both; }
@keyframes banner-pulse {
  0% { transform: translate(-50%, -20px) scale(1); }
  40% { transform: translate(-50%, -20px) scale(1.08); }
  100% { transform: translate(-50%, -20px) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .winbanner--stamp, .winbanner--pulse { animation: none; opacity: 1; }
}
