/* Front-page ("living lake") stylesheet. Only index.html loads this.
 *
 * The design premise: the lake itself is the hero. Its outline is the real
 * lap-01 geometry projected to SVG, drawn as a glowing line on a dark ground,
 * and the live rider dots sit on that same projection — so the page shows the
 * truth before a single tile of a real map loads.
 */

:root {
  color-scheme: dark;
  --ink: #f3eee0;
  --muted: #aab8b2;
  --forest: #102621;
  --forest-deep: #0b1a16;
  --line: rgba(243, 238, 224, 0.16);
  --sun: #efb94f;
  --blue: #8cced2;
  --lap-orange: #f2913d;
  --lap-lime: #b7d356;
}

* { box-sizing: border-box; }

html { background: var(--forest-deep); scroll-behavior: smooth; overflow-x: clip; }

body {
  margin: 0;
  min-height: 100vh;
  overflow-x: hidden;
  color: var(--ink);
  background:
    radial-gradient(ellipse 70rem 40rem at 78% -8%, rgba(140, 206, 210, 0.10), transparent),
    radial-gradient(ellipse 50rem 34rem at 8% 32%, rgba(239, 185, 79, 0.07), transparent),
    var(--forest-deep);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

a { color: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 3px solid var(--sun); outline-offset: 4px; }

.skip-link {
  position: fixed; z-index: 100; top: 10px; left: 10px;
  padding: 10px 14px; color: var(--forest); background: var(--sun);
  border-radius: 999px; text-decoration: none; font-weight: 800;
  transform: translateY(-180%); transition: transform 0.15s ease;
}
.skip-link:focus { transform: translateY(0); }

/* ------------------------------------------------------------------ header */

.site-header {
  width: min(1180px, calc(100% - 40px));
  margin: 0 auto;
  min-height: 82px;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 28px;
  border-bottom: 1px solid var(--line);
}
.brand { text-decoration: none; font-weight: 850; letter-spacing: -0.035em; font-size: 1.08rem; }
.brand span { color: var(--sun); }
.language-switcher { display: flex; gap: 4px; }
.language-switcher button {
  min-width: 44px; min-height: 44px; padding: 0 8px;
  border: 1px solid transparent; border-radius: 999px;
  color: var(--muted); background: transparent;
  font: inherit; font-size: 0.76rem; font-weight: 850; cursor: pointer;
}
.language-switcher button.is-active {
  color: var(--ink); border-color: var(--line); background: rgba(255, 255, 255, 0.06);
}

main { width: min(1180px, calc(100% - 40px)); margin: 0 auto; }

.eyebrow {
  margin: 0 0 14px; color: var(--sun);
  font-size: 0.74rem; font-weight: 850; letter-spacing: 0.14em; text-transform: uppercase;
}

/* --------------------------------------------------------------- lake hero */

.lake-hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: center;
  gap: clamp(28px, 4.5vw, 64px);
  padding: clamp(40px, 7vw, 90px) 0 clamp(30px, 5vw, 60px);
}

.lake-hero::before {
  content: "";
  position: absolute;
  inset: -15% 0 -20%;
  z-index: 0;
  background:
    radial-gradient(ellipse 520px 440px at 26% 48%, rgba(140, 206, 210, 0.13), transparent 70%),
    radial-gradient(ellipse 640px 420px at 48% 62%, rgba(239, 185, 79, 0.09), transparent 75%),
    radial-gradient(ellipse 400px 360px at 78% 46%, rgba(140, 206, 210, 0.06), transparent 70%);
  pointer-events: none;
  filter: blur(28px);
}

.lake-map {
  position: relative;
  z-index: 1;
  margin: -4% -8% -6% -4%;
  width: 112%;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

.lake-map.is-dragging {
  cursor: grabbing;
}

.lake-tiles {
  opacity: 0;
  transition: opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  pointer-events: none;
}

.lake-map.is-active .lake-tiles {
  opacity: 0.38;
}

.lake-tile {
  pointer-events: none;
}

.lake-status {
  position: relative;
  z-index: 2;
  background: rgba(16, 38, 33, 0.65);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(243, 238, 224, 0.14);
  border-radius: 24px;
  padding: clamp(26px, 3.6vw, 42px);
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.45);
}

.lake-map svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 72vh;
  overflow: visible;
  /* Organic atmospheric edge fade dissolving smoothly to 0% transparency well before canvas edges */
  mask-image: radial-gradient(ellipse 78% 74% at 48% 50%, black 35%, rgba(0, 0, 0, 0.8) 50%, rgba(0, 0, 0, 0.35) 65%, transparent 82%);
  -webkit-mask-image: radial-gradient(ellipse 78% 74% at 48% 50%, black 35%, rgba(0, 0, 0, 0.8) 50%, rgba(0, 0, 0, 0.35) 65%, transparent 82%);
}

