/* MapSnap: a bright, airy atlas.
   White ground and soft sky, frosted glass panels floating over the map,
   lime-and-olive tickets you catch and snap into place, and painted-style
   landscapes for the big moments. Light by default, with a dark option
   (:root[data-theme="dark"]). Meanings: lime = placed and correct, olive =
   the main action, ember = mistakes and urgency, amber = hints. */

@font-face {
  font-family: "Hanken Grotesk";
  src: url("fonts/hanken-grotesk-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Hanken Grotesk";
  src: url("fonts/hanken-grotesk-latin-ext-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Hanken Grotesk";
  src: url("fonts/hanken-grotesk-latin-wght-italic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Ground, sky and sea */
  --ground: #f2f5e8;
  --sea: #dfe8cf;
  --sea-line: #c2d0ab;
  --land: #fbfcf4;
  --land-hover: #f1f6dc;
  --land-line: #66794a;

  /* Ink */
  --ink: #141d0e;
  --ink-soft: #3b4430;
  --ink-muted: #596451;
  --on-ink: #ffffff;
  --line: #d3ddc0;
  --line-strong: #b4c0a6;

  /* Lime: placed and correct. Olive: the main action. */
  --lime: #b5c64b;
  --lime-hover: #c0d054;
  --lime-deep: #98ab33;
  --lime-tint: #e7efcb;
  --lime-ink: #2f3d06; /* ticks and text on lime */
  --olive: #4b5f0f;
  --olive-deep: #384908;
  --good-ink: #4b5f0f; /* lime as text on a light ground */
  --btn: #4b5f0f;
  --btn-hover: #384908;
  --btn-ink: #ffffff;

  /* Ember: mistakes and urgency. Amber: hints. */
  --ember: #d8553d;
  --ember-deep: #b23c27;
  --ember-tint: #fbddd5;
  --amber: #f2b13c;
  --amber-tint: #fdeec8;
  --amber-edge: #c98a0f;
  --amber-wash: #f7e47c;

  /* Frosted glass */
  --glass: rgba(255, 255, 255, 0.6);
  --glass-strong: rgba(255, 255, 255, 0.82);
  --glass-edge: rgba(255, 255, 255, 0.95);
  --glass-line: rgba(30, 45, 10, 0.1);
  --veil: rgba(255, 255, 255, 0.16);
  --shadow-glass: 0 1px 2px rgba(25, 35, 10, 0.06), 0 12px 28px -14px rgba(25, 40, 10, 0.3);
  --shadow-sheet: 0 2px 4px rgba(25, 35, 10, 0.06), 0 36px 72px -28px rgba(25, 40, 10, 0.42);
  --flag-edge: rgba(18, 23, 12, 0.7);
  --lane-glass: rgba(244, 247, 234, 0.55);
  --slip-fill: #e3ecbd; /* a slip waiting to be placed: paler than the lime it becomes */
  --ticket-bg: color-mix(in srgb, var(--ink) 7%, transparent);
  --ticket-bad: color-mix(in srgb, var(--ember) 20%, transparent);


  --display: "Expose", "Arial Narrow", system-ui, sans-serif;
  --accent: #4a6712;
  --chip: rgba(30, 46, 16, 0.07);
  --stage-a: #fcfdf6;
  --stage-b: #d9e3c2;
  --bokeh: rgba(181, 198, 75, 0.4);
  --font: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  /* Motion: shared with the landing page and the videos (DESIGN.md "Motion"). */
  --ease-in: cubic-bezier(0.55, 0, 0.8, 0.2);    /* leaving: a slip flying home */
  --ease-snap: cubic-bezier(0.3, 1.45, 0.55, 1); /* the snap: one small overshoot, never a bounce */
  --ease-glass: cubic-bezier(0.22, 1.2, 0.36, 1); /* a panel settling */
  --dur-press: 90ms;   /* a button press */
  --dur-quick: 180ms;  /* hover, release, small state changes */
  --dur-mark: 280ms;   /* a tick or cross drawing itself */
  --dur-fly: 300ms;    /* a slip flying onto its country */
  --dur-ink: 560ms;    /* a placed country taking its lime */
  --dur-sheet: 520ms;  /* a panel arriving */
  --lift-scale: 1.05;  /* a held slip, closer to the eye */
  --tilt-max: 7deg;    /* a held slip's tilt as it's swung */

  /* Safe-area insets (notch, camera cut-out, gesture bar). Inside the
     Android app Capacitor provides them as --safe-area-inset-* (older
     Android WebViews report env() wrongly); browsers use env(). */
  --inset-top: var(--safe-area-inset-top, env(safe-area-inset-top, 0px));
  --inset-right: var(--safe-area-inset-right, env(safe-area-inset-right, 0px));
  --inset-bottom: var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px));
  --inset-left: var(--safe-area-inset-left, env(safe-area-inset-left, 0px));

  --hud-height: 68px;
  --lane-height: 168px; /* overwritten by src/layout.js from LAYOUT */

  color-scheme: light;
}

:root[data-theme="dark"] {
  --ground: #172419;
  --sea: #111c13;
  --sea-line: #263b29;
  --land: #223523;
  --land-hover: #2e482f;
  --land-line: rgba(190, 210, 100, 0.6);

  --ink: #f0f4ea;
  --ink-soft: #c8d5c1;
  --ink-muted: #93a58d;
  --on-ink: #10180a;
  --line: #2d4331;
  --line-strong: #45614a;

  --lime-hover: #c4d557;
  --lime-tint: rgba(181, 198, 75, 0.2);
  --good-ink: #a8c53a;
  --btn: #6f8f1f;
  --btn-hover: #7da024;
  --btn-ink: #ffffff;

  --ember: #ee7a63;
  --ember-deep: #ff9a85;
  --ember-tint: rgba(238, 122, 99, 0.22);
  --amber-tint: rgba(242, 177, 60, 0.2);
  --amber-edge: #d9a03a;
  --amber-wash: #9c8c20;

  --glass: rgba(22, 34, 24, 0.62);
  --glass-strong: rgba(22, 34, 24, 0.84);
  --glass-edge: rgba(214, 240, 160, 0.1);
  --glass-line: rgba(214, 240, 160, 0.12);
  --veil: rgba(4, 10, 5, 0.4);
  --shadow-glass: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 28px -14px rgba(0, 0, 0, 0.6);
  --shadow-sheet: 0 2px 4px rgba(0, 0, 0, 0.3), 0 36px 72px -28px rgba(0, 0, 0, 0.75);
  --flag-edge: rgba(255, 255, 255, 0.55);
  --lane-glass: rgba(18, 29, 20, 0.5);
  --slip-fill: #dfe8b4;

  --accent: #86a523;
  --chip: rgba(214, 240, 170, 0.07);
  --stage-a: #2b422c;
  --stage-b: #142016;
  --bokeh: rgba(140, 182, 38, 0.36);

  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html, body, #app {
  height: 100%;
  margin: 0;
}

body {
  font-family: var(--font);
  background: var(--ground);
  color: var(--ink);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

::selection {
  background: var(--lime);
  color: var(--lime-ink);
}

button {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2.5px solid var(--olive);
  outline-offset: 2px;
}

:root[data-theme="dark"] :focus-visible {
  outline-color: var(--lime);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.logo-ticket { fill: var(--lime); }
.logo-tick { stroke: var(--lime-ink); }

.screen {
  width: 100%;
  height: 100%;
}

.hidden {
  display: none !important;
}

/* ---------- The game screen: always present, the map is every screen's ground ---------- */

/* White sky above the map, easing into the sea exactly where the map starts. */
#game-screen {
  position: relative;
  overflow: hidden; /* the map can be wider than the screen; never widen the page */
  background: linear-gradient(180deg, var(--ground) 0, var(--sea) var(--hud-height), var(--sea) 100%);
}

/* Outside a round the map fills the screen under the sheet; HUD and lane
   only exist during play. */
#app:not([data-screen="game"]) #hud,
#app:not([data-screen="game"]) #lane-track,
#app:not([data-screen="game"]) #spawn-lane {
  display: none;
}

#app:not([data-screen="game"]) #map-svg {
  top: 0;
  height: 100%;
  pointer-events: none;
}

