/* ============ Powder Run ============ */

:root {
  --navy: #10233f;
  --navy-soft: #2c4568;
  --snow: #e8f1fb;
  --orange: #ff7a1a;
  --orange-deep: #e05e00;
  --gold: #ffc93c;
  --gold-deep: #ff9d00;
  --ice: #7ec8ff;
  --pine: #1c4a2e;
  --panel: rgba(255, 255, 255, 0.86);
  --font: 'Nunito', -apple-system, 'Segoe UI', system-ui, sans-serif;
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
}

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

html, body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--snow);
  font-family: var(--font);
  color: var(--navy);
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

#game {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
}

button {
  font-family: var(--font);
  border: 0;
  cursor: pointer;
  color: var(--navy);
  background: none;
}

.hidden { display: none !important; }

/* inline SVG icons */
.ic {
  width: 1.05em;
  height: 1.05em;
  display: inline-block;
  vertical-align: -0.16em;
  fill: currentColor;
  flex-shrink: 0;
}

.icb { color: #2a7fd4; }

/* ============ HUD ============ */

#hud {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 10;
}

/* top band: best (left) | score (center) | pause (right); combo bar
   centered underneath the score */
#scoreWrap {
  position: absolute;
  top: calc(8px + var(--sat));
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
}

#score {
  font-size: 40px;
  font-weight: 900;
  letter-spacing: 1px;
  line-height: 1;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 0 rgba(255, 255, 255, 0.9), 0 4px 14px rgba(16, 35, 63, 0.18);
  transition: transform 0.12s ease;
}

#score.bump { transform: scale(1.06); }

#score.gold {
  background: linear-gradient(180deg, #ffe27a 0%, var(--gold) 45%, var(--gold-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
  filter: drop-shadow(0 0 12px rgba(255, 201, 60, 0.75)) drop-shadow(0 2px 2px rgba(120, 60, 0, 0.35));
  animation: goldPulse 0.9s ease-in-out infinite;
}

@keyframes goldPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

#hudBest {
  position: absolute;
  top: calc(14px + var(--sat));
  left: 12px;
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 17px;
  font-weight: 900;
  color: var(--gold-deep);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.85);
}

#hudBest .ic { width: 20px; height: 20px; }

/* Daily Mountain HUD: best (top-left) | rating+time+speed bar stacked (center) |
   flake total (top-right, left of pause). Stacked (not one wide inline row)
   so it stays clear of the corner readouts even on narrow phones.
   #hudDaily itself stays unpositioned (like #hudEndless) so its
   position:absolute children resolve against #hud, not against it. */
#hudTimeWrap {
  position: absolute;
  top: calc(6px + var(--sat));
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

#hudTimeRow { display: flex; align-items: center; gap: 5px; }

#hudDailyBest, #hudFlakes {
  position: absolute;
  top: calc(14px + var(--sat));
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 15px;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.85);
}

#hudDailyBest { left: 10px; color: var(--gold-deep); }
#hudDailyBest .ic { width: 18px; height: 18px; }

#hudFlakes { right: 62px; color: #2a7fd4; }
#hudFlakes .ic { width: 17px; height: 17px; }

#hudTime {
  font-size: 30px;
  font-weight: 900;
  letter-spacing: 1px;
  line-height: 1;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 0 rgba(255, 255, 255, 0.9), 0 4px 14px rgba(16, 35, 63, 0.18);
}

/* Speed control bar: replaces the MPH readout. Daily Mountain has no
   automatic ramp -- tuck is the throttle for the whole run; Free Ski keeps
   its escalating ramp with tuck riding on top as a boost/brake. Either way
   this shows how hard the player is currently braking (fills left of the
   center tick) or tucking (fills right), not a speedometer number. Shared
   class so both #hudDaily and #hudEndless render the identical bar. */
.speedTrack {
  position: relative;
  width: 92px;
  height: 10px;
  margin-top: 5px;
  border-radius: 5px;
  background: rgba(16, 35, 63, 0.12);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.8);
}

.speedTrack::after {
  content: '';
  position: absolute;
  left: 50%;
  top: -2px;
  bottom: -2px;
  width: 2px;
  transform: translateX(-1px);
  background: rgba(16, 35, 63, 0.3);
}

