/* ============================================================
   kangomo — core styles

   Visual world: CONTROL DESCRIPTION (IOF orienteering notation).
   The ground is the terrain map — pale, printed, legible in sun.
   The overprint magenta is reserved BY LAW for the race: anything
   magenta is live race data and nothing else ever borrows it.
   Everything is ruled and square; only control symbols are round.

   Page-specific styles: pages/faq.css, pages/about.css, pages/map.css
   ============================================================ */

@import url('./pages/faq.css');
@import url('./pages/about.css');
@import url('./pages/map.css');
@import url('./components/footer.css');
@import url('./components/sidebar.css');
@import url('./components/map.css');


/* ── Reset ─────────────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* ── Design tokens ─────────────────────────────────────────── */
:root {
  /* ══ PALETTE ══════════════════════════════════════════════
     Three hues, warm-led, matched in chroma, ranked by area.

     Colours fit together when they share lightness and chroma —
     not when they are quiet. So these are full-strength and they
     still agree: amber and flame are neighbours, indigo is the
     counterweight that gives the warm pair somewhere to sit.
     Boldness comes from the hues; calm comes from the hierarchy,
     which is strict — indigo holds the structure, amber holds the
     fields, flame is scarce and always means the race.

     Three earlier passes failed here and the reasons are worth
     keeping. The ISOM symbol set as UI colour (yellow, green,
     cyan, magenta, brown) mixed a 100%-chroma yellow with a mid
     green and a dark brown: different hue, lightness and chroma
     all at once, so nothing was subordinate to anything. Bister
     brown with a crimson overprint was warm against warm, a few
     steps apart, and read as mud. A cool bone-and-pine field with
     one hot signal held together but went cold.

     The binding constraint behind all of it: route colours come
     from the organiser through the API and can be any hue. The
     chrome is a frame around colours it cannot predict, so it
     keeps its own three and ranks them hard. */

  /* Ground — warm off-white. Not white, not brown, not grey. */
  --ground:        #F5F1E7;
  --ground-2:      #EBE5D6;   /* recessed / hover */
  --ground-3:      #DED6C2;
  --sheet:         #FDFBF6;   /* floats above the sheet: panels, popups */

  /* Indigo — structure. Navbar, footer, table head, contours, rules.
     Deep enough to read as rich rather than cold. */
  --indigo:        #1B2A4A;   /* 12.6:1 on ground */
  --indigo-deep:   #101A30;
  --indigo-2:      #46536E;   /*  6.9:1 */
  --indigo-tint:   #D3DAE6;

  /* Amber — the fields. Large areas, so it carries the warmth. */
  --amber:         #E8A020;   /* ink on amber is 8.1:1 */
  --amber-ink:     #8A5D00;   /*  5.1:1 on ground — amber that may carry text */
  --amber-tint:    #F5E4BE;
  --amber-tint-2:  #EBD3A0;
  --amber-tint-3:  #DFC085;

  /* Flame — the race, the brand mark, the primary action.
     The scarcest colour and the only one that means something. */
  --flame:         #E8432B;
  --flame-ink:     #B32A15;   /*  5.7:1 on ground — flame that may carry text */
  --flame-wash:    #FBDFD8;
  --flame-edge:    #F2A08F;

  /* Ink — warm near-black, so it belongs to the ground. */
  --ink:           #1C1A17;   /* 15.4:1 on ground */
  --ink-2:         #4A453C;   /*  7.9:1 */
  --ink-3:         #626A5C;   /*  4.9:1 — the floor for body text */
  --rule:          #DCD5C4;
  --rule-mid:      #B5AE9E;
  --rule-strong:   #857E6E;

  /* Race state. Encoded twice, always: mark + colour. */
  --state-live:    var(--flame);
  --state-stale:   var(--amber-ink);   /* a warning that is not the race */
  --state-offline: #9A9384;

  /* ── Spacing — strict 4pt grid, nothing off it ──────────── */
  --space-xs:   4px;
  --space-sm:   8px;
  --space-md:  16px;
  --space-lg:  24px;
  --space-xl:  32px;
  --space-2xl: 48px;
  --space-3xl: 64px;

  /* Printed maps have no rounded rectangles. Only symbols are round. */
  --radius: 0;

  /* ── Layout ──────────────────────────────────────────────── */
  --header-height: 64px;

  /* ── Type — one family, the width axis doing the work ─────
     Display runs wide, data runs semi-condensed so the
     leaderboard fits more columns without shrinking below
     a readable size. */
  --font:      'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --wd-display: 116%;
  --wd-ui:      100%;
  --wd-data:     88%;

  /* Motion: the overprint being drawn onto the map. */
  --ease-draw: cubic-bezier(0.16, 1, 0.3, 1);

  font-family: var(--font);
  font-size: 14px;
  color: var(--ink);
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  background: var(--ground);
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* ── Browser surfaces — themed, not left to the UA ───────── */
::selection {
  background: var(--flame-wash);
  color: var(--flame-ink);
}

:where(input, textarea) { caret-color: var(--flame); }

:where(a, button, input, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--flame);
  outline-offset: 2px;
}