/* ---------- Sheets (menu, pause, win): frosted glass over the map ---------- */

.sheet-screen {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex; /* with .sheet's auto margins: centred, yet scrollable to the top when taller than the screen */
  padding: max(20px, var(--inset-top)) max(16px, var(--inset-right))
    max(20px, var(--inset-bottom)) max(16px, var(--inset-left));
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
  background: var(--veil);
}

.sheet {
  position: relative;
  width: 100%;
  max-width: 480px;
  margin: auto;
  padding: 28px 28px 26px;
  border: 1px solid var(--glass-edge);
  border-radius: 28px;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(22px) saturate(1.5);
  backdrop-filter: blur(22px) saturate(1.5);
  box-shadow: var(--shadow-sheet);
  animation: sheet-in var(--dur-sheet) var(--ease-glass);
  transform-origin: 50% 0;
}

/* A panel settling onto the map: it drops a little and eases flat. */
@keyframes sheet-in {
  from { transform: translateY(-16px) scale(0.985); }
  to   { transform: none; }
}

.sheet-tools {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
  display: flex;
  gap: 8px;
}

.sheet-head {
  margin-bottom: 18px;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.wordmark svg {
  width: 24px;
  height: 24px;
}

.title {
  margin: 0;
  font-size: clamp(1.85rem, 6vw, 2.45rem);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -0.035em;
  color: var(--ink);
  text-wrap: balance;
}

/* The italic accent word: a lighter, leaning olive. */
.title em {
  font-style: italic;
  font-weight: 500;
  color: var(--good-ink);
}

.subtitle {
  margin: 10px 0 0;
  color: var(--ink-soft);
  font-size: 1rem;
  line-height: 1.45;
  text-wrap: pretty;
}

.menu-group {
  margin: 0 0 18px;
  padding: 0;
  border: 0;
  min-width: 0;
}

.menu-group legend {
  padding: 0;
  margin-bottom: 8px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-muted);
}

/* ---------- Choices: tiles that fill lime when picked ---------- */

.choice-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.choice-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.choice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 44px;
  padding: 12px;
  border: 1.5px solid var(--line);
  border-radius: 16px;
  background: var(--glass);
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  transition: background var(--dur-quick), border-color var(--dur-quick), transform var(--dur-quick) var(--ease-snap);
}

.choice:hover {
  border-color: var(--lime-deep);
  background: var(--glass-strong);
}

.choice:active {
  transform: scale(0.98);
  transition-duration: var(--dur-press);
}

.choice.selected {
  border-color: var(--lime-deep);
  background: var(--lime-tint);
}

.tickbox {
  flex: none;
  position: relative;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  border: 1.8px solid var(--line-strong);
  border-radius: 50%;
  background: var(--glass-strong);
  transition: background var(--dur-quick), border-color var(--dur-quick);
}

.choice.selected .tickbox {
  border-color: var(--btn);
  background: var(--btn);
}

.tickbox svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 2px;
  color: var(--btn-ink);
}

.tickbox svg use {
  /* The tick draws itself when chosen. */
  stroke-dasharray: 30;
  stroke-dashoffset: 30;
}

.choice.selected .tickbox svg use {
  animation: tick-draw var(--dur-mark) var(--ease-out) forwards;
}

@keyframes tick-draw {
  to { stroke-dashoffset: 0; }
}

.choice-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.choice-title {
  font-size: 1rem;
  font-weight: 650;
  color: var(--ink);
}

.choice-desc {
  font-size: 0.85rem;
  line-height: 1.3;
  color: var(--ink-muted);
}

.choice-compact {
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  border-radius: 999px;
}

.choice-compact .tickbox {
  margin-top: 0;
}

.hint {
  text-wrap: pretty;
  margin: 8px 0 0;
  min-height: 2.7em;
  font-size: 0.88rem;
  line-height: 1.4;
  color: var(--ink-muted);
}

.sheet-foot {
  margin-top: 4px;
}

/* ---------- Buttons ---------- */

.start-btn {
  width: 100%;
  min-height: 54px;
  padding: 14px;
  border: 0;
  border-radius: 999px;
  background: var(--btn);
  color: var(--btn-ink);
  font-size: 1.08rem;
  font-weight: 650;
  letter-spacing: 0.005em;
  cursor: pointer;
  box-shadow: 0 8px 18px -10px rgba(40, 55, 8, 0.7);
  /* Release: springs back with a small overshoot. */
  transition: background var(--dur-quick), transform var(--dur-quick) var(--ease-snap);
}

.start-btn:not(:disabled):hover {
  background: var(--btn-hover);
}

/* A press: quick, short travel, straight down. */
.start-btn:not(:disabled):active {
  transform: translateY(1px) scale(0.97);
  transition-duration: var(--dur-press);
  transition-timing-function: ease-out;
}

.start-btn:disabled {
  background: var(--line);
  color: var(--ink-muted);
  box-shadow: none;
  cursor: progress;
}