.speedFillL, .speedFillR {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  transition: width 0.08s linear;
}

.speedFillL { right: 50%; border-radius: 5px 0 0 5px; background: var(--ice); }
.speedFillR { left: 50%; border-radius: 0 5px 5px 0; background: linear-gradient(90deg, #ffcf6b, var(--gold-deep)); }

.speedLabel { font-size: 8px; font-weight: 800; letter-spacing: 0.5px; color: var(--navy-soft); }

/* Free Ski's own speed bar, centered under the score (mirrors #hudTimeWrap's
   layout in Daily Mountain, which stacks it under the time instead). */
#hudSpeedWrapE {
  position: absolute;
  top: calc(54px + var(--sat));
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* Ghost gap indicator: only shown once the ghost has scrolled off the
   visible band -- tells you how far ahead/behind it is instead of nothing.
   Text-only (no card/background), like #hint, so it reads as a passing
   status note rather than a UI panel sitting on top of the run. */
#hudGhostGap {
  position: absolute;
  left: 50%;
  bottom: calc(38px + var(--sab));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.3px;
  color: var(--orange-deep);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.85), 0 2px 6px rgba(16, 35, 63, 0.18);
  opacity: 0.9;
}

#hudGhostGap.behind { color: #2e9e44; }
#hudGhostGap .ic { width: 12px; height: 12px; }

/* the ghost is off the top of the screen when it's behind (see reportGhostGap
   in game.js) -- move the indicator up there to match instead of leaving it
   anchored to the bottom where nothing is happening */
#hudGhostGap.top {
  top: calc(80px + var(--sat));
  bottom: auto;
}

#pauseBtn {
  position: absolute;
  top: calc(10px + var(--sat));
  right: 12px;
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.75);
  box-shadow: 0 2px 8px rgba(16, 35, 63, 0.15);
  font-size: 18px;
  pointer-events: auto;
}

/* Combo bar, centered under the score */
#combo {
  position: absolute;
  top: calc(92px + var(--sat));
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.88);
  box-shadow: 0 3px 10px rgba(16, 35, 63, 0.18);
  transform-origin: center center;
}

#combo.pop { animation: comboPopCentered 0.3s ease; }

@keyframes comboPopCentered {
  0% { transform: translateX(-50%) scale(1); }
  40% { transform: translateX(-50%) scale(1.14); }
  100% { transform: translateX(-50%) scale(1); }
}

#comboMult {
  font-size: 17px;
  font-weight: 900;
  line-height: 1;
}

#combo.hot #comboMult { color: var(--gold-deep); }

.cbar {
  width: 78px;
  height: 8px;
  border-radius: 4px;
  background: rgba(16, 35, 63, 0.12);
  overflow: hidden;
}

.cbar i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 4px;
  background: linear-gradient(90deg, #9fd4ff, #4aa3e8);
}

#combo.hot .cbar i { background: linear-gradient(90deg, #ffe27a, #ff9d00); }

#combo .cchain {
  display: flex;
  align-items: center;
  gap: 3px;
  font-size: 13px;
  font-weight: 800;
  color: var(--navy-soft);
}

#combo .cchain .ic { color: #2a7fd4; }

/* Floating popups */
#popups { position: absolute; inset: 0; overflow: hidden; }

.pop {
  position: absolute;
  transform: translate(-50%, 0);
  font-weight: 900;
  font-size: 17px;
  color: var(--navy);
  text-shadow: 0 1px 0 #fff, 0 2px 8px rgba(16, 35, 63, 0.25);
  white-space: nowrap;
  animation: popFloat 0.9s ease-out forwards;
}

