/* strava-viz -- palette and layout.
   Series colours come from a validated categorical palette; both light and
   dark steps are selected, not flipped. */

:root {
  color-scheme: light dark;

  --surface-0: #f6f5f2;
  --surface-1: #fcfcfb;
  --surface-2: #efeeea;
  --border: #dedcd5;
  --border-strong: #c6c3b9;

  --text-primary: #0b0b0b;
  --text-secondary: #52514e;
  --text-muted: #7c7a72;

  --series-1: #2a78d6;  /* blue    -- fitness / power */
  --series-2: #eb6834;  /* orange  -- fatigue */
  --series-3: #1baf7a;  /* aqua    -- heart rate */
  --series-4: #eda100;  /* yellow */
  --series-5: #e87ba4;  /* magenta */
  --series-6: #008300;  /* green */
  --series-7: #4a3aa7;  /* violet */
  --series-8: #e34948;  /* red */

  --good: #0ca30c;
  --warning: #fab219;
  --serious: #ec835a;
  --critical: #d03b3b;

  /* Blue ordinal ramp, light mode: never lighter than step 250. */
  --ramp-1: #86b6ef;
  --ramp-2: #5598e7;
  --ramp-3: #3987e5;
  --ramp-4: #256abf;
  --ramp-5: #1c5cab;
  --ramp-6: #184f95;
  --ramp-7: #0d366b;

  --diverge-pos: #2a78d6;
  --diverge-neg: #d03b3b;
  --diverge-mid: #f0efec;

  --grid: #e5e3dd;
  --radius: 10px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --surface-0: #131312;
    --surface-1: #1a1a19;
    --surface-2: #242422;
    --border: #35342f;
    --border-strong: #4a4943;

    --text-primary: #ffffff;
    --text-secondary: #c3c2b7;
    --text-muted: #918f84;

    --series-1: #3987e5;
    --series-2: #d95926;
    --series-3: #199e70;
    --series-4: #c98500;
    --series-5: #d55181;
    --series-6: #008300;
    --series-7: #9085e9;
    --series-8: #e66767;

    --ramp-1: #cde2fb;
    --ramp-2: #9ec5f4;
    --ramp-3: #6da7ec;
    --ramp-4: #3987e5;
    --ramp-5: #256abf;
    --ramp-6: #1c5cab;
    --ramp-7: #184f95;

    --diverge-mid: #383835;
    --grid: #2c2c29;
  }
}

:root[data-theme="dark"] {
  --surface-0: #131312;
  --surface-1: #1a1a19;
  --surface-2: #242422;
  --border: #35342f;
  --border-strong: #4a4943;
  --text-primary: #ffffff;
  --text-secondary: #c3c2b7;
  --text-muted: #918f84;
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;
  --series-5: #d55181;
  --series-6: #008300;
  --series-7: #9085e9;
  --series-8: #e66767;
  --ramp-1: #cde2fb;
  --ramp-2: #9ec5f4;
  --ramp-3: #6da7ec;
  --ramp-4: #3987e5;
  --ramp-5: #256abf;
  --ramp-6: #1c5cab;
  --ramp-7: #184f95;
  --diverge-mid: #383835;
  --grid: #2c2c29;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 15px/1.5 var(--sans);
  background: var(--surface-0);
  color: var(--text-primary);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { line-height: 1.25; margin: 0; font-weight: 600; }
h1 { font-size: 1.15rem; }
h2 { font-size: 1rem; }
h3 { font-size: 0.9rem; }
a { color: var(--series-1); }
.muted { color: var(--text-muted); }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ chrome ----- */

header.top {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: 0.6rem 1rem;
  background: var(--surface-1);
  border-bottom: 1px solid var(--border);
}
header.top .brand { font-weight: 650; margin-right: auto; display: flex; gap: .6rem; align-items: baseline; }
header.top .brand small { color: var(--text-muted); font-weight: 400; }

nav.tabs { display: flex; gap: 2px; flex-wrap: wrap; }
nav.tabs a {
  padding: 0.35rem 0.7rem; border-radius: 999px; text-decoration: none;
  color: var(--text-secondary); font-size: 0.875rem; white-space: nowrap;
}
nav.tabs a:hover { background: var(--surface-2); color: var(--text-primary); }
nav.tabs a[aria-current="page"] {
  background: var(--text-primary); color: var(--surface-1); font-weight: 550;
}

.iconbtn {
  border: 1px solid var(--border); background: var(--surface-1);
  color: var(--text-secondary); border-radius: 8px; cursor: pointer;
  padding: 0.3rem 0.55rem; font-size: 0.85rem;
}
.iconbtn:hover { border-color: var(--border-strong); color: var(--text-primary); }
.iconbtn:disabled { cursor: default; opacity: 0.75; }
/* Width is pinned so "Sync" -> "Syncing…" -> "Updated" does not shuffle the
   header buttons beside it on every state change. */
#sync-btn { min-width: 5.5rem; }
.iconbtn.busy { border-color: var(--border-strong); color: var(--text-primary); }
.iconbtn.busy::before {
  content: ''; display: inline-block; vertical-align: -1px;
  width: 0.62em; height: 0.62em; margin-right: 0.4em;
  border: 1.5px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: sv-spin 0.7s linear infinite;
}
@keyframes sv-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .iconbtn.busy::before { animation-duration: 2.4s; }
}

