/* ============================================================
   GETAWAY! v6 — HUD / dashboard / garage / results
   Theme: chunky kid-friendly. Gold #ffd42a, hot red #d92b0f,
   cop blue #4d7bff, deep purple night #14102b.
   No external fonts, no external assets.
   ============================================================ */

:root {
  --gold: #ffd42a;
  --hot: #ff5a3c;
  --hot-deep: #d92b0f;
  --cop: #4d7bff;
  --danger-red: #ff3b3b;
  --ink: #0a081e;
  --paper: #ffffff;
  --muted: #cfc9ff;
  --dim: #8f88c2;
  --panel: rgba(12, 9, 34, 0.62);
  --panel-hi: rgba(255, 255, 255, 0.09);
  /* the whole dashboard scales off this one number */
  --dash-w: clamp(112px, 21vh, 186px);
}

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  width: 100%; height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  /* NOT `none` — a `none` here is inherited into the touch-action intersection
     of every descendant and would stop the garage rail from scrolling on iPad.
     Gameplay surfaces below opt into `none` explicitly instead. */
  touch-action: manipulation;
  background: #14102b;
  font-family: -apple-system, "Segoe UI", system-ui, sans-serif;
  user-select: none; -webkit-user-select: none;
}

/* the canvas is the real target for every gameplay touch (the HUD is
   pointer-events:none), so this is where scroll/zoom must be killed */
#game, #game canvas {
  position: fixed; inset: 0; width: 100%; height: 100%; display: block;
  touch-action: none;
}

.hidden { display: none !important; }

/* ============================================================
   OVERLAYS (garage + results)
   ============================================================ */
.overlay {
  position: fixed; inset: 0; z-index: 20;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  gap: 14px; text-align: center;
  background: rgba(10, 8, 30, 0.86);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  padding:
    calc(10px + env(safe-area-inset-top))
    calc(12px + env(safe-area-inset-right))
    calc(10px + env(safe-area-inset-bottom))
    calc(12px + env(safe-area-inset-left));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* `manipulation`, not `pan-y`: a pan-y ancestor would intersect the rail's
     pan-x to nothing and the car rail would refuse to scroll sideways */
  touch-action: manipulation;
}

/* Vertical centring that does NOT clip the top when the content overflows
   (justify-content:center + overflow makes the first item unreachable). */
.overlay::before, .overlay::after { content: ''; flex: 1 0 auto; min-height: 0; }

.overlay h1 {
  font-size: clamp(34px, 7.6vh, 84px);
  font-weight: 900; letter-spacing: 2px;
  color: var(--gold);
  text-shadow: 0 4px 0 #c2320a, 0 8px 24px rgba(0, 0, 0, .6);
  transform: rotate(-2deg);
  line-height: 1.05;
}

.tag { color: var(--muted); font-size: clamp(11px, 1.9vh, 16px); line-height: 1.45; font-weight: 700; }
.keys { color: var(--dim); font-size: clamp(9px, 1.5vh, 14px); font-weight: 700; }