.pop.flake { color: #2a7fd4; }
.pop.close { color: var(--orange-deep); font-size: 19px; }
.pop.bonus { color: var(--gold-deep); font-size: 20px; }
.pop.trick { color: #8a3ffc; font-size: 20px; }

@keyframes popFloat {
  0% { opacity: 0; transform: translate(-50%, 10px) scale(0.7); }
  15% { opacity: 1; transform: translate(-50%, 0) scale(1.1); }
  30% { transform: translate(-50%, -8px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -54px) scale(0.95); }
}

/* Snowflake collected during a timed run: no point popup, just this flake
   flying up into the flake-total readout in the corner of the HUD */
.flakeFly {
  position: absolute;
  transform: translate(-50%, -50%);
  color: #2a7fd4;
  font-size: 15px;
  animation: flakeFlyIn 0.55s cubic-bezier(0.3, 0.6, 0.4, 1) forwards;
}

.flakeFly .ic { width: 1em; height: 1em; }

@keyframes flakeFlyIn {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  65% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(0.25); }
}

/* Center banner (milestones, new best) */
#banner {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  text-align: center;
  font-size: 30px;
  font-weight: 900;
  letter-spacing: 1px;
  color: var(--navy);
  text-shadow: 0 2px 0 #fff, 0 4px 16px rgba(16, 35, 63, 0.3);
  opacity: 0;
  pointer-events: none;
}

#banner.show { animation: bannerZoom 1.4s ease forwards; }

/* Date + trail name, shown only during the 3-2-1-GO countdown, just below
   the big number -- replaces the old always-on home-screen mountain badge. */
#raceIntro {
  position: absolute;
  top: calc(50% + 34px);
  left: 0;
  right: 0;
  text-align: center;
  font-size: 15px;
  font-weight: 800;
  color: var(--navy-soft);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.85);
  pointer-events: none;
}

/* ski-run rating badges (green circle / blue square / black diamond) */
.stage-ic {
  display: inline-block;
  width: 0.56em;
  height: 0.56em;
  margin: 0 0.16em -0.03em 0;
  box-shadow: 0 0 0 2px #fff, 0 2px 4px rgba(16, 35, 63, 0.35);
}
.stage-ic.circle { border-radius: 50%; background: #2e9e44; }
.stage-ic.square { border-radius: 2px; background: #2f6fed; }
.stage-ic.diamond { border-radius: 2px; background: #16181d; transform: rotate(45deg) scale(0.86); }

#banner.gold {
  background: linear-gradient(180deg, #ffe27a, var(--gold-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
  filter: drop-shadow(0 0 16px rgba(255, 201, 60, 0.9)) drop-shadow(0 3px 3px rgba(120, 60, 0, 0.4));
  font-size: 34px;
}

#banner.danger {
  color: var(--orange-deep);
  text-shadow: 0 2px 0 #fff, 0 4px 16px rgba(224, 94, 0, 0.4);
  font-size: 34px;
}

@keyframes bannerZoom {
  0% { opacity: 0; transform: translateY(-50%) scale(0.5); }
  12% { opacity: 1; transform: translateY(-50%) scale(1.15); }
  22% { transform: translateY(-50%) scale(1); }
  78% { opacity: 1; transform: translateY(-50%) scale(1); }
  100% { opacity: 0; transform: translateY(-50%) scale(1.08); }
}

#hint {
  position: absolute;
  bottom: calc(90px + var(--sab));
  left: 0;
  right: 0;
  text-align: center;
  font-size: 17px;
  font-weight: 800;
  color: var(--navy-soft);
  text-shadow: 0 1px 0 #fff;
  animation: hintSway 1.6s ease-in-out infinite;
}

@keyframes hintSway {
  0%, 100% { transform: translateX(-18px); }
  50% { transform: translateX(18px); }
}

/* ============ Screens ============ */

.screen {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: calc(16px + var(--sat)) 20px calc(16px + var(--sab));
  overflow-y: auto;
}

.panel {
  position: relative;
  width: 100%;
  max-width: 400px;
  background: var(--panel);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-radius: 26px;
  padding: 22px 20px;
  box-shadow: 0 12px 44px rgba(16, 35, 63, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  animation: panelIn 0.35s cubic-bezier(0.2, 1.4, 0.4, 1);
}

@keyframes panelIn {
  from { opacity: 0; transform: translateY(26px) scale(0.94); }
  to { opacity: 1; transform: none; }
}

/* Logo */
.logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 0.95;
  margin-bottom: 2px;
}

.logo span {
  font-size: 44px;
  font-weight: 900;
  letter-spacing: 3px;
  background: linear-gradient(180deg, #3d6db5, var(--navy));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 0 rgba(255, 255, 255, 0.9));
}

.logo span:last-child {
  background: linear-gradient(180deg, #ff9d3f, var(--orange-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Home screen banner graphic, replaces the plain text logo there */
.homeLogo {
  width: 92%;
  max-width: 320px;
  height: auto;
  margin-bottom: 4px;
}

/* Home screen best-time line -- the tiny character sprite reflects whoever
   actually set that best, not whichever character is currently selected */
.homeBest {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 800;
  color: var(--navy-soft);
}

.homeBest canvas { width: 22px; height: 27px; }

.homeBest.obj {
  color: var(--orange-deep);
  font-weight: 900;
  letter-spacing: 0.3px;
}

.homeBest button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border-radius: 8px;
  background: rgba(16, 35, 63, 0.08);
  color: var(--navy-soft);
  flex-shrink: 0;
}

.homeBest button .ic { width: 13px; height: 13px; }

/* understated secondary entry point -- must not compete with the primary CTA */
.linklike {
  font-size: 13px;
  font-weight: 800;
  color: var(--navy-soft);
  padding: 4px 8px;
}

/* Home screen "Challenge" entry point -- one notch down from the .big PLAY
   NOW CTA (no gradient, no 3D shadow) so it doesn't compete for attention,
   but still its own full-width row, not a buried menu link. */
.pill {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 11px;
  border-radius: 16px;
  font-size: 15px;
  font-weight: 800;
  color: var(--navy);
  background: rgba(111, 193, 255, 0.22);
  border: 2px solid rgba(42, 127, 212, 0.32);
}

.pill:active { transform: translateY(1px); }

/* unread-count indicator -- pending challenges waiting on the player */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--orange-deep);
  color: #fff;
  font-size: 11px;
  font-weight: 900;
}

.recordBadge {
  font-size: 13px;
  font-weight: 800;
  color: var(--navy-soft);
  background: rgba(16, 35, 63, 0.08);
  padding: 3px 9px;
  border-radius: 10px;
  margin-left: 8px;
}

/* Challenge-sheet list row states */
.lbRow.chalPending { background: linear-gradient(90deg, rgba(111, 193, 255, 0.3), rgba(255, 255, 255, 0.8)); }
.lbRow.chalWaiting .pts { color: var(--navy-soft); font-weight: 700; }

/* Character cards */
.chars {
  display: flex;
  gap: 12px;
  width: 100%;
  justify-content: center;
}

.charCard {
  flex: 1;
  max-width: 150px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 12px 8px 10px;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.65);
  border: 3px solid transparent;
  box-shadow: 0 3px 10px rgba(16, 35, 63, 0.12);
  transition: transform 0.15s ease, border-color 0.15s ease;
}