#lake-ambient-heat,
#lake-heat {
  /* Inner heat layer edge fade to eliminate harsh rectangular tile/grid crops */
  mask-image: radial-gradient(ellipse 74% 70% at 48% 50%, black 35%, rgba(0, 0, 0, 0.75) 50%, rgba(0, 0, 0, 0.25) 65%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 74% 70% at 48% 50%, black 35%, rgba(0, 0, 0, 0.75) 50%, rgba(0, 0, 0, 0.25) 65%, transparent 78%);
}

#lake-ambient-heat {
  opacity: 1;
}

.lake-loop { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.lake-loop--halo { stroke: rgba(140, 206, 210, 0.35); stroke-width: 5; }
.lake-loop--dash {
  stroke: var(--blue);
  stroke-width: 2;
  stroke-dasharray: 7 9;
  /* steps() keeps the main-thread dashoffset repaint at ~3/s instead of 60. */
  animation: lake-flow 60s steps(160) infinite;
}
@keyframes lake-flow { to { stroke-dashoffset: -320; } }

.lake-road {
  fill: none;
  stroke: rgba(140, 206, 210, 0.28);
  stroke-width: 2;
  stroke-dasharray: 4 6;
  opacity: 0;
  transition: opacity 0.6s ease;
}
.is-wide-view .lake-road { opacity: 1; }

.lake-hub-mark circle {
  fill: var(--sun); stroke: var(--forest-deep); stroke-width: 2.5;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.9));
}
.lake-hub-mark text {
  fill: var(--ink); font-size: 15px; font-weight: 800;
  text-anchor: end; letter-spacing: 0.08em;
  paint-order: stroke fill;
  stroke: var(--forest-deep);
  stroke-width: 4px;
  stroke-linejoin: round;
  stroke-linecap: round;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.9));
}
.lake-hub-mark--shop {
  opacity: 0;
  transition: opacity 0.6s ease;
}
.is-wide-view .lake-hub-mark--shop { opacity: 1; }

/* Live rider trails and dots, drawn by hub.js on the same projection. The
   trail is the rider's own track from the live feed, not the seeded heatmap. */
.lake-rider-trail {
  fill: none; stroke-width: 4.5; stroke-linecap: round; stroke-linejoin: round;
  /* A dark casing plus a bloom in the rider's own colour. The casing keeps the
     trail off the heat glow it crosses; the bloom is what makes a live line
     look live next to the static history under it. */
  filter: drop-shadow(0 0 2px rgba(11, 26, 22, 0.95))
          drop-shadow(0 0 7px var(--trail, var(--lap-orange)));
}

/* Live rider dots, drawn by hub.js on the same projection. */
.lake-rider circle {
  stroke: var(--forest-deep); stroke-width: 2.5;
  /* Composited transform pulse; animating the r attribute paints every frame.
     scale(1.29) matches the old 7→9. */
  transform-box: fill-box; transform-origin: center;
  animation: rider-pulse 2.4s ease-in-out infinite;
}
.lake-rider text {
  fill: var(--ink); font-size: 15px; font-weight: 750;
  paint-order: stroke; stroke: var(--forest-deep); stroke-width: 4px;
}
@keyframes rider-pulse { 50% { transform: scale(1.29); } }

.lake-status h1 { margin: 0; line-height: 1; }
.live-count strong {
  display: block;
  font-size: clamp(4.4rem, 12vw, 8.6rem);
  font-weight: 900;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.live-count strong.is-live { color: var(--sun); }
.live-count strong.is-muted { opacity: 0.35; }
.live-count-label {
  display: block; max-width: 18ch; margin-top: 6px;
  font-size: clamp(1.25rem, 2.6vw, 1.8rem); font-weight: 800;
  letter-spacing: -0.02em; text-wrap: balance;
}
.live-detail {
  min-height: 1.5em; max-width: 46ch; margin: 18px 0 0;
  color: var(--muted); line-height: 1.55;
}
.live-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 20px; margin-top: 28px; }
.live-actions [hidden] { display: none; }