a { text-underline-offset: 0.18em; text-decoration-thickness: 1px; }

* { scrollbar-width: thin; scrollbar-color: var(--rule-mid) transparent; }

*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--rule-mid);
  border: 3px solid var(--ground);
}
*::-webkit-scrollbar-thumb:hover { background: var(--rule-strong); }

/* ── App shell ───────────────────────────────────────────── */
.app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh; /* mobile: 100vh includes the area under the address bar, pushing bottom UI (leaderboard/elevation toggle) off-screen until it scrolls away */
  overflow: hidden;
}

/* ══════════════════════════════════════════════════════════
   NAVBAR — the map's title bar. A ruled margin, not a slab.
   ══════════════════════════════════════════════════════════ */
.navbar {
  height: var(--header-height);
  background: var(--indigo);
  border-bottom: none;
  display: flex;
  align-items: center;
  padding: 0 var(--space-xl);
  gap: var(--space-xl);
  flex-shrink: 0;
  z-index: 100;
}

.navbar__logo {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  flex-shrink: 0;
}

/* The ISOM start symbol: an equilateral triangle, overprint magenta,
   pointing along the first leg. It is the mark. */
.navbar__mark {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  display: block;
  overflow: visible;
}

.navbar__mark polygon {
  fill: none;
  stroke: var(--flame);
  stroke-width: 2.1;
  stroke-linejoin: round;
}

.navbar__wordmark {
  font-size: 25px;
  font-weight: 700;
  font-stretch: var(--wd-display);
  letter-spacing: -0.022em;
  color: var(--ground);
  line-height: 1;
}

/* ── Nav links — legend entries ──────────────────────────── */
.nav {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  flex: 1;
}

.nav__link {
  padding: 4px 0;
  font-size: 13px;
  font-weight: 500;
  color: #96A0B4;
  text-decoration: none;
  white-space: nowrap;
  letter-spacing: 0.01em;
  border-bottom: 2px solid transparent;
  transition: color 0.14s var(--ease-draw), border-color 0.14s var(--ease-draw);
}