.charCard.sel {
  border-color: var(--orange);
  transform: scale(1.05);
  background: #fff;
  box-shadow: 0 6px 18px rgba(224, 94, 0, 0.25);
}

.charCard canvas { width: 74px; height: 92px; }

.charCard span { font-size: 15px; font-weight: 900; letter-spacing: 1px; }

/* Buttons */
.big {
  width: 100%;
  padding: 16px;
  border-radius: 20px;
  font-size: 22px;
  font-weight: 900;
  letter-spacing: 1.5px;
  color: #fff;
  background: linear-gradient(180deg, #ff9d3f, var(--orange-deep));
  box-shadow: 0 6px 0 #b34a00, 0 10px 24px rgba(224, 94, 0, 0.4);
  transition: transform 0.08s ease, box-shadow 0.08s ease;
}

.big:active {
  transform: translateY(4px);
  box-shadow: 0 2px 0 #b34a00, 0 4px 12px rgba(224, 94, 0, 0.4);
}

.big.alt {
  background: linear-gradient(180deg, #6fc1ff, #2a7fd4);
  box-shadow: 0 6px 0 #1d5a9e, 0 10px 24px rgba(42, 127, 212, 0.4);
}

.big.alt:active {
  box-shadow: 0 2px 0 #1d5a9e, 0 4px 12px rgba(42, 127, 212, 0.4);
}

.menuRow {
  display: flex;
  gap: 10px;
  width: 100%;
  justify-content: center;
}

.menuRow button {
  flex: 1;
  padding: 11px 6px;
  border-radius: 14px;
  font-size: 14px;
  font-weight: 800;
  background: rgba(255, 255, 255, 0.75);
  box-shadow: 0 2px 8px rgba(16, 35, 63, 0.14);
  white-space: nowrap;
}

.tip {
  font-size: 12px;
  font-weight: 700;
  color: var(--navy-soft);
  text-align: center;
}

/* ============ Results ============ */

#newBest, #dailyNewPB {
  width: 100%;
  text-align: center;
  font-size: 26px;
  font-weight: 900;
  letter-spacing: 2px;
  background: linear-gradient(180deg, #ffe27a, var(--gold-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 14px rgba(255, 201, 60, 0.85));
  animation: goldPulse 0.8s ease-in-out infinite;
}

/* "NEW PERSONAL BEST" is longer than endless mode's "NEW BEST" -- wraps to
   two lines at #newBest's size on a phone-width panel, so it gets its own
   smaller size to stay on one line. */
#dailyNewPB {
  font-size: 17px;
  letter-spacing: 1px;
}

.tally { width: 100%; display: flex; flex-direction: column; gap: 7px; }

.trow {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 16px;
  font-weight: 800;
  color: var(--navy-soft);
  opacity: 0;
  transform: translateX(-12px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.trow.on { opacity: 1; transform: none; }

.trow b { color: var(--navy); font-variant-numeric: tabular-nums; font-size: 18px; }

.trow.total {
  margin-top: 4px;
  padding-top: 10px;
  border-top: 2px dashed rgba(16, 35, 63, 0.18);
  font-size: 18px;
  color: var(--navy);
}

.trow.total b { font-size: 34px; font-weight: 900; }

.trow.total.gold b {
  background: linear-gradient(180deg, #ffe27a, var(--gold-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 10px rgba(255, 201, 60, 0.8));
}

#submitRow, #dailySubmitRow, #chalNameGateRow { display: flex; gap: 8px; width: 100%; }

#chalNameGate { display: flex; flex-direction: column; gap: 8px; width: 100%; }

#nameInput, #dailyNameInput, #chalNameInput, #chalGateInput {
  flex: 1;
  min-width: 0;
  padding: 12px 14px;
  border-radius: 14px;
  border: 2px solid rgba(16, 35, 63, 0.18);
  font-family: var(--font);
  font-size: 16px;
  font-weight: 800;
  color: var(--navy);
  background: #fff;
  outline: none;
}

#nameInput:focus, #dailyNameInput:focus, #chalNameInput:focus, #chalGateInput:focus { border-color: var(--ice); }

.chalSearchWrap { display: flex; width: 100%; }
.chalSearchWrap input { width: 100%; }

/* Collapse these out of the panel's flex flow entirely when empty (the
   common case), instead of leaving them as blank flex items that still eat
   the panel's gap above and below -- otherwise the search box ends up
   floating in a big empty gap over the challenge list below it. */
#chalSearchResult:empty, #chalStatus:empty { display: none; }

.hint2 {
  font-size: 13px;
  font-weight: 800;
  color: var(--navy-soft);
  min-height: 17px;
  text-align: center;
  width: 100%;
}

#submitBtn, #dailySubmitBtn, #chalGateBtn {
  padding: 12px 16px;
  border-radius: 14px;
  font-size: 15px;
  font-weight: 900;
  color: #fff;
  background: linear-gradient(180deg, #4a9fe8, #2a6fc4);
  box-shadow: 0 3px 0 #1d4f8f;
}

#submitBtn:disabled, #dailySubmitBtn:disabled { opacity: 0.55; }

#submitMsg, #dailySubmitMsg {
  font-size: 13px;
  font-weight: 800;
  color: var(--navy-soft);
  min-height: 17px;
  text-align: center;
}

/* ============ Daily Mountain results ============ */

.dailyTrailLine {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 800;
  color: var(--navy-soft);
  letter-spacing: 0.5px;
}

.bigTime {
  font-size: 48px;
  font-weight: 900;
  letter-spacing: 1px;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

/* small reveal bounce once the count-up lands on the final time, so every
   finish feels a little alive even without a new-best/rank flourish */
.bigTime.reveal { animation: timePop 0.4s ease; }

@keyframes timePop {
  0% { transform: scale(1); }
  35% { transform: scale(1.1); }
  100% { transform: scale(1); }
}

#rDelta {
  font-size: 15px;
  font-weight: 800;
  color: var(--navy-soft);
  margin-top: -10px;
}

#rDelta.better { color: #2e9e44; }
#rDelta.worse { color: var(--orange-deep); }

#rRank {
  font-size: 14px;
  font-weight: 800;
  color: var(--navy-soft);
  text-align: center;
  margin-bottom: -8px;
}

/* #1 worldwide deserves more than the same plain line every other rank
   gets -- gold gradient + a pop-in and a slow pulse, same idea as
   #newBest/#dailyNewPB above the tally. */
#rRank.rank1 {
  font-size: 20px;
  letter-spacing: 0.5px;
  background: linear-gradient(180deg, #ffe27a, var(--gold-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 12px rgba(255, 201, 60, 0.8));
  animation: rank1In 0.5s cubic-bezier(0.2, 1.6, 0.4, 1), goldPulse 1s ease-in-out 0.5s infinite;
}

/* the gradient-text trick above sets color:transparent, which .ic's
   fill:currentColor would otherwise inherit and vanish -- give the crowns
   their own solid color back */
#rRank.rank1 .ic { width: 1.1em; height: 1.1em; color: var(--gold-deep); filter: drop-shadow(0 0 6px rgba(255, 201, 60, 0.9)); }

@keyframes rank1In {
  0% { opacity: 0; transform: scale(0.4); }
  70% { opacity: 1; transform: scale(1.15); }
  100% { opacity: 1; transform: scale(1); }
}

/* Confetti burst for a #1 finish -- pieces are spawned/removed by JS; this
   just defines the container and how one piece falls. Fixed + full-viewport
   so it isn't clipped by any panel's own overflow:auto. */
#confetti {
  position: fixed;
  inset: 0;
  z-index: 45;
  overflow: hidden;
  pointer-events: none;
}