.button {
  min-height: 48px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0 22px; border: 0; border-radius: 999px;
  font: inherit; font-weight: 850; text-decoration: none; cursor: pointer;
}
.button--sun { color: var(--forest); background: var(--sun); }
.button--sun:hover { background: #f6ca6d; }
.button--ghost { color: var(--ink); background: transparent; border: 1px solid var(--line); }
.button--ghost:hover { border-color: var(--ink); }
.text-link {
  min-height: 44px; display: inline-flex; align-items: center;
  padding: 0; border: 0; background: none; cursor: pointer;
  color: var(--muted); font: inherit; font-weight: 750;
  text-decoration: underline; text-underline-offset: 4px;
}
.text-link:hover { color: var(--ink); }

/* ---------------------------------------------------------- tracking choice */

.tracking { padding: clamp(36px, 6vw, 72px) 0 clamp(48px, 8vw, 92px); }
.tracking-heading {
  display: grid; grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.25fr);
  column-gap: clamp(28px, 6vw, 84px); align-items: end;
  margin-bottom: clamp(24px, 4vw, 42px);
}
.tracking-heading .eyebrow { grid-column: 1 / -1; }
.tracking-heading h2 {
  max-width: 12ch; margin: 0;
  font-size: clamp(2.3rem, 6vw, 4.8rem); line-height: 0.98;
  letter-spacing: -0.055em; text-wrap: balance;
}
.tracking-heading > p:last-child {
  max-width: 52ch; margin: 0;
  color: var(--muted); font-size: clamp(1.05rem, 2vw, 1.3rem); line-height: 1.55;
}
.tracking-options {
  display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: 18px; align-items: stretch;
}
.tracking-option {
  min-width: 0; padding: clamp(26px, 4vw, 44px);
  border: 1px solid var(--line);
  border-radius: 24px;
}
.tracking-option[hidden] { display: none; }
.tracking-option--app {
  display: flex; flex-direction: column;
  background: linear-gradient(145deg, rgba(140, 206, 210, 0.13), rgba(255, 255, 255, 0.015));
}
.tracking-option--beacon {
  background: linear-gradient(145deg, rgba(239, 185, 79, 0.07), rgba(255, 255, 255, 0.015));
}
.tracking-option__tag {
  margin: 0 0 16px; color: var(--blue);
  font-size: 0.72rem; font-weight: 850; letter-spacing: 0.13em; text-transform: uppercase;
}
.tracking-option--beacon .tracking-option__tag { color: var(--sun); }
.tracking-option h3 { margin: 0 0 12px; font-size: clamp(1.65rem, 3vw, 2.25rem); letter-spacing: -0.04em; }
.tracking-option__lead { margin: 0; color: var(--muted); line-height: 1.6; }
.tracking-benefits { display: grid; gap: 10px; margin: 24px 0 0; padding: 0; list-style: none; }
.tracking-benefits li { position: relative; padding-left: 24px; line-height: 1.5; }
.tracking-benefits li::before { content: "✓"; position: absolute; left: 0; color: var(--lap-lime); font-weight: 900; }
.tracking-option__actions { display: flex; align-items: center; flex-wrap: wrap; gap: 16px; margin-top: 28px; }
.tracking-option__status { margin: 18px 0 0; color: var(--muted); font-size: 0.88rem; line-height: 1.5; }
.tracking-option__more { margin-top: auto; padding-top: 14px; align-self: flex-start; }
.beacon-help { max-width: 62ch; margin: 0 0 22px; color: var(--muted); line-height: 1.6; }