/* The best score for the menu's selection, just above Start. */
.menu-best {
  margin: 0 0 10px;
  text-align: center;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.menu-best[hidden] { display: none; }

.menu-best strong {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.menu-status {
  margin: 10px 0 0;
  min-height: 1.2em;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 650;
  color: var(--ember-deep);
}

/* A sheet's buttons, stacked: the primary action first. */
.sheet-actions {
  display: grid;
  gap: 10px;
}

/* Secondary action on a sheet (e.g. "Quit to menu"). */
.secondary-btn {
  width: 100%;
  min-height: 50px;
  padding: 12px;
  border: 1.5px solid var(--line-strong);
  border-radius: 999px;
  background: var(--glass);
  color: var(--ink);
  font-size: 1rem;
  font-weight: 650;
  cursor: pointer;
  transition: border-color var(--dur-quick), background var(--dur-quick), transform var(--dur-quick) var(--ease-snap);
}

.secondary-btn:hover {
  border-color: var(--ink-soft);
  background: var(--glass-strong);
}

.secondary-btn:active {
  transform: translateY(1px) scale(0.97);
  transition-duration: var(--dur-press);
  transition-timing-function: ease-out;
}

.sheet-note {
  margin: 10px 0 0;
  text-align: center;
  font-size: 0.88rem;
  color: var(--ink-muted);
}

/* ---------- Tickets: lime stat cards with a notch on each side ---------- */

/* The recap's figures (pause and win) and the final score are tickets: lime,
   cut with a half-circle notch on each edge. */
.recap-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin: 0 0 22px;
}

.recap-stat,
.ticket {
  --notch: 8px;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 16px 14px;
  border-radius: 18px;
  background: var(--lime);
  color: var(--lime-ink);
  -webkit-mask:
    radial-gradient(circle var(--notch) at 0 50%, #0000 calc(var(--notch) - 0.5px), #000 var(--notch)) left / 51% 100% no-repeat,
    radial-gradient(circle var(--notch) at 100% 50%, #0000 calc(var(--notch) - 0.5px), #000 var(--notch)) right / 51% 100% no-repeat;
  mask:
    radial-gradient(circle var(--notch) at 0 50%, #0000 calc(var(--notch) - 0.5px), #000 var(--notch)) left / 51% 100% no-repeat,
    radial-gradient(circle var(--notch) at 100% 50%, #0000 calc(var(--notch) - 0.5px), #000 var(--notch)) right / 51% 100% no-repeat;
}

.recap-stat dt,
.ticket-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--lime-ink);
  opacity: 0.8;
}

.recap-stat dd,
.ticket-value {
  margin: 0;
  font-size: 1.7rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--lime-ink);
  font-variant-numeric: tabular-nums;
}

/* Lime is for the score and for what's placed. The recap's other figures are
   neutral, and turn ember only when they report a mistake. */
.recap-stat {
  background: var(--ticket-bg);
  color: var(--ink);
}

.recap-stat dt {
  color: var(--ink-muted);
  opacity: 1;
}

.recap-stat dd {
  color: var(--ink);
}

.recap-stat.bad {
  background: var(--ticket-bad);
}

.recap-stat.bad dt,
.recap-stat.bad dd {
  color: var(--ember-deep);
}

.recap-stat[hidden] {
  display: none;
}

.ticket-score {
  --notch: 11px;
  flex: none;
  min-width: 210px;
  gap: 18px;
  padding: 16px 24px 20px;
  border-radius: 22px;
}

.ticket-score .ticket-value {
  font-size: 3.4rem;
  letter-spacing: -0.035em;
}

/* Paused: the slips are put away, so the pause isn't free thinking time. */
#app[data-paused] #spawn-lane {
  visibility: hidden;
}

/* Win */
.win-sheet {
  text-align: left;
}

/* On roomy screens the sheet sits to one side, so the finished map is the
   trophy and stays in view. */
@media (min-width: 980px) and (min-height: 640px) {
  #win-screen .sheet {
    margin: auto max(24px, 6vw) auto auto;
  }
}

.win-result {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
  margin: 20px 0 22px;
}

/* "New best!" / "3rd best", beside the score ticket. */
.win-standing {
  margin: 0;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--btn);
  color: var(--btn-ink);
  font-size: 0.95rem;
  font-weight: 650;
}

.win-standing[hidden] { display: none; }

.best-scores {
  margin: 18px 0 20px;
}

.best-scores[hidden] { display: none; }

/* This round's row: its score in lime. */
.best-list li.current .tricky-name {
  color: var(--good-ink);
}

.win-sheet .recap-stats {
  margin-bottom: 20px;
}

.tricky {
  margin: 0 0 24px;
}

.tricky-heading {
  margin: 0 0 6px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-muted);
}

.tricky-list {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: tricky;
}

.tricky-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  counter-increment: tricky;
}

/* The trickiest countries appear one by one, after the score ticket (--i is
   each row's place, set by UI#showWin). */
#win-tricky li {
  animation: row-in var(--dur-mark) var(--ease-out) both;
  animation-delay: calc(900ms + var(--i, 0) * 110ms);
}

@keyframes row-in {
  from { opacity: 0; translate: -6px 0; }
  to   { opacity: 1; translate: none; }
}

.tricky-list li::before {
  content: counter(tricky) ".";
  min-width: 1.2em;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.tricky-name {
  font-weight: 650;
  color: var(--ink);
}

.tricky-detail {
  margin-left: auto;
  font-size: 0.88rem;
  color: var(--ink-soft);
}

.tricky-empty {
  margin: 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

/* Continent mode's picker: shown under the modes when Continent is chosen. */
.continent-picker {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin: 10px 0 0;
}

.continent-picker .choice-title {
  white-space: nowrap;
  font-size: 0.9rem;
}

.continent-picker[hidden] {
  display: none;
}

/* ---------- HUD: frosted pills floating on the sky above the map ---------- */

#hud {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--hud-height);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 20px;
  color: var(--ink);
  z-index: 30;
}

.hud-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1.12rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.hud-logo {
  width: 26px;
  height: 26px;
}

.hud-stats {
  display: flex;
  align-items: stretch;
  margin: 0 auto;
  padding: 4px 6px;
  border: 1px solid var(--glass-edge);
  border-radius: 999px;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  box-shadow: var(--shadow-glass);
}

.hud-item {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 108px;
  min-height: 42px;
  padding: 0 18px;
  line-height: 1.15;
}

.hud-item + .hud-item {
  border-left: 1px solid var(--line);
}

.hud-label {
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--ink-muted);
  white-space: nowrap;
}

.hud-value {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: color 0.2s;
}

#hud-score.pulse-success { color: var(--good-ink); }
#hud-score.pulse-penalty { color: var(--ember-deep); }
#hud-timer.urgent { color: var(--ember-deep); }

/* "+87" / "−15" beside the score, in space reserved for it, so it never
   collides with the value however large it grows. */
.hud-value-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.hud-delta {
  display: inline-block;
  min-width: 2.4em;
  font-size: 0.95rem;
  font-weight: 700;
  font-style: italic;
  line-height: 1;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
}

.hud-delta.success { color: var(--good-ink); }
.hud-delta.penalty { color: var(--ember-deep); }

.hud-delta.show {
  animation: delta-rise 900ms var(--ease-out);
}

/* Drifts sideways within the value row, never up into the label row. */
@keyframes delta-rise {
  0%   { opacity: 0; transform: translateX(-4px); }
  15%  { opacity: 1; }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translateX(10px); }
}

.hud-score-item {
  z-index: 1;
}

.hud-progress-item {
  min-width: 150px;
}