.nav__link:hover { color: var(--ground); border-bottom-color: #3C4A66; }

.nav__link--active {
  color: var(--ground);
  font-weight: 700;
  border-bottom-color: var(--flame);
}

/* ── Language switcher ──────────────────────────────────────── */
.lang-switch {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  border: 1px solid #3C4A66;
}

.lang-switch__btn {
  padding: 5px 10px;
  font-size: 11px;
  font-weight: 600;
  font-stretch: var(--wd-data);
  letter-spacing: 0.06em;
  font-family: inherit;
  color: #96A0B4;
  background: transparent;
  border: none;
  cursor: pointer;
  transition: color 0.14s, background 0.14s;
}

.lang-switch__btn + .lang-switch__btn { border-left: 1px solid #3C4A66; }

.lang-switch__btn:hover { color: var(--ground); }

.lang-switch__btn--active {
  color: var(--indigo);
  background: var(--ground);
}

/* ── Map loading overlay ─────────────────────────────────── */
.map-loading-overlay {
  position: absolute;
  inset: 0;
  z-index: 2000;
  background: rgb(255 255 255 / 0.88);
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(2px);
}

.map-loading-overlay[hidden] { display: none; }

.map-loading-overlay__text {
  font-size: 13px;
  font-weight: 600;
  font-stretch: var(--wd-data);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--flame-ink);
}

/* ── Main / page shell ───────────────────────────────────── */
.main {
  flex: 1;
  overflow: hidden;
  position: relative;
  background: var(--ground);
}

.page {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  overflow: hidden;
}

.page--active { display: flex; }

.content-page {
  overflow-y: auto;
  flex-direction: column;
}

.content-page__inner {
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
  flex: 1 0 auto; /* short pages still push the footer to the bottom */
  padding: var(--space-2xl) var(--space-xl) var(--space-3xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl);
}

/* ══════════════════════════════════════════════════════════
   HOME — the course sheet.

   The first viewport is an orienteering course drawn over
   terrain, and its controls are the real live events. The
   product's mechanism is the page, not a picture of the page.
   ══════════════════════════════════════════════════════════ */

#page-home { overflow-y: auto; }

.course {
  position: relative;
  min-height: calc(100dvh - var(--header-height));
  flex: none;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: end;
  overflow: hidden;
  background: var(--ground);
  isolation: isolate;
}

/* Terrain and overprint are both full-bleed layers of the same sheet. */
.course__terrain,
.course__overprint {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.course__overprint { z-index: 1; }
.course__overprint .ctrl { pointer-events: auto; }

/* The margin block — a map's title panel, printed on the sheet. */
.course__margin {
  position: relative;
  z-index: 2;
  margin: var(--space-2xl) var(--space-xl);
  max-width: 33rem;
  background: var(--sheet);
  border: 2px solid var(--ink);
  padding: var(--space-xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.course__scale {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  font-size: 10px;
  font-weight: 600;
  font-stretch: var(--wd-data);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--rule);
}

.course__title {
  font-size: clamp(34px, 5.2vw, 60px);
  font-weight: 700;
  font-stretch: var(--wd-display);
  color: var(--ink);
  letter-spacing: -0.035em;
  line-height: 0.98;
  text-wrap: balance;
}

.course__sub {
  font-size: 15px;
  color: var(--ink-2);
  line-height: 1.6;
  max-width: 40ch;
}

/* The live read-out: real counts, straight off the API. */
.course__legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md) var(--space-lg);
  padding-top: var(--space-md);
  border-top: 1px solid var(--rule);
}

/* Nothing running: the sheet says so plainly rather than showing a zero. */
.course__legend--empty {
  display: block;
  font-size: 13px;
  color: var(--ink-3);
  max-width: 40ch;
}

.course__legend-note {
  flex: 1 0 100%;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 44ch;
}

.course__legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-2);
}

.course__legend-item svg { flex-shrink: 0; display: block; }

.course__legend-n {
  font-size: 17px;
  font-weight: 700;
  font-stretch: var(--wd-display);
  color: var(--ink);
  line-height: 1;
}

.course__cta { display: flex; gap: var(--space-sm); flex-wrap: wrap; }

/* A finished course is printed in ink. The overprint colour means a race is
   running, so a course nobody is on may not borrow it. */
.course__overprint--past .ctrl__ring,
.course__overprint--past .leg,
.course__overprint--past .course__start polygon,
.course__overprint--past .course__finish circle { stroke: var(--ink); }

.course__overprint--past .ctrl__num { fill: var(--ink); }

.course__overprint--past .ctrl:hover .ctrl__ring,
.course__overprint--past .ctrl:focus-visible .ctrl__ring { stroke: var(--flame); }

/* ── Control symbols on the hero course ──────────────────── */
.ctrl__ring {
  fill: none;
  stroke: var(--flame);
  stroke-width: 2.4;
  cursor: pointer;
}

.ctrl__hit { fill: transparent; cursor: pointer; }

.ctrl__num {
  font-family: var(--font);
  font-size: 15px;
  font-weight: 700;
  font-stretch: var(--wd-display);
  fill: var(--flame-ink);
  paint-order: stroke;
  stroke: var(--ground);
  stroke-width: 4;
  stroke-linejoin: round;
  pointer-events: none;
}

.ctrl__name {
  font-family: var(--font);
  font-size: 12px;
  font-weight: 600;
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--ground);
  stroke-width: 4.5;
  stroke-linejoin: round;
  pointer-events: none;
}

.ctrl:hover .ctrl__ring,
.ctrl:focus-visible .ctrl__ring { stroke-width: 4; }

.ctrl:focus-visible { outline: none; }
.ctrl:focus-visible .ctrl__hit { stroke: var(--ink); stroke-width: 1.5; stroke-dasharray: 3 3; }

.leg {
  fill: none;
  stroke: var(--flame);
  stroke-width: 2.4;
}

/* The one authored motion: the course being overprinted onto
   the terrain, the way a course is drawn onto a printed map. */
.course--draw .leg {
  stroke-dasharray: var(--len);
  stroke-dashoffset: var(--len);
  animation: overprint-draw 0.9s var(--ease-draw) forwards;
  animation-delay: var(--delay, 0s);
}

.course--draw .ctrl,
.course--draw .course__start,
.course--draw .course__finish {
  opacity: 0;
  animation: overprint-ink 0.34s var(--ease-draw) forwards;
  animation-delay: var(--delay, 0s);
}