.beacon-fields { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 14px; }
.beacon-field { display: flex; flex-direction: column; gap: 6px; }
.beacon-field--link { min-width: 0; }
#beacon-name-field[hidden] + .beacon-field--link { grid-column: 1 / -1; }
/* A class that sets `display` outranks the browser's own [hidden] rule. */
.beacon-field[hidden], .beacon-assigned[hidden], .beacon-reroll[hidden] { display: none; }
.beacon-namebar { display: flex; align-items: center; gap: 14px; }
.beacon-namebar:has(.beacon-reroll:not([hidden])) { margin-top: 10px; }
.beacon-assigned { margin: 0; font-weight: 750; }
.beacon-reroll {
  min-height: 40px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 12px;
  color: var(--ink); background: rgba(0, 0, 0, 0.25);
  font: inherit; font-size: 0.9rem; cursor: pointer;
}
.beacon-field span, .beacon-field > label { font-size: 0.82rem; font-weight: 750; color: var(--muted); }
.beacon-link-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; }
.beacon-field input {
  width: 100%; min-width: 0; min-height: 48px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 12px;
  color: var(--ink); background: rgba(0, 0, 0, 0.25);
  font: inherit;
}
.beacon-field input::placeholder { color: rgba(170, 184, 178, 0.55); }
.beacon-field input:focus-visible { outline-offset: 0; }
.beacon-field input[aria-invalid="true"] { border-color: #f0a08a; }
.beacon-field input[aria-invalid="false"] { border-color: rgba(183, 211, 86, 0.65); }
.beacon-paste {
  min-height: 48px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 12px;
  color: var(--ink); background: rgba(255, 255, 255, 0.055);
  font: inherit; font-size: 0.9rem; font-weight: 750; cursor: pointer;
  white-space: nowrap;
}
.beacon-paste:hover { border-color: var(--ink); }
.button:disabled, .beacon-paste:disabled { cursor: not-allowed; opacity: 0.48; }

.beacon-turnstile { margin-top: 14px; min-height: 0; }
.beacon-turnstile:not(:empty) { margin-bottom: 4px; }
.beacon-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 20px; margin-top: 16px; }
.beacon-actions [hidden] { display: none; }
.beacon-status { min-height: 1.4em; margin: 12px 0 0; font-weight: 700; }
.beacon-status.is-bad { color: #f0a08a; }
.beacon-status.is-good { color: var(--lap-lime); }

.strava-connect {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px 28px; align-items: center;
  margin-top: 18px; padding: clamp(20px, 3vw, 28px) clamp(22px, 4vw, 36px);
  border: 1px dashed var(--line); border-radius: 24px;
}
.strava-connect .tracking-option__tag { margin-bottom: 10px; color: var(--sun); }
.strava-connect h3 { margin: 0 0 8px; font-size: clamp(1.25rem, 2.2vw, 1.6rem); letter-spacing: -0.03em; }
.strava-connect__copy { max-width: 62ch; margin: 0; color: var(--muted); line-height: 1.6; }

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

.years { position: relative; padding: clamp(30px, 5vw, 60px) 0; border-top: 1px solid var(--line); }
.years h2, .days h2 {
  margin: 0 0 26px;
  font-size: clamp(1.7rem, 4vw, 2.6rem);
  letter-spacing: -0.04em;
  text-wrap: balance;
}

.year-grid { position: relative; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 22px; align-items: end; }
/* The connecting thread: a stripe band winding over the card tops, one day
 * growing longer year by year. hub.js draws the paths from the measured
 * staircase, so the band climbs with the cards in every language and width. */
.year-line {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; overflow: visible; opacity: 0.55;
}
.year-line .yl { fill: none; stroke: var(--lap-lime); stroke-width: 1.3; stroke-linecap: round; }
.year-line .yl--lead { stroke: var(--ink); stroke-width: 2; opacity: 0.8; }

.year-card {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  padding: clamp(22px, 3vw, 34px);
  border: 1px solid var(--line); border-radius: 24px;
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
}
/* The staircase: cards sit on a shared baseline and each year is literally a
   bigger card than the one before — a 20,8 km day fits in less space than 203 km.
   --step scales the display type along with the card height. */
.year-card--2023 { --step: 0.7; min-height: 240px; border-color: rgba(170, 184, 178, 0.35); }
.year-card--2024 { --step: 0.84; min-height: 285px; border-color: rgba(140, 206, 210, 0.4); }
.year-card--2026 { --step: 1; min-height: 330px; border-color: rgba(239, 185, 79, 0.4); }
.year-card--2027 { --step: 1.08; min-height: 370px; border-style: dashed; }

.year-label {
  margin: 0; font-size: 0.72rem; font-weight: 850;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted);
}
.year-card--2024 .year-label { color: var(--blue); }
.year-card--2026 .year-label { color: var(--sun); }

.year-card h3 { margin: 0; font-size: calc(clamp(2.6rem, 5vw, 3.6rem) * var(--step, 1)); letter-spacing: -0.06em; line-height: 0.95; }
.year-card h3 a { text-decoration: none; }
.year-card h3 a:hover { color: var(--sun); }

.year-km { margin: 0; color: var(--muted); font-weight: 700; }
.year-km strong {
  font-size: calc(clamp(1.6rem, 3vw, 2.1rem) * var(--step, 1)); font-weight: 900;
  letter-spacing: -0.04em; color: var(--ink); font-variant-numeric: tabular-nums;
}
.year-card--2023 .year-km strong { color: var(--muted); }
.year-card--2024 .year-km strong { color: var(--blue); }
.year-card--2026 .year-km strong { color: var(--sun); }

.year-copy { margin: 0 0 6px; color: var(--muted); line-height: 1.55; flex-grow: 1; }
.year-card .button { align-self: stretch; }