.hud-progress {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 2px;
  height: 3px;
  border-radius: 2px;
  background: var(--line);
  overflow: hidden;
}

#hud-progress-fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--lime-deep);
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 0.4s var(--ease-out);
}

/* Glass pill buttons: pause, sound, theme and (on easy) hint. */
.pause-btn,
.hint-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 8px 16px 8px 12px;
  border: 1px solid var(--glass-edge);
  border-radius: 999px;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  box-shadow: var(--shadow-glass);
  color: var(--ink);
  font-weight: 650;
  font-size: 0.95rem;
  cursor: pointer;
  touch-action: manipulation;
  transition: background var(--dur-quick), border-color var(--dur-quick), opacity var(--dur-quick), transform var(--dur-quick) var(--ease-snap);
}

.pause-btn:hover {
  background: var(--ground);
}

.pause-btn:active,
.hint-btn:active:not(:disabled) {
  transform: scale(0.95);
  transition-duration: var(--dur-press);
}

.pause-btn svg,
.hint-btn svg {
  width: 20px;
  height: 20px;
}

.hint-btn {
  position: relative;
  border-color: var(--amber-edge);
  background: var(--amber-tint);
}

/* What the hint costs, on the button itself. */
.hint-cost {
  position: absolute;
  top: -7px;
  right: -3px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--ember-deep);
  color: var(--on-ink);
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1.3;
  pointer-events: none;
}

.hint-btn:disabled .hint-cost {
  opacity: 0.5;
}

/* display:flex above would otherwise override the hidden attribute. */
.hint-btn[hidden] { display: none; }

.hint-btn:hover:not(:disabled) {
  background: var(--amber);
  color: #2a1d02;
}

.hint-btn:disabled {
  background: var(--glass);
  border-color: var(--line);
  color: var(--ink-muted);
  box-shadow: none;
  cursor: default;
}

/* Sound and theme: icon-only round buttons in the HUD and on the menu sheet. */
.sound-btn,
.theme-btn {
  justify-content: center;
  min-width: 44px;
  padding: 8px;
}

.sound-btn[aria-pressed="false"] {
  color: var(--ink-muted);
}

/* The theme button shows the theme you'd switch to: a moon while it's light. */
.theme-btn use {
  /* swapped by UI#setTheme */
  pointer-events: none;
}

/* ---------- The lane: a frosted strip the slips float along ---------- */

#lane-track {
  position: fixed;
  top: var(--hud-height);
  left: 0;
  right: 0;
  height: var(--lane-height);
  /* See-through glass (MAP-07); the slips on it are solid. */
  background: var(--lane-glass);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--glass-edge);
  box-shadow: 0 12px 24px -18px rgba(25, 40, 10, 0.4);
  z-index: 5;
  pointer-events: none;
}

#lane-track::after {
  content: "Drag a slip onto the map, or tap its country";
  position: absolute;
  right: 20px;
  bottom: 10px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-muted);
}

@media (max-width: 720px) {
  #lane-track::after { display: none; }
}

/* Full-screen map below the HUD (the lane floats over it); its size is set
   in px by WorldMap and it's panned and zoomed with a transform (MapPan),
   so the browser must not scroll or zoom it. */
#map-svg {
  position: absolute;
  top: var(--hud-height);
  left: 0;
  display: block;
  z-index: 1;
  touch-action: none;
  transform-origin: 0 0; /* MapPan's translate + scale assume a top-left origin */
}

/* ---------- The map ---------- */

/* Map strokes are divided by --map-zoom (set by MapPan once a pan or zoom
   settles), so borders keep their width at any zoom. */

/* The sea is a plain rectangle, repeated for the wrap-around copy: no
   outline, or the seam between the copies would show as a line. */
.sphere {
  fill: var(--sea);
  stroke: none;
  pointer-events: none;
}

.graticule {
  fill: none;
  stroke: var(--sea-line);
  stroke-opacity: 0.5;
  stroke-width: calc(0.5px / var(--map-zoom, 1));
  pointer-events: none;
}

.country {
  fill: var(--land);
  stroke: var(--land-line);
  stroke-width: calc(0.5px / var(--map-zoom, 1));
  stroke-linejoin: round;
  transition: fill 0.3s;
}

/* Unplaced countries can be tapped to place a matching piece. Every unplaced
   country gets the same hover, so it gives nothing away; no hover on touch. */
.country.unplaced {
  cursor: pointer;
}

@media (hover: hover) {
  .country.unplaced:hover {
    fill: var(--land-hover);
    stroke: var(--lime-deep);
    stroke-width: calc(1.2px / var(--map-zoom, 1));
  }
}

/* Continent mode: countries of other continents aren't drawn; the chosen
   continent fills the map. (Its own non-playable shapes, e.g. French
   Guiana, are drawn but can't be tapped: out-of-play.) */
.country.off-map,
.country-dot.off-map {
  display: none;
}

.country.out-of-play {
  cursor: default;
}

/* Placed: lime, with a faint olive weave. */
.country.placed {
  fill: url(#placed-hatch);
  stroke: var(--olive);
  stroke-width: calc(0.6px / var(--map-zoom, 1));
}

.country.flash-success {
  transition: none;
}

/* The snap (WorldMap#_ink): a lime copy of the country lands a little large,
   presses down past flat and fades into the fill below. --ink-from is larger
   for small countries. */
.ink {
  fill: var(--lime);
  stroke: var(--olive);
  stroke-width: calc(1px / var(--map-zoom, 1));
  stroke-linejoin: round;
  pointer-events: none;
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: ink-take var(--dur-ink) var(--ease-out) both;
}

@keyframes ink-take {
  0%   { opacity: 0.95; transform: scale(var(--ink-from, 1.1)); }
  30%  { opacity: 0.9;  transform: scale(0.985); animation-timing-function: var(--ease-out); }
  55%  { opacity: 0.7;  transform: none; }
  100% { opacity: 0;    transform: none; }
}

.country.flash-wrong {
  fill: var(--ember-tint) !important;
  stroke: var(--ember);
  stroke-width: calc(1.3px / var(--map-zoom, 1));
  transition: none;
}

.country.flash-missed {
  stroke: var(--ember);
  stroke-width: calc(1.5px / var(--map-zoom, 1));
}

/* Hint: an amber wash over every country on the continent. No 0%/100%
   keyframes, so each pulse returns to the path's own fill. Timing comes from
   config via --hint-pulse-ms / --hint-pulses on the layer. */
.country.hint-flash {
  animation: continent-flash var(--hint-pulse-ms, 450ms) ease-in-out var(--hint-pulses, 3);
}

@keyframes continent-flash {
  50% { fill: var(--amber-wash); }
}

/* Dots for countries too small to see as a shape. */
.country-dot {
  fill: var(--ink-soft);
  stroke: var(--land);
  stroke-width: 0.6px;
  pointer-events: none;
  /* Dots keep their size at any zoom, so a zoomed-in small country's own
     shape shows round its dot. */
  transform-box: fill-box;
  transform-origin: center;
  scale: calc(1 / var(--map-zoom, 1));
}

.country-dot.placed {
  fill: var(--olive);
}

/* A small country's dot pops as it turns lime. */
.country-dot.dot-pop {
  animation: dot-pop 420ms var(--ease-snap) both;
}

@keyframes dot-pop {
  0%   { transform: scale(2.6); }
  100% { transform: none; }
}

/* Marks: drawn by their stroke, then fade. */
.mark path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  pointer-events: none;
  animation:
    mark-draw var(--dur-mark) var(--ease-out) var(--mark-delay, 0ms) forwards,
    mark-fade 300ms ease-in calc(850ms + var(--mark-delay, 0ms)) forwards;
}