.confettiPiece {
  position: absolute;
  top: -5vh;
  width: 8px;
  height: 14px;
  border-radius: 2px;
  opacity: 0.95;
  animation-name: confettiFall;
  animation-timing-function: cubic-bezier(0.3, 0.4, 0.4, 1);
  animation-fill-mode: forwards;
}

@keyframes confettiFall {
  0% { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(110vh) rotate(600deg); opacity: 0; }
}

/* "You vs Them" challenge-result comparison card, shown instead of #rDelta's
   plain text when the run just finished was racing someone -- more
   screenshot-shareable than a one-line delta. */
.vsCard { display: flex; align-items: center; gap: 10px; width: 100%; }

.vsCard .vsBox {
  flex: 1;
  text-align: center;
  padding: 10px 6px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.7);
}

.vsCard .vsBox.win {
  background: linear-gradient(180deg, rgba(255, 226, 122, 0.55), rgba(255, 255, 255, 0.75));
  outline: 2px solid rgba(255, 157, 0, 0.5);
}

.vsCard .vsLabel {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--navy-soft);
  text-transform: uppercase;
}

.vsCard .vsTime {
  font-size: 20px;
  font-weight: 900;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.vsCard .vsTag {
  font-size: 11px;
  font-weight: 800;
  color: var(--orange-deep);
}

.vsCard .vsAt { font-size: 14px; font-weight: 900; color: var(--navy-soft); }

/* ============ Leaderboard ============ */

#lbPanel .panel, #dailyResults .panel, #pastMountains .panel { max-height: 82vh; }

.lbHead {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
}

.lbHead h2 { font-size: 22px; font-weight: 900; letter-spacing: 1px; }

#lbClose,
#settingsClose {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: rgba(16, 35, 63, 0.08);
  font-size: 17px;
  font-weight: 900;
}