/* ---------------------------------------------------------------- ride log */

.days { padding: clamp(30px, 5vw, 60px) 0; border-top: 1px solid var(--line); }
.days-sub { max-width: 56ch; margin: -14px 0 24px; color: var(--muted); line-height: 1.55; }

.days-list { list-style: none; margin: 0; padding: 0; }
.days-list li {
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: 18px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.days-list .day-date { font-weight: 850; font-variant-numeric: tabular-nums; white-space: nowrap; }
.days-list .day-date a { color: var(--sun); text-decoration: none; }
.days-list .day-date a:hover { text-decoration: underline; text-underline-offset: 4px; }
.days-list .day-who { color: var(--muted); line-height: 1.5; }
.days-list .day-sum {
  font-weight: 850; font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right;
}
.days-list .day-sum small { display: block; color: var(--muted); font-weight: 700; }
.days-empty { color: var(--muted); padding: 14px 0; }

/* Year folds: the log spans seasons back to 2021, so each year collapses
 * into its own <details>; the row grid above only styles the inner lists. */
.days-list > .days-year { display: block; padding: 0; border-bottom: none; }
.days-year details { border-bottom: 1px solid var(--line); }
.days-year summary {
  display: flex; align-items: baseline; gap: 12px;
  padding: 16px 0; cursor: pointer; list-style: none;
}
.days-year summary::-webkit-details-marker { display: none; }
.days-year summary::before { content: "▸"; color: var(--muted); }
.days-year details[open] summary::before { content: "▾"; }
.days-year .year-label { font-weight: 850; font-size: 1.15em; font-variant-numeric: tabular-nums; margin-right: auto; }
.days-year .year-stats { color: var(--muted); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.days-year .days-list { margin: 0 0 6px; padding-left: clamp(14px, 3vw, 26px); }
.days-year .days-list li:last-child { border-bottom: none; }

/* -------------------------------------------------------------- invitation */

.invitation { margin: 20px 0 40px; padding: 34px 0; border-top: 1px solid var(--line); }
.invitation p {
  max-width: 52ch; margin: 0;
  font-size: clamp(1.35rem, 3vw, 2.15rem); line-height: 1.35; font-weight: 700;
  text-wrap: pretty;
}

footer {
  width: min(1180px, calc(100% - 40px));
  margin: 0 auto; padding: 0 0 42px;
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 16px 20px;
  color: var(--muted);
}
.footer-nav {
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px 20px;
}
footer a { color: var(--muted); font-weight: 700; }
footer a:hover { color: var(--ink); }
footer .build-tag {
  margin: 0;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  opacity: 0.75;
}

/* ------------------------------------------------------------- breakpoints */

@media (max-width: 900px) {
  .lake-hero { grid-template-columns: 1fr; padding-top: 30px; }
  .lake-map { order: 2; max-width: min(440px, 100%); margin-inline: 0; }
  .lake-status { order: 1; }
  .year-grid { grid-template-columns: 1fr; align-items: stretch; }
  .year-card { min-height: 0; }
  .year-line { display: none; }
  .tracking-heading { grid-template-columns: 1fr; align-items: start; gap: 18px; }
  .tracking-heading .eyebrow { grid-column: auto; margin-bottom: -8px; }
  .tracking-options { grid-template-columns: 1fr; }
  .beacon-fields { grid-template-columns: 1fr; }
  .strava-connect { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .site-header { grid-template-columns: 1fr auto; gap: 10px; padding: 12px 0; }
  .site-header, main, footer { width: min(100% - 28px, 1180px); }
  .live-actions .button, .beacon-actions .button, .tracking-option__actions .button, .strava-connect .button { width: 100%; }
  .beacon-link-row { grid-template-columns: 1fr; }
  .beacon-paste { width: 100%; }
  .days-list li { grid-template-columns: 1fr auto; }
  .days-list .day-who { grid-column: 1 / -1; grid-row: 2; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .lake-loop--dash, .lake-rider circle { animation: none; }
  * { transition: none !important; }
}

/* --------------------------------------------------------------- heat glow */

/* The ridden-trail glow inside the lake SVG (#lake-heat, drawn by hub.js from
   /heatmap.json). The toggle floats over the map's corner. */
.heat-toggle {
  position: absolute; left: 8px; bottom: 8px;
  min-height: 44px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 999px;
  color: var(--muted); background: rgba(11, 26, 22, 0.75);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  font: inherit; font-size: 0.78rem; font-weight: 850; cursor: pointer;
  z-index: 3;
}
.heat-toggle::before {
  content: ""; display: inline-block; width: 8px; height: 8px;
  margin-right: 8px; border-radius: 50%;
  background: var(--sun); box-shadow: 0 0 6px var(--sun);
}
.heat-toggle.is-off { color: rgba(170, 184, 178, 0.55); }
.heat-toggle.is-off::before { background: transparent; box-shadow: none; border: 1px solid var(--muted); }
.heat-toggle:hover { color: var(--ink); }
/* Second pill above "Heatmap": reveals the base map without the drag gesture. */
.basemap-toggle { bottom: 60px; }
.basemap-toggle::before { background: var(--sky, #7cc0ff); box-shadow: 0 0 6px var(--sky, #7cc0ff); }
.basemap-toggle.is-off::before { background: transparent; box-shadow: none; }

.lake-map-reset {
  position: absolute; right: 8px; bottom: 8px;
  min-height: 44px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 999px;
  color: var(--muted); background: rgba(11, 26, 22, 0.75);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  font: inherit; font-size: 0.78rem; font-weight: 850; cursor: pointer;
  z-index: 3;
  display: inline-flex; align-items: center; gap: 7px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.lake-map-reset[hidden] { display: none !important; }
.lake-map-reset:hover { color: var(--ink); border-color: var(--blue); }

.lake-map-attribution {
  position: absolute;
  right: 8px;
  bottom: 8px;
  font-size: 0.68rem;
  line-height: 1.3;
  color: var(--muted);
  background: rgba(11, 26, 22, 0.78);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  border: 1px solid rgba(243, 238, 224, 0.12);
  border-radius: 6px;
  padding: 3px 8px;
  z-index: 3;
  opacity: 0;
  pointer-events: auto;
  transition: opacity 0.4s ease, bottom 0.2s ease;
}
.lake-map.is-active .lake-map-attribution {
  opacity: 0.85;
}
.lake-map.has-reset .lake-map-attribution {
  bottom: 58px;
}
.lake-map-attribution a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.lake-map-attribution a:hover {
  color: var(--blue);
}
.lake-map-attribution[hidden] {
  display: none !important;
}

/* -------------------------------------------------------------------- guide */

/* Three steps: arrive, ride around, enjoy. Numbered by the counter so the
   markup stays a plain list. */
.guide { padding: clamp(30px, 5vw, 60px) 0; border-top: 1px solid var(--line); }
.guide h2 {
  margin: 0 0 26px;
  font-size: clamp(1.7rem, 4vw, 2.6rem);
  letter-spacing: -0.04em;
}
.guide-steps {
  list-style: none; counter-reset: step;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px;
  margin: 0; padding: 0;
}
.guide-steps li {
  counter-increment: step;
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  padding: clamp(22px, 3vw, 30px);
  border: 1px solid var(--line); border-radius: 24px;
}
.guide-steps li::before {
  content: counter(step);
  font-size: clamp(2rem, 4vw, 2.8rem); font-weight: 900; line-height: 1;
  letter-spacing: -0.05em; color: var(--sun); font-variant-numeric: tabular-nums;
}
.guide-steps h3 { margin: 0; font-size: clamp(1.15rem, 2.2vw, 1.4rem); letter-spacing: -0.02em; }
.guide-steps p { margin: 0; color: var(--muted); line-height: 1.55; flex-grow: 1; }

@media (max-width: 900px) {
  .guide-steps { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------- beacon how-to */

/* "Where do I get a Beacon link?" — collapsed by default so the form stays
   two fields and a button. */
.beacon-how { max-width: 62ch; margin-top: 14px; font-size: 0.9rem; }
.beacon-how summary {
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--muted); font-weight: 750; cursor: pointer;
  text-decoration: underline; text-underline-offset: 4px;
  list-style: none;
}
.beacon-how summary::-webkit-details-marker { display: none; }
.beacon-how summary::before {
  content: ""; display: inline-block; width: 0; height: 0;
  margin-right: 8px;
  border-left: 6px solid var(--sun); border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform 0.15s ease;
}
.beacon-how[open] summary::before { transform: rotate(90deg); }
.beacon-how summary:hover { color: var(--ink); }
.beacon-how ol { margin: 8px 0 0; padding-left: 22px; color: var(--muted); line-height: 1.6; }
.beacon-how li { margin-bottom: 4px; }
.beacon-how li::marker { color: var(--sun); font-weight: 800; }
.beacon-how p { margin: 10px 0 0; color: var(--muted); line-height: 1.55; }

.live-hint { margin: 12px 0 0; font-size: 0.9rem; }

/* ---------------------------------------------------------- notify toggles */

/* The heat toggle's look, but sitting in normal flow inside .live-actions. */
.notify-toggle, .notify-mute {
  min-height: 44px; padding: 0 16px;
  border: 1px solid var(--line); border-radius: 999px;
  color: var(--muted); background: rgba(11, 26, 22, 0.7);
  font: inherit; font-size: 0.78rem; font-weight: 850; cursor: pointer;
}
.notify-toggle::before {
  content: ""; display: inline-block; width: 8px; height: 8px;
  margin-right: 8px; border-radius: 50%;
  background: var(--sun); box-shadow: 0 0 6px var(--sun);
}
.notify-toggle.is-off { color: rgba(170, 184, 178, 0.55); }
.notify-toggle.is-off::before { background: transparent; box-shadow: none; border: 1px solid var(--muted); }
.notify-toggle.is-denied { color: rgba(170, 184, 178, 0.4); cursor: default; }
.notify-toggle.is-denied::before { background: transparent; box-shadow: none; border: 1px solid rgba(170, 184, 178, 0.4); }
.notify-toggle:hover:not(.is-denied), .notify-mute:hover { color: var(--ink); }
.notify-mute.is-off { color: rgba(170, 184, 178, 0.55); text-decoration: line-through; }

/* Let the geographic heat continue behind the rest of the page. Content stays
   above the decorative canvas; existing translucent cards protect small copy. */
body > main, body > header, body > footer { position: relative; z-index: 1; }
.lake-map svg { mask-image: none; -webkit-mask-image: none; }

/* A real link remains usable without Web Share or clipboard access. */
.day-share { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 8px 14px; border: 1px solid var(--line); border-radius: 999px; color: var(--sun); font-size: .85rem; font-weight: 750; text-decoration: none; white-space: nowrap; }
.day-share:hover { background: rgba(239,185,79,.1); border-color: var(--sun); }
.day-share-status { color: var(--blue); min-height: 1.5em; }
@media (max-width: 700px) {
  .days-list .day-share { grid-column: 1 / -1; justify-self: start; }
  .days-list .day-who { overflow-wrap: anywhere; }
}

/* Hidden until the Worker's Strava connect routes are enabled (STRAVA_CLIENT_ID). */
.strava-connect[hidden] { display: none; }


/* ------------------------------------------------------- phone hero
   The lake is the hero, so on a phone it takes whatever screen one has left and
   the status line, the one primary action and the Beacon link sit in one glass
   sheet under it. Flow layout, so the sheet can never cover the map controls. The headline is a sentence, not a number on a poster. */

@media (max-width: 900px) {
  .site-header { min-height: 56px; padding: 6px 0; }
  .language-switcher button { min-width: 40px; min-height: 40px; }

  .lake-hero {
    display: flex; flex-direction: column; gap: 8px;
    min-height: calc(100svh - 140px); padding: 0 0 18px;
  }
  .lake-hero::before { display: none; }
  .lake-map {
    order: 1; flex: 1 1 auto; min-height: 200px; width: 100%; max-width: none; margin: 0;
    display: grid; place-items: center;
  }
  .lake-map svg { max-height: 100%; }
  .lake-status { order: 2; padding: 16px 16px 14px; border-radius: 22px; }

  .live-count, .live-count strong, .live-count-label { display: inline; }
  .lake-status h1 {
    font-size: clamp(1.45rem, 6.4vw, 1.9rem); font-weight: 850;
    letter-spacing: -0.025em; line-height: 1.15; text-wrap: balance;
  }
  .live-count strong { font-size: 1em; letter-spacing: inherit; margin-right: 0.3em; }
  .live-count-label { max-width: none; margin: 0; font-size: 1em; }
  .lake-status .eyebrow { margin-bottom: 8px; }
  .live-detail { margin-top: 8px; font-size: 0.88rem; min-height: 0; }
  .live-actions { gap: 6px 12px; margin-top: 12px; }
  .live-actions .button { min-height: 50px; }
  .notify-toggle { min-height: 40px; padding: 0 12px; font-size: 0.72rem; }
  .live-hint { display: none; }

  .brand { font-size: clamp(0.95rem, 4.6vw, 1.08rem); white-space: nowrap; }
  .heat-toggle { left: 4px; bottom: 4px; min-height: 36px; padding: 0 12px; font-size: 0.72rem; }
  .basemap-toggle { left: 104px; bottom: 4px; }
  .lake-map-reset { right: 4px; bottom: 4px; }
}


/* ---------------------------------------------------------------- ride log */

/* display:grid on the rows would otherwise win over the hidden attribute. */
.days-list li[hidden] { display: none; }
.days-list li.days-more { display: block; padding: 14px 0 6px; border-bottom: 0; }
.days-more__btn {
  min-height: 48px; padding: 0 22px; border: 1px solid var(--line); border-radius: 999px;
  color: var(--ink); background: transparent; font: inherit; font-weight: 850; cursor: pointer;
}
.days-more__btn:hover { border-color: var(--ink); }

/* On a phone a day is two short lines plus the photo fold, not five stacked
   blocks: date and distance, then riders with a small share link. */
@media (max-width: 640px) {
  .days-list li { grid-template-columns: minmax(0, 1fr) auto; gap: 2px 12px; padding: 12px 0; align-items: center; }
  .days-list li .day-date { grid-column: 1; grid-row: 1; }
  .days-list li .day-sum { grid-column: 2; grid-row: 1; }
  .days-list li .day-sum small { display: inline; margin-left: 0.45em; }
  .days-list li .day-who { grid-column: 1; grid-row: 2; font-size: 0.9rem; }
  .days-list li .day-share { grid-column: 2; grid-row: 2; justify-self: end; min-height: 36px; padding: 0 12px; font-size: 0.78rem; }
  .days-list li .ride-photo-day { grid-row: 3; }
  .ride-photo-day summary { display: flex; align-items: center; min-height: 36px; }
  .days-more__btn { width: 100%; }
}


/* ------------------------------------------------- tracking section, phones */

/* Three stacked cards (app, Beacon, Strava) were 1,427 px of mostly padding. */
@media (max-width: 640px) {
  .tracking { padding-top: 28px; padding-bottom: 36px; }
  .tracking-heading { margin-bottom: 18px; row-gap: 10px; }
  .tracking-heading h2 { font-size: clamp(2rem, 9vw, 2.4rem); }
  .tracking-options { gap: 14px; }
  .tracking-option { padding: 20px 18px; border-radius: 20px; }
  .tracking-option__tag { margin-bottom: 10px; }
  .tracking-option h3 { margin-bottom: 8px; font-size: 1.5rem; }
  .tracking-option__actions { margin-top: 18px; gap: 10px; }
  .beacon-help { margin-bottom: 14px; }
  .strava-connect { padding: 18px; }
}


/* ----------------------------------------------- tracking tabs (phones only) */

/* tracking-tabs.js adds .tracking--tabs and the tablist at <= 640px; without it all
   three cards stay visible. */
.tracking-tabs {
  display: flex; gap: 4px; margin: 0 0 14px; padding: 4px;
  border: 1px solid var(--line); border-radius: 999px; background: rgba(255, 255, 255, 0.04);
}
.tracking-tab {
  flex: 1 1 0; min-height: 44px; padding: 0 10px; border: 0; border-radius: 999px;
  color: var(--muted); background: transparent; font: inherit; font-weight: 850; cursor: pointer;
}
.tracking-tab[hidden] { display: none; }
.tracking-tab[aria-selected="true"] { color: var(--forest); background: var(--sun); }
.tracking-tab:not([aria-selected="true"]):hover { color: var(--ink); }
.tracking--tabs .is-tab-hidden { display: none; }

/* ------------------------------------------------- year cards, phones only */

/* Four tall stacked cards (~300 px each) become compact rows: the year and its distance on
   the left, what happened on the right. The desktop staircase is untouched. */
@media (max-width: 640px) {
  .years h2, .days h2 { margin-bottom: 16px; }
  .year-grid { gap: 10px; }
  .year-card {
    display: grid; grid-template-columns: 5.2rem minmax(0, 1fr); column-gap: 14px; row-gap: 2px;
    align-items: start; padding: 14px 16px; min-height: 0; border-radius: 18px;
  }
  .year-card h3 { grid-column: 1; grid-row: 1; font-size: 2.1rem; }
  .year-card .year-km { grid-column: 1; grid-row: 2; }
  .year-card .year-km strong { font-size: 1.15rem; }
  .year-card .year-label { grid-column: 2; grid-row: 1; align-self: center; }
  .year-card .year-copy { grid-column: 2; grid-row: 2; margin: 0; font-size: 0.9rem; line-height: 1.45; }
  .year-card .button {
    grid-column: 1 / -1; grid-row: 3; justify-self: start; align-self: auto;
    min-height: 40px; margin-top: 8px; padding: 0 16px; font-size: 0.9rem;
  }
}