.mark-cross path:nth-child(2) {
  animation-delay: calc(110ms + var(--mark-delay, 0ms)), calc(850ms + var(--mark-delay, 0ms));
}

.mark-tick path { stroke: var(--lime-ink); stroke-width: 3.4px; }
.mark-cross path { stroke: var(--ember); stroke-width: 3.2px; }
.mark-circle path { stroke: var(--ember); stroke-width: 2.8px; animation-duration: 420ms, 300ms; }

/* "Here it is": after a mistake the right country is outlined in ember and
   its name appears on a glass label with an arrow pointing at it
   (WorldMap#reveal). The tag is placed at the arrow's tip; data-side says
   where the name goes and mirrors the arrow to match. */
.country.reveal {
  stroke: var(--ember);
  stroke-width: calc(1.7px / var(--map-zoom, 1));
  animation: reveal-pulse 700ms ease-in-out 2;
}

@keyframes reveal-pulse {
  50% { fill: var(--ember-tint); }
}

.reveal-tag {
  --reveal-ms: 1500ms; /* set from REVEAL.durationMs */
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  z-index: 6; /* over the map and the lane, under the slips, HUD and sheets */
  pointer-events: none;
}

.reveal-arrow {
  position: absolute;
  left: -4px;
  bottom: -4px;
  width: 48px;
  height: 34px;
  overflow: visible;
  fill: none;
  stroke: var(--ember);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.reveal-arrow path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation:
    mark-draw 260ms var(--ease-out) forwards,
    mark-fade 300ms ease-in calc(var(--reveal-ms) - 300ms) forwards;
}

.reveal-arrow path:nth-child(2) {
  animation-delay: 220ms, calc(var(--reveal-ms) - 300ms);
}

.reveal-text {
  position: absolute;
  left: 38px;
  bottom: 22px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  padding: 8px 14px 9px;
  border: 2px solid var(--ember);
  border-radius: 14px;
  background: var(--ground);
  box-shadow: var(--shadow-glass);
  line-height: 1.1;
  white-space: nowrap;
  color: var(--ink);
  opacity: 0;
  animation:
    reveal-write 200ms ease-out 180ms forwards,
    mark-fade 300ms ease-in calc(var(--reveal-ms) - 300ms) forwards;
}

.reveal-name { font-size: 1.2rem; font-weight: 700; }
.reveal-sub { font-size: 0.9rem; font-weight: 500; color: var(--ink-soft); }

.reveal-tag[data-side$="w"] .reveal-arrow { left: auto; right: -4px; scale: -1 1; }
.reveal-tag[data-side$="w"] .reveal-text { left: auto; right: 38px; align-items: flex-end; }
.reveal-tag[data-side^="s"] .reveal-arrow { bottom: auto; top: -4px; scale: 1 -1; }
.reveal-tag[data-side^="s"] .reveal-text { bottom: auto; top: 22px; }
.reveal-tag[data-side="sw"] .reveal-arrow { scale: -1 -1; }

@keyframes reveal-write {
  from { opacity: 0; translate: 0 3px; }
  to   { opacity: 1; translate: none; }
}

@keyframes mark-draw {
  to { stroke-dashoffset: 0; }
}

@keyframes mark-fade {
  to { opacity: 0; }
}

/* Phones in portrait: a glass chip under the header saying the map can be
   swiped (shown until the player's first swipe, see main.js). */
.swipe-hint {
  position: fixed;
  top: calc(var(--hud-height) + 12px);
  left: 50%;
  translate: -50% 0;
  z-index: 25; /* over the map, under the HUD and sheets */
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100% - 32px);
  padding: 10px 16px 10px 12px;
  border: 1px solid var(--glass-edge);
  border-radius: 20px;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-glass);
  color: var(--ink);
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.25;
  pointer-events: none;
  animation: slip-in 350ms var(--ease-out);
}

.swipe-hint[hidden] {
  display: none;
}

.swipe-hint svg {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--ink-soft);
  animation: swipe-nudge 1.6s ease-in-out infinite;
}

@keyframes swipe-nudge {
  0%, 100% { translate: -3px 0; }
  50% { translate: 3px 0; }
}

#app[data-paused] .swipe-hint {
  display: none;
}

/* ---------- Slips: the country itself, in lime ---------- */

#spawn-lane {
  position: fixed;
  inset: 0;
  z-index: 20;
  pointer-events: none;
}

/* A slip is just the country's shape (drawn at the map's own scale) with its
   name beneath. The padding is an invisible grip, so small countries are
   still easy to catch. */
.piece {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 10px 12px;
  min-width: 48px;
  color: var(--ink);
  pointer-events: auto;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  will-change: transform;
  animation: slip-in 350ms var(--ease-out);
}

/* A new slip slides in from the lane's start as it fades up. Uses the
   translate property, which adds to the slip's positioning transform. */
@keyframes slip-in {
  from { opacity: 0; translate: -14px 0; }
  to   { opacity: 1; translate: none; }
}

/* The country drawn as on the map, at the map's own scale: its size is set
   inline by pieces.js (width/height attributes). The shadow lifts it off the
   map; it lifts further when held. */
.piece-shape-svg {
  display: block;
  overflow: visible;
  filter:
    drop-shadow(0 1px 1.5px rgba(25, 40, 10, 0.38))
    drop-shadow(0 6px 8px rgba(25, 40, 10, 0.2));
  transition: filter var(--dur-quick);
}

/* Keep outlines hairline-thin however much a shape is scaled. */
.piece-shape-svg path,
.piece-shape-svg circle {
  vector-effect: non-scaling-stroke;
}

.piece-outline {
  fill: var(--slip-fill);
  stroke: var(--olive-deep);
  stroke-width: 1.4;
  stroke-linejoin: round;
  transition: fill var(--dur-quick), stroke var(--dur-quick);
}

:root[data-theme="dark"] .piece-outline {
  stroke: #26320a;
}

.piece:hover .piece-outline {
  fill: var(--lime);
}

/* The slip's own countdown: a bar under its name drains as it floats away
   (--left is 1 at the lane's start, 0 at its end; set by GameRound). */