@keyframes overprint-draw { to { stroke-dashoffset: 0; } }
@keyframes overprint-ink  { to { opacity: 1; } }

.course__start polygon,
.course__finish circle {
  fill: none;
  stroke: var(--flame);
  stroke-width: 2.4;
}

/* ── Buttons ─────────────────────────────────────────────── */
.btn-primary {
  padding: 12px 22px;
  background: var(--flame);
  color: #fff;
  border: 1px solid var(--flame);
  font-size: 12px;
  font-weight: 700;
  font-stretch: var(--wd-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: background 0.14s var(--ease-draw), color 0.14s var(--ease-draw);
}

.btn-primary:hover { background: var(--flame-ink); border-color: var(--flame-ink); }

.btn-secondary {
  padding: 12px 22px;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--rule-mid);
  font-size: 12px;
  font-weight: 700;
  font-stretch: var(--wd-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  transition: border-color 0.14s, background 0.14s;
}

.btn-secondary:hover { border-color: var(--ink); background: var(--ground-2); }

/* ── Content page shared base — a sheet header ───────────── */
.cp-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding-bottom: var(--space-md);
  border-bottom: 2px solid var(--ink);
}

.cp-title {
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 700;
  font-stretch: var(--wd-display);
  color: var(--ink);
  letter-spacing: -0.03em;
  line-height: 1.02;
}

.cp-subtitle {
  font-size: 14px;
  color: var(--ink-2);
  max-width: 62ch;
}

/* ── Statistics page ─────────────────────────────────────── */
.stats-page {
  padding: var(--space-xl);
  overflow-y: auto;
  flex-direction: column;
  gap: var(--space-xl);
}

.stats-panel__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 0;
  border: 1px solid var(--rule);
}

.stats-kpi {
  background: var(--ground);
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.stats-kpi__label {
  font-size: 10px;
  font-weight: 600;
  font-stretch: var(--wd-data);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.stats-kpi__value {
  font-size: 34px;
  font-weight: 700;
  font-stretch: var(--wd-display);
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.03em;
}

.stats-kpi__unit {
  font-size: 13px;
  font-weight: 400;
  font-stretch: var(--wd-ui);
  color: var(--ink-3);
  margin-left: 3px;
}

.stats-panel__chart-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
}

.chart-card {
  background: var(--ground);
  border: 1px solid var(--rule);
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.chart-card__title {
  font-size: 10px;
  font-weight: 600;
  font-stretch: var(--wd-data);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.chart-card__canvas {
  position: relative;
  width: 100%;
  height: 200px;
  background: var(--ground-2);
  overflow: hidden;
}

.chart-card__canvas canvas { display: block; }

/* ═══════════════════════════════════════════════════════════
   MOBILE / RESPONSIVE  ≤ 767 px
   ═══════════════════════════════════════════════════════════ */
@media (max-width: 767px) {
  :root { --header-height: 54px; }

  .navbar {
    padding: 0 var(--space-md);
    gap: var(--space-md);
  }
  .navbar__wordmark { font-size: 19px; }
  .navbar__mark { width: 17px; height: 17px; }
  .nav { gap: var(--space-md); }
  .nav__link { font-size: 12px; letter-spacing: 0; }
  .lang-switch__btn { padding: 4px 7px; font-size: 10px; }

  .content-page__inner { padding: var(--space-xl) var(--space-md) var(--space-2xl); gap: var(--space-xl); }

  .course__margin {
    margin: var(--space-md);
    padding: var(--space-lg) var(--space-md);
    max-width: none;
  }
  .course__cta { flex-direction: column; align-items: stretch; }
  .btn-primary, .btn-secondary { justify-content: center; }

  /* Portrait keeps the control names: only two or three controls clear the
     margin panel, so naming them is what makes the sheet readable at all. */
  .ctrl__name { font-size: 19px; stroke-width: 6; }
  .ctrl__num  { font-size: 24px; stroke-width: 5; }
  .ctrl__ring, .leg,
  .course__start polygon, .course__finish circle { stroke-width: 3.4; }
}

@media (max-width: 380px) {
  .navbar { gap: var(--space-sm); }
  .navbar__wordmark { font-size: 17px; }
  .nav { gap: 10px; }
  .nav__link { font-size: 11px; }
}

/* ── Reduced motion: the course is already printed ───────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .course--draw .leg { stroke-dashoffset: 0; }
  .course--draw .ctrl,
  .course--draw .course__start,
  .course--draw .course__finish { opacity: 1; }
}