/* settings gear -- sits on the home screen card itself, top-right, like the
   close buttons on every other panel, instead of floating over the viewport */
#settingsBtn {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 40px;
  height: 40px;
  border-radius: 13px;
  background: rgba(16, 35, 63, 0.08);
  box-shadow: 0 2px 8px rgba(16, 35, 63, 0.1);
  color: var(--navy-soft);
}

.setLabel {
  width: 100%;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 1px;
  color: var(--navy-soft);
  margin-bottom: -6px;
}

.privacyLink {
  margin-top: 4px;
  font-size: 12px;
  font-weight: 700;
  color: var(--navy-soft);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.lbTabs {
  display: flex;
  width: 100%;
  background: rgba(16, 35, 63, 0.08);
  border-radius: 14px;
  padding: 4px;
  gap: 4px;
}

.lbTabs .tab {
  flex: 1;
  padding: 9px;
  border-radius: 11px;
  font-size: 14px;
  font-weight: 800;
  color: var(--navy-soft);
}

.lbTabs .tab.active {
  background: #fff;
  color: var(--navy);
  box-shadow: 0 2px 6px rgba(16, 35, 63, 0.15);
}

#lbStatus, #chalStatus { font-size: 13px; font-weight: 700; color: var(--navy-soft); min-height: 16px; }

#lbList, .lbList {
  list-style: none;
  width: 100%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 120px;
  /* padding on every side so a row's own outline/shadow (e.g. .lbRow.me)
     or a taller podium rank number (.lbRow.top1 .rank) has room to render --
     overflow-y: auto here clips flush against all four edges, so the very
     first/last row would otherwise get its top/bottom sliced off */
  padding: 3px;
}