.piece::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 3px;
  height: 3px;
  border-radius: 2px;
  background: var(--olive);
  opacity: 0.8;
  transform-origin: left center;
  transform: scaleX(var(--left, 1));
  pointer-events: none;
}

:root[data-theme="dark"] .piece::after {
  background: var(--lime);
}

.piece.urgent::after {
  background: var(--ember);
  opacity: 1;
}

.piece.piece-flags::after {
  left: 6px;
  right: 6px;
}

.piece.dragging::after,
.piece.returning::after {
  opacity: 0.35;
}

/* Held: lifted closer to the eye and tilted as it's swung (both set in the
   transform by GameRound#_holdAt, about the finger). */
.piece.dragging {
  cursor: grabbing;
  z-index: 50;
}

.piece.dragging .piece-shape-svg {
  filter:
    drop-shadow(0 2px 3px rgba(25, 40, 10, 0.25))
    drop-shadow(0 18px 18px rgba(25, 40, 10, 0.32));
}

/* Released without a place (wrong drop, or back over the lane): it drifts
   back to the lane; a wrong one shakes its head and flushes ember. */
.piece.returning {
  transition: transform 280ms var(--ease-out);
  animation: piece-reject 380ms ease-out;
}

.piece.returning .piece-outline {
  fill: var(--ember-tint);
  stroke: var(--ember);
}

@keyframes piece-reject {
  0%   { translate: 0 0; }
  18%  { translate: -5px 0; }
  38%  { translate: 5px 0; }
  58%  { translate: -3px 0; }
  78%  { translate: 1.5px 0; }
  100% { translate: 0 0; }
}

/* Nearly gone: the shape warms to ember and the slip flutters, as if a
   draught taking it off the page has picked up. */
.piece.urgent:not(.dragging):not(.returning) {
  animation: slip-flutter 640ms ease-in-out infinite;
}

.piece.urgent:not(.dragging):not(.returning) .piece-outline {
  fill: var(--ember);
  stroke: var(--ink);
}

@keyframes slip-flutter {
  0%, 100% { translate: 0 0; }
  25%      { translate: 0.5px -1.5px; }
  75%      { translate: -0.5px 1.5px; }
}

/* A placed slip flying onto its country (GameRound#_flyHome). */
.piece.flying {
  z-index: 40;
  animation: none;
  transition: none;
  pointer-events: none; /* it must not eat the taps and drops meant for the map it is landing on */
}

/* Flags mode: the flag itself floats by, in its true proportions. A hairline
   follows the flag's own edge (Nepal isn't a rectangle; Japan's field is
   white) and a soft shadow lifts it off the map. */
.piece.piece-flags {
  gap: 4px;
  padding: 6px;
  min-width: 0;
}

.piece-flag {
  display: block;
  filter:
    drop-shadow(0 0 0.6px var(--flag-edge))
    drop-shadow(0 0 0.6px var(--flag-edge))
    drop-shadow(0 2px 3px rgba(25, 40, 10, 0.3));
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  transition: filter 0.15s;
}

.piece.piece-flags:hover .piece-flag,
.piece.piece-flags.dragging .piece-flag {
  filter:
    drop-shadow(0 0 1px var(--lime-deep))
    drop-shadow(0 0 1px var(--lime-deep))
    drop-shadow(0 10px 14px rgba(25, 40, 10, 0.4));
}

.piece.piece-flags.urgent:not(.dragging):not(.returning) .piece-flag {
  filter:
    drop-shadow(0 0 1.2px var(--ember))
    drop-shadow(0 0 1.2px var(--ember))
    drop-shadow(0 2px 3px rgba(25, 40, 10, 0.3));
}

/* A wrong drop: the flag's edge flashes ember as it floats back. */
.piece.piece-flags.returning {
  animation: flag-reject 380ms ease-out;
}

@keyframes flag-reject {
  18% { translate: -5px 0; }
  38% { translate: 5px 0; }
  58% { translate: -3px 0; }
  78% { translate: 1.5px 0; }
}

.piece.piece-flags.returning .piece-flag {
  filter:
    drop-shadow(0 0 1.3px var(--ember))
    drop-shadow(0 0 1.3px var(--ember))
    drop-shadow(0 2px 3px rgba(25, 40, 10, 0.3));
}

/* Capitals mode: a city marker at the capital's real spot. */
.piece-capital-ring {
  fill: #ffffff;
  stroke: var(--olive-deep);
  stroke-width: 1.6;
}

.piece-capital-dot {
  fill: var(--olive-deep);
}

.piece.piece-unlabelled {
  padding: 10px;
}

/* Names are plain text with a halo in the ground colour, so they read on the
   frosted lane and over the map alike. */
.piece-label {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 0.84rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--ink);
  white-space: nowrap;
  text-shadow: 0 0 2px var(--ground), 0 0 4px var(--ground), 0 0 8px var(--ground);
  pointer-events: none;
}

/* Capitals mode, easy: the country's name under the capital's. */
.piece-sublabel {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: -2px;
  font-size: 0.72rem;
  line-height: 1.15;
  color: var(--ink-soft);
  white-space: nowrap;
  text-shadow: 0 0 2px var(--ground), 0 0 4px var(--ground), 0 0 8px var(--ground);
  pointer-events: none;
}

/* ---------- Small screens ---------- */

@media (max-width: 720px) {
  .hud-brand span { display: none; }
  #hud .theme-btn { display: none; } /* it's on the menu and pause sheets */
  #hud { gap: 8px; padding: 0 10px; }
  .hud-item { min-width: 0; padding: 0 12px; }
  .hud-progress-item { min-width: 0; }
  .hud-progress { left: 12px; right: 12px; }
  .pause-btn span, .hint-btn span:not(.hint-cost) { display: none; }
  .pause-btn { padding: 8px; min-width: 44px; justify-content: center; }
  .hint-btn { padding: 8px 10px; }
}

@media (max-width: 420px) {
  .sheet { padding: 24px 20px 22px; }
  .choice { padding: 10px; }
  .recap-stat dd, .ticket-value { font-size: 1.45rem; }
  .ticket-score .ticket-value { font-size: 3rem; }
  .ticket-score { min-width: 0; flex: 1 1 100%; }
}

@media (max-height: 780px) {
  .menu-sheet .subtitle { display: none; }
}

@media (max-height: 720px) and (max-width: 559px) {
  .choice-desc { display: none; }
  .sheet { padding-top: 22px; }
  .menu-group { margin-bottom: 14px; }
  .hint { min-height: 0; }
}

/* Short screens (phones in landscape): the sheet runs in two columns so the
   Start button sits above the fold, and the landscape gives way to room. */