.big-btn {
  font-family: inherit;
  font-size: clamp(17px, 3.2vh, 26px); font-weight: 900; letter-spacing: 1px;
  padding: clamp(10px, 1.9vh, 18px) clamp(22px, 5vw, 44px);
  border: none; border-radius: 18px;
  background: linear-gradient(var(--hot), var(--hot-deep));
  color: #fff; cursor: pointer;
  box-shadow: 0 6px 0 #8f1a05, 0 12px 24px rgba(0, 0, 0, .5);
}
.big-btn:active { transform: translateY(4px); box-shadow: 0 2px 0 #8f1a05; }
.big-btn--alt {
  background: linear-gradient(#6a8ae8, #22348f);
  box-shadow: 0 6px 0 #101a4a, 0 12px 24px rgba(0, 0, 0, .5);
}

/* "BUY THUNDER — 600" : the unmissable purchase button. Deliberately in normal
   flow (not inside the scrolling card rail) so no stacking context can hide it. */
.big-btn--buy {
  position: relative; z-index: 5;
  color: #08240a;
  background: linear-gradient(#7cf05a, #2f9d3a);
  box-shadow: 0 6px 0 #175c1f, 0 12px 24px rgba(0, 0, 0, .5);
  animation: buy-pulse 1.15s ease-in-out infinite alternate;
}
.big-btn--buy:active { box-shadow: 0 2px 0 #175c1f; }
@keyframes buy-pulse {
  from { box-shadow: 0 6px 0 #175c1f, 0 0 0 rgba(110, 232, 90, 0); }
  to   { box-shadow: 0 6px 0 #175c1f, 0 0 26px rgba(110, 232, 90, .9); }
}
.big-btn--alt:active { box-shadow: 0 2px 0 #101a4a; }

/* ============================================================
   GARAGE  (#menu)
   ============================================================ */
.garage { gap: clamp(6px, 1.4vh, 14px); }

.garage-bar {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(10px, 3vw, 26px); flex-wrap: wrap;
}
#garage-coins {
  font-size: clamp(16px, 2.8vh, 26px); font-weight: 900; color: var(--gold);
  background: var(--panel); border: 2px solid rgba(255, 212, 42, .35);
  border-radius: 14px; padding: 5px 14px;
  text-shadow: 0 2px 4px rgba(0, 0, 0, .7);
}

/* ---- car card rail (horizontally scrollable) ---- */
#cars {
  display: flex; gap: 10px;
  overflow-x: auto; overflow-y: hidden;
  touch-action: manipulation;
  /* NO -webkit-overflow-scrolling:touch. On iOS it creates a stacking context
     on this scroller, and #swatches (a LATER sibling) then paints on top of the
     rail — which buried the BUY button under the colour circles on the iPad
     while looking perfectly fine in desktop Chrome. Momentum scrolling is the
     default on modern iOS anyway, so the property bought nothing. */
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  max-width: min(97vw, 1000px);
  width: 100%;
  padding: 6px 8px 10px;
  /* explicit paint order beats DOM order — the rail must win */
  position: relative;
  z-index: 3;
}
/* auto-margin spacers centre the rail when it fits and collapse to 0 when it
   overflows — `justify-content:center` would clip the first card instead */
#cars::before, #cars::after { content: ''; flex: 1 0 auto; min-width: 0; }
#cars::-webkit-scrollbar { display: none; }

.car-card {
  position: relative;
  flex: 0 0 auto;
  scroll-snap-align: center;
  width: clamp(122px, 21vh, 168px);
  border: 3px solid rgba(255, 255, 255, .18); border-radius: 16px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, .03));
  color: #fff; cursor: pointer;
  padding: 9px 9px 10px; text-align: center;
  font-family: inherit;
  transition: transform .12s, border-color .12s, box-shadow .12s;
}
.car-card.sel {
  border-color: var(--gold);
  background: linear-gradient(180deg, rgba(255, 212, 42, .22), rgba(255, 212, 42, .06));
  transform: scale(1.05);
  box-shadow: 0 0 20px rgba(255, 212, 42, .45);
}
.car-card.locked { opacity: .45; filter: grayscale(.6); }
.car-card.locked.afford { opacity: .85; filter: none; border-color: rgba(79, 212, 42, .6); }

.cc-lock {
  position: absolute; top: 6px; right: 8px;
  font-size: clamp(14px, 2vh, 18px);
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .8));
}
.cc-name {
  display: block; font-size: clamp(14px, 2.2vh, 19px);
  font-weight: 900; letter-spacing: 1px; font-style: normal;
}
.cc-blurb {
  display: block; font-style: normal;
  font-size: clamp(8px, 1.35vh, 11px); color: var(--muted);
  margin-top: 2px; min-height: 2.3em; line-height: 1.15;
}
.cc-stats { margin: 6px 0 4px; display: flex; flex-direction: column; gap: 3px; }
.cc-stat { display: flex; align-items: center; gap: 5px; }
.cc-lab {
  flex: 0 0 auto; width: 3.6em; text-align: left;
  font-size: clamp(7px, 1.15vh, 9px); font-weight: 900; color: var(--dim); letter-spacing: .5px;
}
.cc-bar {
  flex: 1 1 auto; height: 6px; border-radius: 4px;
  background: rgba(0, 0, 0, .55); overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .12);
}
.cc-fill { height: 100%; border-radius: 3px; }
.cc-fill.s-speed { background: linear-gradient(90deg, #ff9d00, var(--gold)); }
.cc-fill.s-grip  { background: linear-gradient(90deg, #2b6bff, #6ab6ff); }
.cc-fill.s-tough { background: linear-gradient(90deg, #2f9d3a, #6ee85a); }

.cc-price {
  margin-top: 4px;
  font-size: clamp(9px, 1.5vh, 12px); font-weight: 900; color: var(--gold);
  letter-spacing: .5px;
}
.car-card.locked .cc-price { color: #ffb0a0; }
.cc-buy {
  font-family: inherit; display: block; width: 100%;
  margin-top: 6px; padding: 9px 4px;
  min-height: 38px;                 /* thumb-sized target for a 7-year-old */
  position: relative; z-index: 4;   /* above its own card's decoration */
  border: none; border-radius: 10px; cursor: pointer;
  font-size: clamp(11px, 1.7vh, 14px); font-weight: 900; letter-spacing: .5px;
  color: #08240a;
  background: linear-gradient(#7cf05a, #2f9d3a);
  box-shadow: 0 3px 0 #175c1f;
  animation: buy-glow 1.1s ease-in-out infinite alternate;
}
.cc-buy:active { transform: translateY(2px); box-shadow: 0 1px 0 #175c1f; }
@keyframes buy-glow {
  from { box-shadow: 0 3px 0 #175c1f, 0 0 0 rgba(110, 232, 90, 0); }
  to   { box-shadow: 0 3px 0 #175c1f, 0 0 16px rgba(110, 232, 90, .8); }
}

/* ---- colour swatches ---- */
#swatches {
  display: flex; gap: clamp(6px, 1.6vw, 12px); flex-wrap: wrap; justify-content: center;
  max-width: 440px;
  position: relative; z-index: 1;   /* must never paint over the card rail */
  margin-top: 4px;                  /* clear air under the BUY buttons */
}
.swatch {
  width: clamp(26px, 4.6vh, 44px); height: clamp(26px, 4.6vh, 44px);
  border-radius: 50%;
  border: 4px solid rgba(255, 255, 255, .25); cursor: pointer;
  transition: transform .1s;
}
.swatch.sel { border-color: var(--gold); transform: scale(1.22); box-shadow: 0 0 16px rgba(255, 212, 42, .7); }

/* ---- lifetime stats ---- */
#stats-panel {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 5px clamp(8px, 2vw, 18px);
  background: var(--panel); border: 2px solid var(--panel-hi);
  border-radius: 14px; padding: 8px clamp(10px, 2.5vw, 20px);
  max-width: min(94vw, 560px);
}
.stat-cell { text-align: center; }
.stat-lab { font-size: clamp(7px, 1.2vh, 10px); font-weight: 900; color: var(--dim); letter-spacing: .5px; }
.stat-val { font-size: clamp(12px, 2vh, 17px); font-weight: 900; color: #fff; }

/* ============================================================
   MOD SHOP (inside garage — toggled by hud.js)
   ============================================================ */
.mod-toggle {
  font-family: inherit;
  font-size: clamp(14px, 2.4vh, 20px); font-weight: 900;
  padding: clamp(8px, 1.5vh, 14px) clamp(16px, 3vw, 28px);
  min-height: 56px;
  border: none; border-radius: 14px;
  background: linear-gradient(#6a8ae8, #22348f);
  color: #fff; cursor: pointer;
  box-shadow: 0 5px 0 #101a4a, 0 10px 20px rgba(0, 0, 0, .4);
  letter-spacing: 1px;
}
.mod-toggle:active { transform: translateY(3px); box-shadow: 0 2px 0 #101a4a; }

.mod-view {
  width: 100%; max-width: min(97vw, 560px);
  display: flex; flex-direction: column;
  gap: clamp(6px, 1.2vh, 10px);
}
.mod-header {
  display: flex; align-items: center; gap: clamp(8px, 2vw, 14px);
}
.mod-back {
  font-family: inherit;
  font-size: clamp(13px, 2.2vh, 18px); font-weight: 900;
  min-height: 56px; min-width: 56px;
  padding: 8px 14px;
  border: 2px solid rgba(255, 255, 255, .18); border-radius: 12px;
  background: var(--panel); color: #fff; cursor: pointer;
}
.mod-back:active { transform: scale(.95); }
.mod-car-name {
  font-size: clamp(16px, 2.8vh, 24px); font-weight: 900;
  color: var(--gold); letter-spacing: 1px;
}

.mod-slots {
  display: flex; flex-direction: column;
  gap: clamp(5px, 1vh, 8px);
  overflow-y: auto;
  max-height: min(54vh, 420px);
  padding: 4px;
  touch-action: manipulation;
  scrollbar-width: thin;
}
.mod-slot {
  background: var(--panel);
  border: 2px solid var(--panel-hi);
  border-radius: 12px;
  padding: clamp(6px, 1vh, 10px) clamp(8px, 1.5vw, 12px);
}
.mod-slot-head {
  display: flex; align-items: center; gap: 6px;
  margin-bottom: clamp(4px, .8vh, 6px);
}
.mod-slot-icon { font-size: clamp(14px, 2.2vh, 20px); }
.mod-slot-name {
  font-size: clamp(10px, 1.6vh, 14px); font-weight: 900;
  color: var(--muted); letter-spacing: 1px;
}

.mod-tiers {
  display: flex; gap: clamp(4px, 1vw, 8px);
  overflow-x: auto;
  touch-action: manipulation;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.mod-tiers::-webkit-scrollbar { display: none; }

.mod-tier {
  flex: 0 0 auto;
  min-width: clamp(68px, 13vw, 96px);
  min-height: 56px;
  border: 2px solid rgba(255, 255, 255, .12);
  border-radius: 10px;
  padding: clamp(4px, .8vh, 8px) clamp(6px, 1vw, 10px);
  text-align: center; cursor: pointer;
  background: rgba(255, 255, 255, .04);
  transition: transform .1s, border-color .12s;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
}
.mod-tier:active { transform: scale(.94); }
.mod-tier.equipped {
  border-color: var(--gold);
  background: rgba(255, 212, 42, .15);
  box-shadow: 0 0 14px rgba(255, 212, 42, .45);
}
.mod-tier.owned {
  border-color: rgba(110, 232, 90, .5);
  background: rgba(110, 232, 90, .08);
}
.mod-tier.affordable { border-color: rgba(79, 212, 42, .4); }
.mod-tier.locked { opacity: .45; }

.mod-tier-icon { font-size: clamp(16px, 2.6vh, 24px); line-height: 1.1; }
.mod-tier-name {
  font-size: clamp(8px, 1.3vh, 11px); font-weight: 900;
  color: #fff; letter-spacing: .5px; line-height: 1.15;
}
.mod-tier-price {
  font-size: clamp(8px, 1.2vh, 10px); font-weight: 900;
  color: var(--gold); line-height: 1.2;
}
.mod-tier.owned .mod-tier-price { color: #6ee85a; }
.mod-tier.equipped .mod-tier-price { color: var(--gold); }
.mod-tier.locked .mod-tier-price { color: #ffb0a0; }
.mod-tier-effect {
  font-size: clamp(7px, 1.1vh, 9px); font-weight: 900;
  color: var(--muted); letter-spacing: .5px;
}

.mod-shake { animation: mod-deny .4s ease-out; }
@keyframes mod-deny {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
.mod-bought { animation: mod-celebrate .45s ease-out; }
@keyframes mod-celebrate {
  0% { transform: scale(1); }
  35% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* ============================================================
   RESULTS  (#busted)
   ============================================================ */
.results { gap: clamp(5px, 1.2vh, 12px); }

.busted-title {
  color: var(--danger-red) !important;
  text-shadow: 0 4px 0 #1e2b8f, 0 8px 24px rgba(0, 0, 0, .6) !important;
  animation: busted-flash .5s steps(2) infinite;
}
@keyframes busted-flash { 0% { color: #ff3b3b; } 50% { color: #4d7bff; } }

.busted-score { font-size: clamp(28px, 5.6vh, 48px); font-weight: 900; color: #fff; line-height: 1; }
.busted-best { font-size: clamp(12px, 2.1vh, 19px); font-weight: 800; color: var(--gold); }
.busted-best.newbest { animation: newbest-pop 1s ease-out infinite alternate; }
@keyframes newbest-pop { from { transform: scale(1); } to { transform: scale(1.12); } }

#res-lines {
  display: flex; flex-direction: column; gap: 3px;
  width: min(90vw, 400px);
  background: var(--panel); border: 2px solid var(--panel-hi);
  border-radius: 14px; padding: 8px 12px;
}
.res-line {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  font-size: clamp(11px, 1.9vh, 16px); font-weight: 800;
  transition: opacity .18s;
}
.res-line.pending { opacity: .22; }
.rl-label { color: var(--muted); letter-spacing: .5px; }
.rl-val { color: var(--gold); font-weight: 900; font-variant-numeric: tabular-nums; }

#res-total {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  width: min(90vw, 400px); padding: 0 14px;
  font-size: clamp(14px, 2.5vh, 22px); font-weight: 900;
}
.rt-label { color: #fff; letter-spacing: 1px; }
#res-total-val { color: var(--gold); font-variant-numeric: tabular-nums; }
#res-total.done #res-total-val { animation: total-pop .35s ease-out; }
@keyframes total-pop { 0% { transform: scale(1); } 45% { transform: scale(1.28); } 100% { transform: scale(1); } }

#res-unlock {
  font-size: clamp(13px, 2.3vh, 21px); font-weight: 900; color: #08240a;
  background: linear-gradient(#ffe375, #ffb01a);
  border-radius: 14px; padding: 7px 16px;
  box-shadow: 0 4px 0 #a86a00, 0 0 26px rgba(255, 212, 42, .55);
  transform: rotate(-2deg);
}
#res-unlock.go { animation: unlock-in .7s cubic-bezier(.2, 1.6, .4, 1) both; }
@keyframes unlock-in {
  0% { opacity: 0; transform: rotate(-2deg) scale(.3); }
  100% { opacity: 1; transform: rotate(-2deg) scale(1); }
}

.res-btns { display: flex; gap: clamp(8px, 2vw, 18px); flex-wrap: wrap; justify-content: center; }

/* ============================================================
   HUD
   ============================================================ */
#hud { position: fixed; inset: 0; z-index: 10; pointer-events: none; touch-action: none; }

/* ---- top-left ---- */
#hud-tl {
  position: absolute;
  top: calc(8px + env(safe-area-inset-top));
  left: calc(10px + env(safe-area-inset-left));
  max-width: min(30vw, 240px);
  color: #fff; text-shadow: 0 2px 6px rgba(0, 0, 0, .85);
  text-align: left;
}
#score { font-size: clamp(22px, 4.6vh, 38px); font-weight: 900; line-height: 1; }
#best { font-size: clamp(9px, 1.5vh, 13px); font-weight: 800; color: var(--gold); }
#hearts { font-size: clamp(12px, 2vh, 18px); margin-top: 2px; letter-spacing: 1px; }
#hearts.hurt { animation: heart-thump .5s ease-in-out infinite; }
@keyframes heart-thump { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.18); } }

/* ---- missions ---- */
#missions { margin-top: 5px; display: flex; flex-direction: column; gap: 4px; }
.mission {
  background: var(--panel); border: 1px solid var(--panel-hi);
  border-radius: 8px; padding: 3px 6px 4px;
}
.mission.done { border-color: rgba(110, 232, 90, .7); }
.m-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  font-size: clamp(7px, 1.25vh, 11px); font-weight: 900; letter-spacing: .4px;
}
.m-text { color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.m-count { color: var(--gold); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.m-bar {
  margin-top: 2px; height: 4px; border-radius: 3px;
  background: rgba(0, 0, 0, .55); overflow: hidden;
}
.m-fill { height: 100%; width: 0%; border-radius: 3px; background: linear-gradient(90deg, #ff9d00, var(--gold)); }
.mission.done .m-fill { background: linear-gradient(90deg, #2f9d3a, #6ee85a); }

/* ---- top-centre: stars / cop gap / district ---- */
#hud-tc {
  position: absolute;
  top: calc(5px + env(safe-area-inset-top));
  left: 50%; transform: translateX(-50%);
  width: min(48vw, 320px); text-align: center;
}
#stars-box { font-size: clamp(17px, 3.2vh, 30px); line-height: 1; letter-spacing: 2px; }
.star {
  display: inline-block;
  color: var(--gold);
  text-shadow: 0 0 10px rgba(255, 180, 20, .9), 0 2px 3px #000;
}
.star.off { color: rgba(255, 255, 255, .18); text-shadow: 0 2px 3px rgba(0, 0, 0, .8); }
.star.pop { animation: star-pop .45s cubic-bezier(.2, 1.7, .4, 1); }
@keyframes star-pop {
  0% { transform: scale(2.2) rotate(-25deg); }
  100% { transform: scale(1) rotate(0deg); }
}

#heat-box { margin-top: 3px; }
.heat-label { font-size: clamp(8px, 1.4vh, 12px); font-weight: 900; color: #fff; text-shadow: 0 2px 4px #000; }
#heat-bar {
  margin-top: 2px; height: clamp(8px, 1.5vh, 13px); border-radius: 8px;
  background: rgba(0, 0, 0, .55); border: 2px solid rgba(255, 255, 255, .3); overflow: hidden;
}
#heat-fill {
  height: 100%; width: 50%; border-radius: 6px;
  background: linear-gradient(90deg, var(--danger-red), var(--cop));
  transition: width .15s linear;
}

#district {
  margin-top: 6px; opacity: 0;
  font-size: clamp(12px, 2.4vh, 22px); font-weight: 900; letter-spacing: 3px;
  color: #fff; text-shadow: 0 2px 0 var(--hot-deep), 0 4px 16px rgba(0, 0, 0, .9);
}
#district.go { animation: district-in 3.2s ease-out; }
@keyframes district-in {
  0% { opacity: 0; transform: translateY(-8px) scale(.9); }
  14% { opacity: 1; transform: translateY(0) scale(1); }
  72% { opacity: 1; }
  100% { opacity: 0; }
}

/* ---- top-right: coins ---- */
#coins-box {
  position: absolute;
  top: calc(8px + env(safe-area-inset-top));
  right: calc(10px + env(safe-area-inset-right));
  text-align: right;
}
#coins {
  font-size: clamp(15px, 2.9vh, 27px); font-weight: 900; color: var(--gold);
  text-shadow: 0 2px 6px rgba(0, 0, 0, .9);
  font-variant-numeric: tabular-nums;
}
#coin-pops { position: absolute; top: 100%; right: 2px; width: 0; height: 0; }
.coin-pop {
  position: absolute; top: 0; right: 0; opacity: 0;
  white-space: nowrap;
  font-size: clamp(12px, 2.1vh, 19px); font-weight: 900; color: #6ee85a;
  text-shadow: 0 2px 4px #000;
}
.coin-pop.neg { color: #ff6a5a; }
.coin-pop.go { animation: coin-drift .95s ease-out forwards; }
@keyframes coin-drift {
  0% { opacity: 0; transform: translateY(4px) scale(.7); }
  18% { opacity: 1; transform: translateY(0) scale(1.15); }
  35% { transform: translateY(-6px) scale(1); }
  100% { opacity: 0; transform: translateY(-42px) scale(1); }
}

/* ---- minimap (canvas created + appended to #hud by minimap.js) ---- */
#minimap-canvas {
  position: absolute;
  top: calc(52px + env(safe-area-inset-top));
  right: calc(10px + env(safe-area-inset-right));
  width: clamp(100px, 18vw, 140px);
  height: clamp(100px, 18vw, 140px);
  border-radius: 12px;
  background: rgba(12, 9, 34, 0.72);
  border: 2px solid rgba(255, 255, 255, 0.15);
  pointer-events: none;
}

/* ---- mission toasts ---- */
#toast-layer {
  position: absolute; top: 24%; left: 50%; transform: translateX(-50%);
  width: min(84vw, 460px); text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.toast {
  opacity: 0;
  font-size: clamp(13px, 2.4vh, 22px); font-weight: 900; letter-spacing: .5px;
  color: #08240a;
  background: linear-gradient(#ffe375, #ffb01a);
  border-radius: 14px; padding: 6px 16px;
  box-shadow: 0 4px 0 #a86a00, 0 6px 22px rgba(0, 0, 0, .6);
}
.toast.go { animation: toast-in 2.4s cubic-bezier(.2, 1.5, .4, 1) forwards; }
@keyframes toast-in {
  0% { opacity: 0; transform: scale(.4) rotate(-6deg); }
  12% { opacity: 1; transform: scale(1.08) rotate(2deg); }
  22% { transform: scale(1) rotate(0deg); }
  78% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(.95) translateY(-16px); }
}

/* ============================================================
   DASHBOARD — bottom RIGHT corner, never under a thumb
   Bottom-centre sat the dial directly on top of the car, which is dead
   centre of frame. It stacks above the BOOST/DRIFT buttons instead
   (those are 92px tall at bottom:18, so anything above 110px is clear).
   ============================================================ */
#dash {
  position: absolute;
  left: auto; transform: none;
  right: calc(10px + env(safe-area-inset-right));
  bottom: calc(118px + env(safe-area-inset-bottom));
  width: var(--dash-w);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
}

#dash-face {
  position: relative; width: 100%;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 48%, rgba(30, 22, 62, .88) 58%, rgba(12, 9, 34, .55) 74%, rgba(12, 9, 34, 0) 82%);
}

#tacho {
  display: block; width: 100%; height: auto;
  aspect-ratio: 200 / 190;
  overflow: visible;
}

.tk-track { fill: none; stroke: rgba(255, 255, 255, .13); stroke-width: 7; stroke-linecap: round; }
.tk-red   { fill: none; stroke: var(--danger-red); stroke-width: 7; stroke-linecap: round; opacity: .85; }
.tk-maj   { stroke: #e8e4ff; stroke-width: 2.6; stroke-linecap: round; }
.tk-min   { stroke: rgba(207, 201, 255, .42); stroke-width: 1.6; stroke-linecap: round; }
.tk-num   { fill: #e8e4ff; font-size: 15px; font-weight: 900; text-anchor: middle;
            font-family: -apple-system, "Segoe UI", system-ui, sans-serif; }
.tk-num-red { fill: #ff8a7a; }

#tacho-needle {
  fill: var(--gold);
  stroke: #40200a; stroke-width: .8; stroke-linejoin: round;
  /* the pivot (100,95) is the exact centre of the "0 0 200 190" viewBox,
     so 50% 50% resolves to it — belt and braces with transform-box */
  transform-box: view-box;
  transform-origin: 50% 50%;
  transition: transform 60ms linear;
}
#tacho-hub { fill: #241a44; stroke: rgba(255, 255, 255, .35); stroke-width: 1.5; }
#tacho-hub-in { fill: var(--gold); }

#dash.redline #tacho-needle { fill: #ff5030; }
#dash.redline .tk-red { opacity: 1; }
#dash.redline #gear { color: #ff7a52; }
#dash.drifting #dash-face { box-shadow: 0 0 22px rgba(109, 138, 232, .55); }

#gear {
  position: absolute; left: 0; right: 0; top: 36%;
  text-align: center; pointer-events: none;
  font-size: calc(var(--dash-w) * .255); line-height: 1;
  font-weight: 900; color: #fff;
  text-shadow: 0 2px 0 #000, 0 0 14px rgba(0, 0, 0, .95);
}
#gear.shift { animation: gear-shift .28s ease-out; }
@keyframes gear-shift {
  0% { transform: scale(1.55); color: var(--gold); text-shadow: 0 0 22px var(--gold); }
  100% { transform: scale(1); }
}

#speed {
  position: absolute; left: 0; right: 0; top: 71%;
  display: flex; align-items: baseline; justify-content: center; gap: 2px;
  pointer-events: none;
}
#speed-num {
  font-size: calc(var(--dash-w) * .20); line-height: 1;
  font-weight: 900; color: #fff;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 0 #000, 0 0 12px rgba(0, 0, 0, .95);
}
#speed-unit {
  font-size: calc(var(--dash-w) * .075); font-weight: 800; color: var(--muted);
  text-shadow: 0 1px 3px #000;
}

#air-badge {
  /* floats clear ABOVE the dial so it never sits on the arc */
  position: absolute; left: 0; right: 0; top: -13%;
  text-align: center; opacity: 0;
  font-size: calc(var(--dash-w) * .085); font-weight: 900; letter-spacing: 1px;
  color: #fff; text-shadow: 0 2px 0 var(--hot-deep), 0 0 12px rgba(0, 0, 0, .9);
  transition: opacity .12s;
}
#air-badge.on { opacity: 1; }

#dash-strip { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 3px; }
#boost-bar {
  width: 94%; height: clamp(7px, 1.3vh, 12px); border-radius: 8px;
  background: rgba(0, 0, 0, .55); border: 2px solid rgba(255, 255, 255, .3); overflow: hidden;
}
#boost-fill { height: 100%; width: 100%; background: linear-gradient(90deg, #ff9d00, var(--gold)); border-radius: 6px; }

#wheels-box { font-size: clamp(11px, 1.9vh, 17px); letter-spacing: 2px; text-shadow: 0 2px 6px rgba(0, 0, 0, .85); line-height: 1; }
.wheel-dot.gone { opacity: .18; filter: grayscale(1); }

/* ============================================================
   TOUCH CONTROLS (unchanged geometry — the kid knows where they are)
   ============================================================ */
.ctl-btn {
  position: absolute; bottom: calc(18px + env(safe-area-inset-bottom));
  width: 92px; height: 92px; border-radius: 50%;
  border: none; pointer-events: auto; cursor: pointer; touch-action: none;
  font-size: 34px; font-weight: 900; color: #fff;
  font-family: inherit;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-shadow: 0 2px 4px rgba(0, 0, 0, .6);
  z-index: 2;
}
.ctl-btn span { font-size: 13px; letter-spacing: 1px; }
#btn-boost {
  right: calc(18px + env(safe-area-inset-right));
  background: radial-gradient(circle at 35% 30%, #ff7a52, var(--hot-deep) 70%);
  box-shadow: 0 5px 0 #8f1a05, 0 10px 20px rgba(0, 0, 0, .5);
}
#btn-pop {
  left: calc(18px + env(safe-area-inset-left));
  background: radial-gradient(circle at 35% 30%, #6a6a7a, #23232e 70%);
  box-shadow: 0 5px 0 #0c0c12, 0 10px 20px rgba(0, 0, 0, .5);
}
.ctl-btn:active, .ctl-btn.pressed { transform: translateY(4px); }

#btn-drift {
  right: calc(122px + env(safe-area-inset-right));
  bottom: calc(18px + env(safe-area-inset-bottom));
  width: 72px; height: 72px; font-size: 26px;
  background: radial-gradient(circle at 35% 30%, #6a8ae8, #22348f 70%);
  box-shadow: 0 5px 0 #101a4a, 0 10px 20px rgba(0, 0, 0, .5);
}
#btn-drift span { font-size: 11px; }

/* ============================================================
   WANTED FLASH + DANGER STROBE
   ============================================================ */
#wanted-flash {
  position: fixed; inset: 0; z-index: 30;
  display: flex; align-items: center; justify-content: center;
  font-size: clamp(38px, 9vw, 80px); font-weight: 900;
  color: var(--danger-red); text-shadow: 0 0 30px #ff0000, 0 4px 0 #1e0808;
  background: rgba(180, 0, 0, 0.15);
  pointer-events: none;
  animation: wanted-pop 1.2s ease-out forwards;
}
#wanted-flash.hidden { display: none !important; }
@keyframes wanted-pop {
  0% { opacity: 0; transform: scale(0.5); }
  15% { opacity: 1; transform: scale(1.15); }
  40% { opacity: 1; transform: scale(1.0); }
  100% { opacity: 0; transform: scale(1.0); }
}

#hud::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  opacity: var(--danger, 0);
  background:
    linear-gradient(90deg, rgba(255, 40, 40, .35), transparent 30%, transparent 70%, rgba(60, 90, 255, .35));
  animation: danger-strobe .4s steps(2) infinite;
}
@keyframes danger-strobe { 0% { filter: hue-rotate(0deg); } 50% { filter: hue-rotate(180deg); } }

/* ============================================================
   SHORT-LANDSCAPE TRIM (phones held sideways, e.g. 844x390)
   ============================================================ */
@media (max-height: 460px) and (orientation: landscape) {
  .overlay { gap: 6px; }
  .cc-blurb { display: none; }
  #stats-panel { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  #toast-layer { top: 18%; }
  .mod-slots { max-height: min(36vh, 280px); }
  .mod-tier-effect { display: none; }
}

/* Narrow viewports (phone portrait): three top clusters do not fit across
   the width, so the mission tracker steps aside and the centre column
   narrows. Distance / stars / coins all stay. */
@media (max-width: 540px) {
  #missions { display: none; }
  #hud-tc { width: min(52vw, 200px); }
  #stats-panel { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mod-tier { min-width: clamp(60px, 18vw, 88px); }
  #minimap-canvas { width: clamp(80px, 22vw, 110px); height: clamp(80px, 22vw, 110px); }
}

/* Very short viewports: the dashboard yields before the controls do. */
@media (max-height: 360px) {
  :root { --dash-w: 104px; }
  #dash-strip { display: none; }
  #minimap-canvas { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .busted-title, .cc-buy, #hud::after, .busted-best.newbest { animation: none; }
}

/* ===========================================================================
   MENU LAYOUT — "the buttons to choose the cars disappear on the smaller
   screens, it gets covered by other divs" (BK, 2026-08-30)

   NOT a stacking bug. Measured on this live build at 375x812: #cars wanted
   141px of content and rendered 127px, clipping the cards. v3 had the same
   defect far worse (16px of a wanted 144) because it carries two extra option
   rows pushing on the column.

   MECHANISM. .overlay is a flex column. When its children total more than the
   viewport, flexbox shrinks them rather than overflowing. `min-height:auto`
   normally stops a flex item shrinking below its own content — but only for
   items whose overflow is `visible`. #cars sets `overflow-y: hidden` to keep
   the rail on one line, which makes its automatic minimum size ZERO. So the
   car rail was the one child flexbox was free to crush, and it absorbed the
   whole overflow. And because the children shrank to fit, the column never
   overflowed, so .overlay's own `overflow-y: auto` had nothing to scroll.

   FIX: nothing in the menu may shrink. The column overflows honestly, the
   overlay scrolls, every control keeps its real size. Do NOT let something
   shrink again to make the menu fit — that is the bug. Fold a section instead.
   =========================================================================== */
.overlay > * { flex-shrink: 0; }
#cars { flex: 0 0 auto; min-height: 148px; }

/* Career stats folded away: 134px of a phone's 812 that nobody needs open
   while choosing a car. #stats-panel keeps its id, so hud.js is unaffected. */
.fold { width: 100%; max-width: min(94vw, 560px); }
.fold-sum {
  cursor: pointer; list-style: none;
  font-size: clamp(10px, 1.5vh, 13px); font-weight: 900; letter-spacing: 1px;
  color: var(--dim); padding: 6px 10px; border-radius: 10px;
  border: 2px solid var(--panel-hi); background: var(--panel);
}
.fold-sum::-webkit-details-marker { display: none; }
.fold-sum::after { content: ' \25B8'; }
.fold[open] .fold-sum::after { content: ' \25BE'; }
.fold[open] .fold-sum { margin-bottom: 8px; }
.fold #stats-panel { max-width: none; width: 100%; }

/* STICKY FOOTER. START is the one control a 7-year-old must never have to hunt
   for, so it is pinned to the bottom of the scroller. The shadow is a SOLID
   16px extension plus a soften — a soft shadow alone is semi-transparent and
   text scrolling beneath stayed faintly legible, which reads as a rendering
   fault rather than as content passing behind a bar. */
.menu-foot {
  position: sticky;
  bottom: calc(-10px - env(safe-area-inset-bottom));
  z-index: 6;
  display: flex; flex-direction: column; align-items: center;
  gap: 8px; width: 100%;
  padding: 10px 0 calc(10px + env(safe-area-inset-bottom));
  margin-top: auto;
  background: rgba(10, 8, 30, .985);
  box-shadow: 0 -16px 0 0 rgba(10, 8, 30, .985),
              0 -30px 20px 0 rgba(10, 8, 30, .8);
}

/* Version switcher — the same three pills on v1, v2 and v3, so the builds link
   to each other. The current one is a <span>, so it cannot be clicked. */
.ver-switch {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 6px; font-size: clamp(9px, 1.3vh, 12px); font-weight: 900;
  letter-spacing: .5px;
}
.ver {
  padding: 5px 11px; border-radius: 999px;
  border: 2px solid var(--panel-hi); background: var(--panel);
  color: var(--muted); text-decoration: none;
  transition: border-color .12s, color .12s;
}
a.ver:hover, a.ver:focus-visible { color: #fff; border-color: var(--gold); }
.ver.here { color: var(--gold); border-color: var(--gold); background: rgba(255, 212, 42, .12); }

/* The keys line lists KEYBOARD controls. On a touch device it tells a
   7-year-old about keys he does not have, costs 33px of height, and is the
   thing that scrolls behind START. */
@media (pointer: coarse) { .keys { display: none; } }

@media (max-height: 560px) {
  .tag { display: none; }
  .keys { display: none; }
  .garage-title { font-size: clamp(20px, 5vh, 30px); }
  #cars { min-height: 132px; }
}
@media (max-height: 420px) {
  .fold { display: none; }
  #swatches { max-width: 300px; }
}