/* Cap the Challenge sheet's list to about 5 rows -- pending/waiting/
   completed entries can pile up fast (Random Opponent, leaderboard
   challenges, etc.), so anything past that scrolls within the list
   instead of growing the sheet itself. */
#chalList { max-height: 240px; }

.lbRow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 12px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.7);
  font-weight: 800;
  font-size: 15px;
}

.lbRow .rank { width: 30px; color: var(--navy-soft); font-size: 14px; }

.lbRow .name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lbRow .pts { font-variant-numeric: tabular-nums; }

.lbRow .place {
  font-size: 11px;
  font-weight: 700;
  color: var(--navy-soft);
}

/* Past Mountains packs a date prefix into .name and a rank into .pts on top
   of the usual rating icon + trophy button, so it runs tighter than a plain
   leaderboard row to keep the trail name from being squeezed too hard. */
.lbRow.compact { font-size: 13px; gap: 8px; }
.lbRow.compact .pts { font-size: 12px; }

.lbRow .lbBtn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: 8px;
  background: rgba(16, 35, 63, 0.06);
  color: var(--navy-soft);
  flex-shrink: 0;
}

.lbRow .lbBtn .ic { width: 15px; height: 15px; }

.lbRow.me {
  background: linear-gradient(90deg, rgba(255, 201, 60, 0.35), rgba(255, 255, 255, 0.8));
  outline: 2px solid rgba(255, 157, 0, 0.5);
}

.lbRow.top1 .rank { color: #e2a90c; font-size: 16px; }
.lbRow.top2 .rank { color: #8d9bb0; font-size: 16px; }
.lbRow.top3 .rank { color: #b0703c; font-size: 16px; }

/* ============ Misc ============ */

#toast {
  position: fixed;
  bottom: calc(26px + var(--sab));
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  padding: 11px 20px;
  border-radius: 999px;
  background: var(--navy);
  color: #fff;
  font-size: 14px;
  font-weight: 800;
  white-space: nowrap;
  box-shadow: 0 6px 20px rgba(16, 35, 63, 0.4);
  animation: toastIn 0.25s ease;
}

@keyframes toastIn {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

#offlinePill {
  position: fixed;
  top: calc(12px + var(--sat));
  right: 12px;
  z-index: 30;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(16, 35, 63, 0.82);
  color: #fff;
  font-size: 12px;
  font-weight: 800;
}

#rotate {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--navy);
  color: #fff;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 900;
  text-align: center;
  padding: 30px;
}

@media (orientation: landscape) and (pointer: coarse) and (max-height: 500px) {
  #rotate { display: flex; }
}

@media (max-height: 700px) {
  .panel { gap: 10px; padding: 16px; }
  .logo span { font-size: 36px; }
  .charCard canvas { width: 60px; height: 75px; }
}