@media (max-height: 500px) and (min-width: 560px) {

  .sheet-tools { top: 10px; right: 10px; }

  .menu-sheet {
    max-width: 780px;
    display: grid;
    grid-template-columns: 1fr 1.1fr;
    column-gap: 28px;
    padding: 18px 22px 16px;
  }

  .menu-sheet .sheet-head {
    grid-column: 1;
    grid-row: 1;
    margin-bottom: 10px;
  }

  .menu-sheet .wordmark { margin-bottom: 4px; }

  .menu-sheet .sheet-body {
    display: contents;
  }

  .menu-sheet .menu-group:first-child {
    grid-column: 1;
    grid-row: 2;
    margin-bottom: 0;
  }

  .menu-sheet .menu-group:last-child {
    grid-column: 2;
    grid-row: 1;
    margin-bottom: 8px;
    padding-top: 40px; /* clear of the sound and theme buttons */
  }

  .menu-sheet .sheet-foot {
    grid-column: 2;
    grid-row: 2;
    align-self: start;
  }

  .menu-sheet .choice-desc {
    display: none;
  }

  .menu-sheet .choice { padding: 8px 10px; }

  .continent-picker {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: 8px;
  }

  .continent-picker .choice { padding: 6px 8px; }

  .title { font-size: 1.55rem; }
  .subtitle { font-size: 0.92rem; margin-top: 6px; }

  /* The win sheet too: score on the left, recap and Play again on the right. */
  .win-sheet {
    max-width: 780px;
    display: grid;
    grid-template-columns: 1fr 1.1fr;
    column-gap: 28px;
    align-items: start;
    padding: 18px 22px 16px;
  }

  .win-sheet .recap-stats { margin-bottom: 12px; }
  .tricky { margin-bottom: 14px; }
  .tricky-list li { padding: 4px 0; }

  .hint { min-height: 0; }
  .win-result { margin: 12px 0; }
  .ticket-score .ticket-value { font-size: 2.6rem; }
  .ticket-score { gap: 10px; padding: 12px 20px 14px; }
}

/* ---------- Compact layout (phones during a round) ----------
   Set by src/layout.js as <html data-layout="compact">; the breakpoint lives
   only in LAYOUT.compactQuery (config.js). The map fills the screen below a
   slim HUD and pans/zooms; the lane floats over its bottom edge.
   --lane-height is written by layout.js from LAYOUT. */

[data-layout="compact"] {
  --hud-height: calc(52px + var(--inset-top));
}

/* The panned map is wider than the screen: clip it, or mobile browsers widen
   the layout viewport to fit it. */
[data-layout="compact"],
[data-layout="compact"] #game-screen {
  overflow: hidden;
}

[data-layout="compact"] body {
  overscroll-behavior: none;
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
}

[data-layout="compact"] #hud {
  gap: 6px;
  padding: var(--inset-top) max(8px, var(--inset-right)) 0
    max(8px, var(--inset-left));
}

[data-layout="compact"] .hud-brand {
  display: none;
}

[data-layout="compact"] #hud .theme-btn {
  display: none; /* it's on the menu and pause sheets */
}

[data-layout="compact"] .hud-stats {
  flex: 0 1 auto;
  min-width: 0;
  margin: 0 auto 0 0;
  padding: 3px 2px;
}

[data-layout="compact"] .hud-item {
  min-width: 0;
  min-height: 36px;
  padding: 0 9px;
}

[data-layout="compact"] .hud-progress-item {
  min-width: 0;
}

[data-layout="compact"] .hud-progress {
  left: 9px;
  right: 9px;
  bottom: 1px;
}

[data-layout="compact"] .hud-delta {
  min-width: 1.8em;
}

[data-layout="compact"] .hud-label {
  font-size: 0.66rem;
}

[data-layout="compact"] .hud-value {
  font-size: 0.98rem;
}

[data-layout="compact"] .hud-delta {
  font-size: 0.85rem;
}

[data-layout="compact"] .pause-btn span,
[data-layout="compact"] .hint-btn span:not(.hint-cost) {
  display: none;
}

[data-layout="compact"] .pause-btn {
  min-height: 40px;
  min-width: 40px;
  padding: 8px;
}

[data-layout="compact"] .hint-btn {
  min-height: 40px;
  padding: 8px 10px;
}

/* The lane: a frosted strip laid over the bottom of the map, clear of the
   home indicator and the landscape notch. The map shows through, blurred,
   so land scrolled under it reads as a calm wash instead of ghosting
   sharply behind the slips. pointer-events stay off so a pan can start on
   an empty part of the lane. */
[data-layout="compact"] #lane-track {
  top: auto;
  bottom: var(--inset-bottom);
  left: 0;
  right: 0;
  /* The strip spans the full width; the slips keep clear of a camera
     cut-out or rounded corner at the sides (layout.js measures the lane
     inside this padding). */
  padding: 0 var(--inset-right) 0 var(--inset-left);
  height: var(--lane-height);
  background: var(--lane-glass);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  backdrop-filter: blur(14px) saturate(1.2);
  border-top: 1px solid var(--glass-edge);
  border-bottom: 0;
  border-radius: 22px 22px 0 0;
  box-shadow: 0 -10px 24px -16px rgba(25, 40, 10, 0.4);
}

[data-layout="compact"] #lane-track::after {
  display: none;
}

/* Slips hug their real-size shapes in the compact lane. */
[data-layout="compact"] .piece {
  gap: 1px;
  padding: 6px 8px;
  min-width: 36px;
}

[data-layout="compact"] .piece.piece-flags {
  gap: 3px;
  padding: 4px;
  min-width: 0;
}

[data-layout="compact"] .piece.piece-unlabelled {
  padding: 8px;
}

[data-layout="compact"] .piece-label {
  max-width: 120px;
  font-size: 0.76rem;
}

[data-layout="compact"] .piece-sublabel {
  max-width: 120px;
  font-size: 0.64rem;
}

@font-face {
  font-family: "Expose";
  src: url("fonts/expose-variable.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    transition-duration: 1ms !important;
  }
  /* A 1ms pulse would be invisible: show a steady wash instead. */
  .country.hint-flash {
    animation: none !important;
    fill: var(--amber-wash);
  }
  /* Marks appear fully drawn and stay readable for their lifetime. */
  .mark path,
  .reveal-arrow path {
    animation: none !important;
    stroke-dashoffset: 0;
  }
  .reveal-text {
    animation: none !important;
    opacity: 1;
  }
  .choice.selected .tickbox svg use {
    animation: none !important;
    stroke-dashoffset: 0;
  }
  /* No flutter, snap or staged rows: the states still show (an ember shape
     when urgent, the lime fill on a placed country). */
  .piece.urgent,
  .ink,
  .country-dot.dot-pop,
  #win-tricky li {
    animation: none !important;
  }
}

/* ---------- Moss pass: the landing page's look, in the game ----------
   Dark moss by default, matcha paper on request. Big condensed titles, an
   olive-green gradient for the main action, sheets framed like the landing
   hero (soft studio light, drifting green bokeh). */

html {
  accent-color: var(--accent);
  caret-color: var(--accent);
  scrollbar-color: color-mix(in srgb, var(--accent) 55%, transparent) transparent;
}