main { padding: 1rem; max-width: 1500px; margin: 0 auto; }

/* ------------------------------------------------------------- cards ----- */

.grid { display: grid; gap: 0.85rem; }
.grid.cols-2 { grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); }
.grid.cols-3 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

.card {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.85rem 0.9rem 0.6rem;
  min-width: 0;
}
.card > header {
  display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap;
  margin-bottom: 0.15rem;
}
.card > header .sub { color: var(--text-muted); font-size: 0.8rem; }
.card > header .spacer { margin-left: auto; }
.card .note {
  color: var(--text-muted); font-size: 0.78rem; margin: 0.45rem 0 0.2rem;
}

/* --------------------------------------------------------- stat tiles ---- */

.tiles { display: grid; gap: 0.6rem; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.tile {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 0.7rem 0.8rem;
}
.tile .label {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted); display: flex; align-items: center; gap: 0.35rem;
}
.tile .value {
  font-family: var(--mono); font-size: 1.65rem; font-weight: 600;
  line-height: 1.15; margin-top: 0.2rem; font-variant-numeric: tabular-nums;
}
.tile .value small { font-size: 0.8rem; font-weight: 400; color: var(--text-muted); }
.tile .foot { font-size: 0.76rem; color: var(--text-secondary); margin-top: 0.15rem; }

.swatch {
  width: 9px; height: 9px; border-radius: 2px; display: inline-block; flex: none;
}
/* Dashes only read as dashes on something wider than it is tall. */
.swatch.dashed { width: 14px; height: 3px; border-radius: 0; }
.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

.pill {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: 0.72rem; padding: 0.1rem 0.45rem; border-radius: 999px;
  border: 1px solid var(--border-strong); color: var(--text-secondary);
  white-space: nowrap;
}
.pill.good    { border-color: var(--good);     color: var(--good); }
.pill.warning { border-color: var(--warning);  color: var(--text-primary); background: color-mix(in oklab, var(--warning) 18%, transparent); }
.pill.serious { border-color: var(--serious);  color: var(--text-primary); background: color-mix(in oklab, var(--serious) 18%, transparent); }
.pill.critical{ border-color: var(--critical); color: var(--critical); }

/* ------------------------------------------------------------ legend ----- */

