:root {
  --ink: #18312d;
  --muted: #5d6f6a;
  --panel: #fffaf0;
  --line: #d9cfb7;
  --forest: #2f7d57;
  --clay: #b74e37;
}

* { box-sizing: border-box; }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* A class that sets `display` outranks the browser's own [hidden] rule. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  font-family: Avenir Next, Trebuchet MS, Verdana, sans-serif;
  color: var(--ink);
}

#map {
  position: absolute;
  inset: 0;
  /* The style's own background colour, so the page does not flash white while
     MapLibre loads after the first paint. */
  background: #f5f3ee;
}

/* Map data attribution, painted with the page (MapLibre's own control is off
   on /live). It sits in the strip under the bottom panel on phones and in the
   bottom-right corner on wider screens, above the map and the panel. */
.map-attribution {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 501;
  max-width: 100%;
  margin: 0;
  padding: 0 6px;
  border-top-left-radius: 6px;
  background: rgba(255, 250, 240, 0.85);
  color: var(--muted);
  font-size: 10px;
  line-height: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.map-attribution a { color: inherit; }
/* Keep the zoom buttons clear of the attribution line. */
#map .maplibregl-ctrl-bottom-right { bottom: 12px; }

.map-note {
  margin: 8px 0 0;
  color: var(--clay);
  font-size: 0.85rem;
}
.map-retry {
  font: inherit;
  font-weight: 800;
  margin-left: 4px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid currentColor;
  background: #fff;
  color: var(--clay);
  cursor: pointer;
}

/* ride-photos.css arrives after the map; these keep an early gallery in the
   panel at its final size in the meantime. */
.panel .ride-photo-gallery { display: flex; gap: 12px; overflow-x: auto; }
.panel .ride-photo-thumb { flex: 0 0 160px; overflow: hidden; }
.panel .ride-photo-thumb img { width: 160px; height: 120px; object-fit: cover; }

.bar {
  position: absolute;
  top: max(12px, env(safe-area-inset-top));
  left: 12px;
  right: 12px;
  z-index: 500;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 999px;
  background: rgba(255, 250, 240, 0.94);
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px rgba(24, 49, 45, 0.18);
}

.back {
  text-decoration: none;
  font-size: 1.2rem;
  line-height: 1;
  padding: 6px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: inherit;
}

.bar-title {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  margin-right: auto;
  overflow: hidden;
}

.bar-title strong { font-size: 0.95rem; white-space: nowrap; }
.bar-title small { color: var(--muted); }

.follow {
  font: inherit;
  font-weight: 800;
  font-size: 0.85rem;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}

.follow.is-on {
  background: var(--forest);
  border-color: var(--forest);
  color: #fffaf0;
}

.back:focus-visible, .follow:focus-visible, .watcher summary:focus-visible,
.watcher-body input:focus-visible, .watcher-body select:focus-visible,
.watcher-body button:focus-visible, .filters input:focus-visible {
  outline: 3px solid #d88b2f;
  outline-offset: 2px;
}

@media (max-width: 480px) {
  .bar-title { display: none; }
  .bar { gap: 6px; padding-inline: 8px; }
  .back { padding-inline: 8px; }
  .follow { padding-inline: 9px; }
  #lang { margin-left: auto; }
  .notify-toggle, .notify-mute {
    min-width: 36px;
    padding-inline: 8px;
    font-size: 0;
  }
  .notify-toggle::before { content: "🔔"; font-size: 0.95rem; }
  .notify-mute::before { content: "🔊"; font-size: 0.95rem; }
  .notify-mute.is-off::before { content: "🔇"; }
  .share-topic { display: none; }
  .share { font-size: 0.8rem; padding: 6px 10px; }
}

.panel {
  position: absolute;
  z-index: 500;
  left: 12px;
  bottom: max(12px, env(safe-area-inset-bottom));
  width: min(340px, calc(100% - 24px));
  /* A fixed, viewport-bounded box (bik-141s): the panel is anchored at the
     bottom, so a content-sized box grew upwards as the feed, the photo strip
     and the heat slider arrived, and that counted as layout shift. The
     content scrolls inside instead. */
  height: clamp(9.5rem, 28vh, 20rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 14px 16px;
  border-radius: 14px;
  background: rgba(255, 250, 240, 0.95);
  border: 1px solid var(--line);
  box-shadow: 0 14px 40px rgba(24, 49, 45, 0.22);
}

.map-panel-toggle, .panel-status { display: none; }

.empty {
  margin: 0;
  color: var(--muted);
  /* Two lines reserved: "searching" is one line, the answer often two, and
     the step pushed the rest of the panel down (a measured layout shift). */
  line-height: 1.3;
  min-height: 2.6em;
}

.riders {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.riders li {
  display: flex;
  align-items: center;
  gap: 10px;
}

.swatch {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex: none;
}

.who strong { display: block; }
.who small { color: var(--muted); }
.tracker-replay-link { display: block; margin-top: 5px; color: var(--forest); font-size: .85rem; }

.foot {
  margin: 12px 0 0;
  font-size: 0.85rem;
  min-height: 1.3em; /* its links arrive with the first poll */
}

.foot a { color: var(--forest); font-weight: 800; }

.watcher, .filters { border-top: 1px solid var(--line); margin-top: 12px; padding-top: 10px; }
.watcher summary { font-weight: 800; cursor: pointer; }
.watcher-body { display: grid; gap: 8px; margin-top: 10px; }
.watcher-privacy, .watcher-summary {
  margin: 4px 0;
  font-size: .78rem;
  line-height: 1.4;
  color: #536660;
}
.watcher-summary {
  padding: 8px 10px;
  border-left: 3px solid #d88b2f;
  background: rgba(216, 139, 47, .09);
  color: #18312d;
}
.watcher-body input[type=text], .watcher-body select {
  font: inherit; padding: 9px 10px; border: 1px solid var(--line);
  border-radius: 8px; background: #fff; color: var(--ink); width: 100%;
}
.watcher-row { display: flex; gap: 14px; font-size: 0.88rem; }
.watcher-row label { display: flex; gap: 5px; align-items: center; }
.watcher-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.w-send {
  font: inherit; font-weight: 800; cursor: pointer; padding: 13px;
  border-radius: 8px; border: 1px solid var(--forest); background: var(--forest); color: #fffaf0;
}
.w-send:disabled { opacity: 0.6; cursor: progress; }
.w-leave { font: inherit; font-size: 0.85rem; border: 0; background: none; padding: 0;
  color: var(--muted); text-decoration: underline; cursor: pointer; }
.w-message { margin: 0; font-size: 0.85rem; font-weight: 700; color: var(--forest); min-height: 1.1em; }
.filters { display: flex; gap: 14px; flex-wrap: wrap; font-size: 0.85rem; }
.filters label { display: flex; gap: 5px; align-items: center; }

/* A spectator is a hollow mark, so it never reads as a rider. */
.watcher-marker { position: relative; width: 14px; height: 14px; }
.watcher-marker .w-dot {
  display: block; width: 12px; height: 12px; border-radius: 50%;
  background: #fffaf0; border: 3px solid var(--muted);
}
.watcher-marker.is-mine .w-dot { border-color: var(--ink); }
.watcher-marker .w-tag {
  position: absolute; top: 16px; left: 50%; transform: translateX(-50%);
  white-space: nowrap; font-size: 0.68rem; font-weight: 700; padding: 1px 6px;
  border-radius: 999px; background: rgba(255, 250, 240, 0.9); border: 1px solid var(--line);
}
/* A photo marker is the photo itself: at 40 px it reads as "something was seen
   here" without another legend to learn. */
.photo-marker img {
  display: block;
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 6px;
  border: 2px solid #fffaf0;
  box-shadow: 0 2px 8px rgba(24, 49, 45, 0.4);
  cursor: zoom-in;
}

.link-label {
  background: rgba(255, 250, 240, 0.94); border: 1px solid var(--line);
  color: var(--ink); font-weight: 800; font-size: 0.75rem;
  padding: 2px 8px; border-radius: 6px; white-space: nowrap;
  pointer-events: none;
}

.rider-marker { position: relative; width: 16px; height: 16px; }
.rider-marker .dot {
  display: block;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 3px solid #fffaf0;
  box-shadow: 0 2px 8px rgba(24, 49, 45, 0.4);
}

.rider-marker .tag {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 0.72rem;
  font-weight: 800;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(255, 250, 240, 0.92);
  border: 1px solid var(--line);
}

.hub-marker {
  display: grid;
  place-items: center;
  width: 46px;
  height: 26px;
  font-size: 0.7rem;
  font-weight: 800;
  border-radius: 999px;
  background: var(--ink);
  color: #fffaf0;
  border: 2px solid #fffaf0;
}

@media (max-width: 620px) {
  .bar-title strong { font-size: 0.85rem; }

  .map-panel-toggle {
    position: absolute;
    top: 7px;
    right: 7px;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: #fff;
    color: var(--ink);
    font: 900 1rem/1 system-ui, sans-serif;
    cursor: pointer;
  }
  .map-panel-toggle:focus-visible { outline: 3px solid #d88b2f; outline-offset: 2px; }
  .panel > .empty, .panel > .riders, .panel > .mark-hint { padding-right: 48px; }
  .panel.is-collapsed {
    min-height: 58px;
    height: auto;
    max-height: none;
    overflow: hidden;
    padding: 10px 60px 10px 14px;
  }
  /* The map-unavailable note stays visible in the peek: it explains the
     empty map behind the collapsed panel. */
  .panel.is-collapsed > :not(.map-panel-toggle):not(.panel-status):not(.map-note) { display: none; }
  .panel.is-collapsed .panel-status {
    display: flex;
    align-items: center;
    min-height: 36px;
    margin: 0;
    overflow: hidden;
    color: var(--muted);
    font-size: 0.85rem;
    font-weight: 800;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}

.heat-range { display: flex; flex-direction: column; gap: 6px; padding-top: 4px; }
.heat-range label { font-size: 0.82rem; }
.heat-range strong { font-variant-numeric: tabular-nums; }
.heat-range input[type="range"] { width: 100%; min-height: 44px; accent-color: #efb94f; }

/* Notify bell in the map header: .follow gives the shape, these give state. */
.notify-toggle.is-off, .notify-mute.is-off { opacity: 0.55; }
.notify-mute.is-off { text-decoration: line-through; }
.notify-toggle.is-denied { opacity: 0.4; cursor: default; }

/* Header share button: with a marked pin it shares the pin (bik-3rqa); the
   accent says so on phones, where only "Jaa" fits. */
.share.has-mark {
  border-color: #d88b2f;
  box-shadow: inset 0 0 0 1px #d88b2f;
  color: var(--ink);
}

/* Marking hint and the keyboard way to mark (bik-3rqa). */
.mark-hint {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin: 0 0 8px;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.3;
}
/* visibility keeps the row's space: hiding it must not move the panel. */
.mark-hint.is-marked .mark-hint-text { visibility: hidden; }
.mark-centre {
  font: inherit;
  font-weight: 800;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink);
  cursor: pointer;
}

/* The marked pin. The marker's anchor is the bottom of this box, the tip of
   the needle, so the card above it never covers the marked point. Only the
   card and the needle take pointer events. */
.mark-pin {
  position: relative;
  width: 28px;
  height: 36px;
  pointer-events: none;
}
.mark-pin-card, .mark-pin-icon { pointer-events: auto; }

.mark-pin-card {
  position: absolute;
  bottom: 44px;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 6px 10px;
  width: max-content;
  max-width: min(260px, calc(100vw - 32px));
  margin-bottom: 8px;
  padding: 8px 8px 10px 12px;
  border-radius: 12px;
  background: #fffaf0;
  border: 1px solid var(--line);
  box-shadow: 0 8px 22px rgba(24, 49, 45, 0.25);
  color: var(--ink);
  cursor: default;
}
.mark-pin.is-below .mark-pin-card { top: 44px; bottom: auto; }
.mark-pin-card::after {
  content: "";
  position: absolute;
  /* --mark-caret: set by live-map.js when the card shifts inward near a side. */
  left: calc(50% + var(--mark-caret, 0px));
  bottom: -6px;
  width: 10px;
  height: 10px;
  margin-left: -5px;
  background: #fffaf0;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  transform: rotate(45deg);
}
.mark-pin.is-below .mark-pin-card::after {
  top: -6px;
  bottom: auto;
  transform: rotate(225deg);
}
.mark-pin-coords {
  font-size: 0.82rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.mark-pin-close {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink);
  font: 700 1.1rem/1 system-ui, sans-serif;
  cursor: pointer;
}
.mark-pin-close:hover { background: #f1eadb; }
.mark-pin-share {
  grid-column: 1 / -1;
  min-height: 40px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: #fffaf0;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 800;
  white-space: nowrap;
  cursor: pointer;
}
.mark-pin-icon {
  display: block;
  width: 28px;
  height: 36px;
  cursor: grab;
  touch-action: none;
  filter: drop-shadow(0 3px 6px rgba(16, 22, 20, 0.35));
}
.mark-pin-icon svg { display: block; }
.mark-pin-close:focus-visible, .mark-pin-share:focus-visible, .mark-centre:focus-visible {
  outline: 3px solid #d88b2f;
  outline-offset: 2px;
}

/* Hidden tracking-areas view (/live?alueet, jarkko 01M1W259WZ). */
.areas { border-top: 1px solid rgba(0, 0, 0, 0.08); margin-top: 12px; padding-top: 10px; font-size: 0.85rem; }
.areas-title { font-size: 0.95rem; margin: 0 0 4px; }
.areas-note { margin: 0 0 8px; opacity: 0.75; }
.areas-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.areas-item { display: grid; grid-template-columns: 14px 1fr; column-gap: 8px; align-items: start; }
.areas-item > strong { grid-column: 2; }
.areas-item > .areas-coords, .areas-item > .areas-desc, .areas-item > .areas-source { grid-column: 2; }
.areas-swatch { width: 14px; height: 14px; border-radius: 3px; margin-top: 2px; opacity: 0.85; }
.areas-coords { font-variant-numeric: tabular-nums; opacity: 0.8; }
.areas-source { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.72rem; opacity: 0.6; word-break: break-all; }
.areas-point { grid-template-columns: 1fr; }

/* The map and its heat remain continuous beneath the controls. A soft paper
   veil keeps labels readable while allowing the trails to show through. */
.bar, .panel {
  background: linear-gradient(120deg, rgba(255, 250, 240, .95), rgba(255, 250, 240, .83));
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
@media (max-width: 900px) {
  .bar { flex-wrap: wrap; border-radius: 22px; }
}