.sheet-screen {
  background:
    radial-gradient(ellipse 60% 55% at 50% 45%, color-mix(in srgb, var(--stage-a) 60%, transparent), transparent 80%),
    var(--veil);
}

.sheet {
  max-width: 500px;
  padding: 32px 30px 28px;
  border: 1px solid color-mix(in srgb, var(--ink) 9%, transparent);
  border-radius: 38px;
  background: radial-gradient(ellipse 95% 55% at 50% 0%, var(--stage-a), var(--stage-b));
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  overflow: hidden;
  isolation: isolate;
}

/* drifting bokeh behind the sheet's content */
.sheet::before,
.sheet::after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 230px;
  height: 120px;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--bokeh), transparent 72%);
  rotate: -30deg;
  pointer-events: none;
  animation: bokeh 18s ease-in-out infinite alternate;
}
.sheet::before { right: -70px; top: -34px; }
.sheet::after { left: -80px; bottom: -40px; animation-duration: 24s; animation-delay: -7s; }

@keyframes bokeh {
  from { translate: 0 0; opacity: 0.55; }
  to   { translate: 22px -26px; opacity: 1; }
}

.title {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2.3rem, 8.6vw, 3.2rem);
  line-height: 0.98;
  letter-spacing: 0.004em;
  text-transform: uppercase;
}

.title em {
  font-style: normal;
  font-weight: 800;
  color: var(--accent);
}

.wordmark { font-size: 1rem; }

.menu-group legend {
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* choices: quiet chips that take the accent when picked */
.choice {
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--chip);
}
.choice:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.choice.selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}
.choice-compact { border-radius: 999px; }

/* the main action: olive gradient with a white arrow square */
.start-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 62px;
  padding: 7px 7px 7px 26px;
  border-radius: 16px;
  background: linear-gradient(180deg, #76961f, #4d6813);
  color: #fff;
  font-size: 1.05rem;
  font-weight: 600;
  text-align: left;
  box-shadow: 0 16px 30px -14px rgba(134, 165, 36, 0.75), inset 0 1px 0 rgba(255, 255, 255, 0.28);
}
.start-btn::after {
  content: "";
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 11px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6' fill='none' stroke='%231a2305' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 20px no-repeat;
  transition: transform var(--dur-quick) var(--ease-snap);
}
.start-btn:not(:disabled):hover { background: linear-gradient(180deg, #82a424, #567318); }
.start-btn:not(:disabled):hover::after { transform: translateX(3px); }
.start-btn:disabled { background: var(--chip); color: var(--ink-muted); box-shadow: none; }
.start-btn:disabled::after { opacity: 0.35; }

.secondary-btn {
  border: 1px solid var(--glass-edge);
  border-radius: 16px;
  background: var(--chip);
}
.secondary-btn:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }

/* tickets: the figures are condensed caps; the score is the one olive card */
.recap-stat dd,
.ticket-value {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.7rem;
  letter-spacing: 0.004em;
}
.ticket-score .ticket-value { font-size: 3.4rem; letter-spacing: 0.004em; }
:root[data-theme="dark"] .ticket { background: linear-gradient(160deg, #5b7919, #435d11); color: #fff; }
:root[data-theme="dark"] .ticket-label,
:root[data-theme="dark"] .ticket-value { color: #fff; }

/* the HUD: condensed numerals */
.hud-value {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: 0.01em;
}
.hud-stats { background: color-mix(in srgb, var(--ground) 70%, transparent); }
.pause-btn:hover { background: color-mix(in srgb, var(--accent) 14%, var(--ground)); }

/* slips glow like the landing page's floating countries */
:root[data-theme="dark"] .piece-shape-svg {
  filter: drop-shadow(0 0 5px rgba(190, 208, 84, 0.26)) drop-shadow(0 8px 10px rgba(0, 0, 0, 0.4));
}
:root[data-theme="dark"] .piece.dragging .piece-shape-svg {
  filter: drop-shadow(0 0 8px rgba(190, 208, 84, 0.4)) drop-shadow(0 18px 18px rgba(0, 0, 0, 0.5));
}
:root[data-theme="dark"] .piece-outline { stroke: var(--lime); }
:root[data-theme="dark"] .piece-capital-ring { stroke: var(--lime); }

#lane-track { border-bottom-color: color-mix(in srgb, var(--ink) 9%, transparent); }

@media (max-width: 420px) {
  .recap-stat dd, .ticket-value { font-size: 1.45rem; }
  .ticket-score .ticket-value { font-size: 2.9rem; }
  .sheet { padding: 26px 20px 22px; border-radius: 32px; }
}

@media (max-height: 500px) and (min-width: 560px) {
  .title { font-size: 2rem; }
  .ticket-score .ticket-value { font-size: 2.5rem; }
  .sheet { border-radius: 30px; }
}

/* ---------- Languages (LOC) ---------- */

/* Another language: the English placeholders stay hidden until main.js has
   swapped them (theme-init.js sets the class and lifts it after 3 s anyway). */
html.i18n-pending #app { visibility: hidden; }

/* The language picker: a pill like the sound and theme buttons, the browser's
   own list inside, showing the language's own name. */
.lang-btn {
  padding-right: 14px;
  cursor: pointer;
}
.lang-btn:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.lang-btn select {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  margin: 0;
  padding: 0 2px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.lang-btn select:focus { outline: none; }

/* Long names (Zentralafrikanische Republik) a size smaller on the slip. */
.piece-label { max-width: 220px; }
.piece-label.piece-label-long { font-size: 0.74rem; letter-spacing: -0.01em; }
[data-layout="compact"] .piece-label { max-width: 150px; }
[data-layout="compact"] .piece-label.piece-label-long { font-size: 0.66rem; }
.title { overflow-wrap: break-word; hyphens: auto; }

/* Korean and Chinese: the bundled fonts have no Hangul or Han characters, so
   the system's own fonts take over after them (Latin digits keep the game's
   faces). Capitals and tight tracking mean nothing in these scripts. */
:root:lang(ko) {
  --font: "Hanken Grotesk", "Apple SD Gothic Neo", "Noto Sans KR", "Noto Sans CJK KR", "Malgun Gothic", system-ui, sans-serif;
  --display: "Expose", "Apple SD Gothic Neo", "Noto Sans KR", "Noto Sans CJK KR", "Malgun Gothic", sans-serif;
  word-break: keep-all;
}
:root:lang(zh-HK) {
  --font: "Hanken Grotesk", "PingFang HK", "Noto Sans HK", "Noto Sans CJK HK", "Microsoft JhengHei", system-ui, sans-serif;
  --display: "Expose", "PingFang HK", "Noto Sans HK", "Noto Sans CJK HK", "Microsoft JhengHei", sans-serif;
}
:root:lang(ko) body *,
:root:lang(zh-HK) body * {
  letter-spacing: 0 !important; /* overrides every tracked heading at once */
  text-transform: none !important;
}
:root:lang(ko) .title,
:root:lang(zh-HK) .title { line-height: 1.15; font-weight: 900; }