.legend {
  display: flex; flex-wrap: wrap; gap: 0.35rem 0.9rem;
  font-size: 0.78rem; color: var(--text-secondary); margin: 0.3rem 0 0.1rem;
}
.legend .item { display: inline-flex; align-items: center; gap: 0.35rem; cursor: default; }
.legend .item.toggle { cursor: pointer; }
.legend .item.off { opacity: 0.35; }
.legend .item b { font-weight: 550; color: var(--text-primary); font-family: var(--mono); }

/* All-time context strip under the PMC. Same visual weight as the legend, but
   these are fixed reference numbers rather than toggles, so no swatches and no
   pointer cursor. */
.reflist {
  display: flex; flex-wrap: wrap; gap: 0.25rem 1.1rem;
  font-size: 0.76rem; color: var(--text-secondary);
  margin: 0.45rem 0 0; padding-top: 0.45rem;
  border-top: 1px solid var(--border);
}
.reflist:empty { display: none; }
.refitem { display: inline-flex; align-items: baseline; gap: 0.3rem; }
.reflabel { color: var(--text-muted); }
.refitem b { font-weight: 550; color: var(--text-primary); font-family: var(--mono); }
.refnote { color: var(--text-muted); font-size: 0.72rem; }

/* ------------------------------------------------------------ charts ----- */

.chart { width: 100%; }
.chart-scroll { overflow-x: auto; }

.uplot { font-family: var(--sans) !important; }
.u-title { color: var(--text-primary); }
.u-legend { display: none; }           /* replaced by our own legend + tooltip */
.u-axis   { color: var(--text-muted); }
.u-select { background: color-mix(in oklab, var(--series-1) 14%, transparent); }
.u-cursor-x, .u-cursor-y { border-color: var(--border-strong) !important; }
.u-cursor-pt { box-shadow: 0 0 0 2px var(--surface-1); }

.tooltip {
  position: absolute; z-index: 50; pointer-events: none;
  background: var(--surface-1); color: var(--text-primary);
  border: 1px solid var(--border-strong); border-radius: 8px;
  padding: 0.4rem 0.55rem; font-size: 0.78rem; line-height: 1.4;
  box-shadow: 0 4px 14px rgb(0 0 0 / 0.14); min-width: 130px;
}
.tooltip .t-date { color: var(--text-muted); margin-bottom: 0.2rem; }
.tooltip .t-row { display: flex; gap: 0.5rem; align-items: center; }
.tooltip .t-row .name { color: var(--text-secondary); }
.tooltip .t-row .val { margin-left: auto; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.tooltip .t-total { margin-top: 0.2rem; padding-top: 0.2rem; border-top: 1px solid var(--border); }
.tooltip .t-total .name { color: var(--text-primary); }

/* --------------------------------------------------------- controls ------ */

.controls {
  display: flex; flex-wrap: wrap; gap: 0.4rem 0.55rem; align-items: center;
  margin-bottom: 0.85rem;
}
/* A long segmented group (eight years of the calendar) scrolls inside itself
   rather than pushing the page sideways. */
.controls .group {
  display: flex; gap: 2px; background: var(--surface-2); padding: 2px;
  border-radius: 8px; max-width: 100%; overflow-x: auto;
}
.controls .group button { flex: 0 0 auto; }
.controls button, .controls select, .controls input[type="search"], .controls input[type="date"] {
  font: inherit; font-size: 0.83rem;
  border: 1px solid transparent; background: transparent;
  color: var(--text-secondary); border-radius: 6px; padding: 0.25rem 0.6rem;
  cursor: pointer;
}
.controls select, .controls input[type="search"], .controls input[type="date"] {
  border-color: var(--border); background: var(--surface-1); cursor: auto;
}
.controls .group button[aria-pressed="true"] {
  background: var(--surface-1); color: var(--text-primary); font-weight: 550;
  border-color: var(--border);
}
.controls button:hover { color: var(--text-primary); }
.controls label { font-size: 0.8rem; color: var(--text-muted); }

/* ----------------------------------------------------------- tables ------ */

.table-wrap { overflow-x: auto; }
table.data {
  width: 100%; border-collapse: collapse; font-size: 0.83rem;
}
table.data th, table.data td {
  padding: 0.35rem 0.5rem; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
table.data th:first-child, table.data td:first-child,
table.data th.left, table.data td.left { text-align: left; }
table.data thead th {
  position: sticky; top: 0; background: var(--surface-1); z-index: 1;
  color: var(--text-muted); font-weight: 550; font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: 0.03em; cursor: pointer;
  border-bottom: 1px solid var(--border-strong);
}
table.data thead th.nosort { cursor: default; }
table.data tbody tr:hover { background: var(--surface-2); }
table.data td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }
table.data tbody tr { cursor: pointer; }
table.data .name-cell { max-width: 26ch; overflow: hidden; text-overflow: ellipsis; }

/* Progression strip. Rows are not links, so they lose the pointer that
   table.data hands out by default. */
table.data.progress tbody tr { cursor: default; }
table.data.progress td { padding-top: 0.45rem; padding-bottom: 0.45rem; }
table.data.progress td.left { font-weight: 550; }
table.data.progress td.strong { font-size: 1.05rem; font-weight: 600; }
table.data.progress small { color: var(--text-muted); font-weight: 400; }

/* Direction is carried by colour and by the sign in the text, never by colour
   alone -- the sign is already there in fmtSigned, which is what a red/green
   pair has to fall back on.

   Card-scoped rather than --good/--critical: those two are tuned for the pills,
   which set them as a background behind dark text, and as 0.83rem foreground
   text they land at 3.1:1 (good on light) and 2.9:1 (critical on dark). Both are
   under 4.5:1. Retuning the globals would repaint every pill on the site, so the
   contrast is fixed here where the text lives. */
table.data.progress { --delta-up: #0a7d0a; --delta-down: #b32d2d; }
:root[data-theme="dark"] table.data.progress { --delta-up: #4ec94e; --delta-down: #f08a8a; }

table.data.progress td.delta.up { color: var(--delta-up); }
table.data.progress td.delta.down { color: var(--delta-down); }
table.data.progress td.delta.flat { color: var(--text-muted); }
table.data.progress td.delta.up small,
table.data.progress td.delta.down small { color: inherit; opacity: 0.85; }

table.data.progress td.sparkcell { width: 108px; padding-right: 0.5rem; }
/* currentColor on the polyline, so one declaration themes the whole thing. */
table.data.progress .spark { color: var(--series-1); display: block; }

table.data.progress .lbl-short { display: none; }

@media (max-width: 700px) {
  /* Trend and best-ever go first: both are context, while the two change
     columns are the entire point of the card and must survive to 390 px. */
  table.data.progress th:nth-child(6), table.data.progress td:nth-child(6) { display: none; }
}
@media (max-width: 560px) {
  table.data.progress th:nth-child(5), table.data.progress td:nth-child(5) { display: none; }
  table.data.progress .lbl-full { display: none; }
  table.data.progress .lbl-short { display: inline; }
  table.data.progress th, table.data.progress td { padding-left: 0.3rem; padding-right: 0.3rem; }
  table.data.progress td.strong { font-size: 1rem; }
}

/* Climb list: no column sorts, and a row selects a stretch of the map rather
   than navigating, so only the linkable variant gets a pointer. */
table.data.climbs thead th { cursor: default; }
table.data.climbs tbody tr { cursor: default; }
table.data.climbs.pick tbody tr { cursor: pointer; }
table.data.climbs tbody tr.sel {
  background: var(--surface-2); box-shadow: inset 3px 0 0 var(--series-8);
}

/* --------------------------------------------------------- calendar ------ */

.cal { display: flex; flex-direction: column; gap: 0.4rem; }
.cal-grid {
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(7, 12px);
  gap: 2px; overflow-x: auto; padding-bottom: 0.2rem;
}
.cal-cell { width: 12px; height: 12px; border-radius: 2px; background: var(--surface-2); }
.cal-cell[data-l="0"] { background: var(--surface-2); }
.cal-cell[data-l="1"] { background: var(--ramp-1); }
.cal-cell[data-l="2"] { background: var(--ramp-2); }
.cal-cell[data-l="3"] { background: var(--ramp-3); }
.cal-cell[data-l="4"] { background: var(--ramp-4); }
.cal-cell[data-l="5"] { background: var(--ramp-5); }
.cal-cell[data-l="6"] { background: var(--ramp-6); }
.cal-months { display: flex; gap: 2px; font-size: 0.68rem; color: var(--text-muted); }

/* ---------------------------------------------------------- details ------ */

dl.kv {
  display: grid; grid-template-columns: auto 1fr; gap: 0.2rem 0.8rem;
  margin: 0; font-size: 0.85rem;
}
dl.kv dt { color: var(--text-muted); }
dl.kv dd { margin: 0; font-family: var(--mono); font-variant-numeric: tabular-nums; }

.bars { display: flex; flex-direction: column; gap: 3px; }
.bar-row { display: grid; grid-template-columns: 8.5rem 1fr 5.5rem; gap: 0.5rem; align-items: center; font-size: 0.8rem; }
.bar-track { background: var(--surface-2); border-radius: 3px; height: 14px; overflow: hidden; }
/* display:block matters — the fill is a span, and width does nothing inline. */
.bar-fill { display: block; height: 100%; border-radius: 3px; }
.bar-row .v { text-align: right; font-family: var(--mono); color: var(--text-secondary); }

/* ------------------------------------------------------------ login ------ */

body.login-page { display: grid; place-items: center; min-height: 100vh; }
.login-card {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1.6rem; width: min(340px, 90vw);
}
.login-card h1 { margin-bottom: 0.2rem; }
.login-card form { display: grid; gap: 0.4rem; margin-top: 1rem; }
.login-card label { font-size: 0.78rem; color: var(--text-muted); }
.login-card input {
  font: inherit; padding: 0.45rem 0.6rem; border-radius: 8px;
  border: 1px solid var(--border-strong); background: var(--surface-0);
  color: var(--text-primary);
}
.login-card button {
  font: inherit; font-weight: 550; padding: 0.45rem; border-radius: 8px;
  border: none; background: var(--text-primary); color: var(--surface-1);
  cursor: pointer; margin-top: 0.3rem;
}
.error { color: var(--critical); font-size: 0.85rem; }

/* -------------------------------------------------------- utilities ----- */

.spinner { color: var(--text-muted); font-size: 0.85rem; padding: 1.5rem 0; text-align: center; }
.row { display: flex; gap: 0.6rem; align-items: center; flex-wrap: wrap; }
.hide { display: none !important; }
.prose { max-width: 68ch; margin: 0 auto; font-size: 0.9rem; }
.prose h2 { margin: 1.4rem 0 0.4rem; }
.prose h3 { margin: 1rem 0 0.25rem; }
.prose p, .prose li { color: var(--text-secondary); }
.prose code {
  font-family: var(--mono); font-size: 0.85em; background: var(--surface-2);
  padding: 0.05rem 0.3rem; border-radius: 4px; color: var(--text-primary);
}
.prose .ref { font-size: 0.82rem; }

@media (max-width: 620px) {
  .grid.cols-2, .grid.cols-3 { grid-template-columns: 1fr; }
  main { padding: 0.6rem; }
  .tile .value { font-size: 1.35rem; }
}

/* ----------------------------------------------------------- weight ------ */

/* Table wide, form narrow, and the form stays put while the list scrolls. */
.grid.weightgrid { grid-template-columns: minmax(0, 1.6fr) minmax(280px, 1fr); }
.weightgrid > .card:last-child { align-self: start; position: sticky; top: 0.6rem; }

.weightform {
  display: grid; gap: 0.55rem; grid-template-columns: 1fr 1fr;
  margin-top: 0.5rem;
}
.weightform label { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.weightform label.wide, .weightform .formactions { grid-column: 1 / -1; }
.weightform label > span {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted);
}
.weightform input, .weightform select {
  font: inherit; font-size: 0.85rem; min-width: 0;
  border: 1px solid var(--border); background: var(--surface-0);
  color: var(--text-primary); border-radius: 6px; padding: 0.3rem 0.45rem;
}
.weightform input:focus-visible, .weightform select:focus-visible {
  outline: 2px solid var(--border-strong); outline-offset: 1px;
}
.weightform .row { gap: 0.35rem; }
.weightform .row input { flex: 1 1 5rem; }
.weightform .row select { flex: 0 0 auto; }
.weightform .formactions { display: flex; gap: 0.5rem; margin-top: 0.15rem; }

.btn {
  font: inherit; font-size: 0.83rem; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface-1);
  color: var(--text-secondary); border-radius: 6px; padding: 0.3rem 0.7rem;
}
.btn:hover:not(:disabled) { border-color: var(--border-strong); color: var(--text-primary); }
.btn:disabled { opacity: 0.5; cursor: default; }
.btn.primary {
  border-color: var(--border-strong); color: var(--text-primary); font-weight: 550;
}
.btn.small { font-size: 0.75rem; padding: 0.12rem 0.4rem; }

/* 143 monthly weigh-ins is a very long page, and the notes under the table are
   worth reading, so scroll the rows instead of the document. thead is already
   sticky, so the header stays put inside it. */
.weightgrid .table-wrap { max-height: 62vh; overflow-y: auto; }

/* Two buttons per row, so the row itself must not also be a link target. */
.weightgrid table.data tbody tr { cursor: default; }
td.rowbtns { display: flex; gap: 0.3rem; justify-content: flex-end; }

/* Green for down, amber for up. This does assume losing is the direction you
   want, which is the whole reason a cyclist tracks mass against FTP; it is a
   hint on a column that already carries a sign, not a verdict. */
table.data td.up { color: var(--warning); }
table.data td.down { color: var(--good); }

.formnote {
  font-size: 0.78rem; margin: 0.5rem 0 0.1rem; color: var(--text-muted);
  min-height: 1.2em;
}
.formnote.ok { color: var(--good); }
.formnote.warn { color: var(--warning); }
.formnote.bad { color: var(--critical); }

@media (max-width: 820px) {
  .grid.weightgrid { grid-template-columns: 1fr; }
  /* Sticky inside a single column would pin the form over the table. */
  .weightgrid > .card:last-child { position: static; }
}

/* -------------------------------------------------------------- maps ----- */

.map {
  width: 100%; height: 380px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2);
  /* Leaflet puts panes and controls at z-index 400-1000; a stacking context
     here keeps them under the site header instead of over it. */
  isolation: isolate;
}

/* Leaflet ships its own font stack and a white chrome. Its stylesheet is
   injected at first use, so it lands after this file and wins on source order;
   the extra `.map` in each selector is what puts these back on top. */
.map.leaflet-container { font-family: var(--sans); font-size: 0.75rem; }
.map .leaflet-bar a,
.map .leaflet-control-attribution {
  background: var(--surface-1); color: var(--text-secondary);
  border-color: var(--border);
}
.map .leaflet-bar a:hover { background: var(--surface-2); color: var(--text-primary); }
.map .leaflet-control-attribution a { color: var(--series-1); }

@media (max-width: 620px) {
  .map { height: 260px; }
}

/* OSM only publishes a light raster style. Inverting the tile pane is the
   standard trick: invert, then rotate the hue back so water is blue again
   rather than orange. Applied to the tiles alone, so the route and its
   markers keep their own colours. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .leaflet-tile-pane {
    filter: invert(1) hue-rotate(180deg) brightness(0.92) contrast(0.9);
  }
}
:root[data-theme="dark"] .leaflet-tile-pane {
  filter: invert(1) hue-rotate(180deg) brightness(0.92) contrast(0.9);
}
