/* Route Planner — Phase 1 skeleton styles.
   Scoped to #route-planner-panel. Map/editor styles come in Phase 2. 
   */

#route-planner-panel {
  display: none;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  background: var(--bg0);
  color: var(--txt);
}
#route-planner-panel.visible { display: flex; }

/* Routes toolbar — mirrors .rp-coll-toolbar for consistent layout. */
#route-planner-panel .rp-routes-toolbar {
  display: flex;
  align-items: center;
  padding: 8px 10px;
  gap: 6px;
  border-bottom: 1px solid var(--bdr, var(--bg3));
}
/* Fixed top action bar (New/Import/Export/Save) — a flex item of the sidebar
   column, so it must not shrink as the section list below it scrolls. */
#route-planner-panel .rp-top-toolbar { flex-shrink: 0; }
/* Push the route-count to the right, same as .rp-coll-cap. */
#route-planner-panel .rp-routes-toolbar .rp-coll-cap { margin-left: auto; }
/* Keep button labels on one line — the sidebar is ~320px and the buttons
   would otherwise wrap their text in a cramped two-line layout. */
#route-planner-panel .rp-routes-toolbar button {
  white-space: nowrap;
  padding: 7px 10px;
}

#route-planner-panel .rp-btn-primary {
  background: var(--amber);
  color: var(--on-amber);
  /* Transparent border (not border:0) keeps the rendered box the same
     height as adjacent .rp-btn buttons, which carry a 1px coloured border. */
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 7px 14px;
  font-weight: 600;
  cursor: pointer;
}
#route-planner-panel .rp-btn-primary:hover { filter: brightness(1.1); }

#route-planner-panel .rp-body {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  position: relative;
}
#route-planner-panel .rp-body[hidden] { display: none; }

#route-planner-panel .rp-sidebar {
  width: 300px;
  flex-shrink: 0;
  background: var(--bg1);
  border-right: 1px solid var(--bdr);
  display: flex;
  flex-direction: column;
  transition: width 0.18s ease;
}
#route-planner-panel .rp-sidebar[hidden] { display: none; }
#route-planner-panel .rp-sidebar-collapse[hidden] { display: none; }
#route-planner-panel .rp-sidebar.collapsed {
  width: 0;
  border-right: 0;
  overflow: hidden;
}
#route-planner-panel .rp-sidebar.wide {
  width: 450px;
}
#route-planner-panel .rp-sidebar.wide ~ .rp-sidebar-collapse {
  left: 450px;
}
#route-planner-panel .rp-sidebar-body {
  flex: 1;
  overflow-y: auto;
}
/* Sidebar accordion sections. Visual language mirrors the right panel's
   .rp-rp-* accordion (uppercase header, caret, rotate-on-collapse) so both
   sides feel unified. Bodies do NOT impose padding/flex — each tab's
   render function owns its own internal layout (lists, toolbars, etc.). */
#route-planner-panel .rp-sb-section {
  border-bottom: 1px solid var(--bdr);
}
#route-planner-panel .rp-sb-header {
  width: 100%;
  background: var(--bg2);
  color: var(--txt);
  border: 0;
  text-align: left;
  padding: 10px 12px;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
}
#route-planner-panel .rp-sb-header:hover { color: var(--amber-ink); }
#route-planner-panel .rp-sb-caret {
  display: inline-block;
  transition: transform 0.15s ease;
  font-size: var(--fs-xs);
  color: var(--dim);
}
#route-planner-panel .rp-sb-section.collapsed .rp-sb-caret {
  transform: rotate(-90deg);
}
#route-planner-panel .rp-sb-body {
  /* Plain block flow — list renderers handle their own padding/spacing. */
  display: block;
}
#route-planner-panel .rp-sb-section.collapsed .rp-sb-body {
  display: none;
}
/* Climb detection thresholds (TKF-346) — the two selects the Display panel used
   to hold, now above the list they filter. Outside .rp-sb-body on purpose: that
   body is rewritten wholesale on every render, and the controls matter most
   when it says "No climbs detected". Padding and gap copy .rp-rp-body so the
   rows read exactly as they did on the right; the hairline below separates
   them from the list. Must collapse with the section, since the .rp-sb-body
   rule above doesn't reach them. */
#route-planner-panel .rp-sb-climb-opts {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--bdr);
}
#route-planner-panel .rp-sb-section.collapsed .rp-sb-climb-opts {
  display: none;
}
#route-planner-panel .rp-sidebar-widen {
  flex-shrink: 0;
  width: 100%;
  padding: 6px 12px;
  background: var(--bg2);
  color: var(--dim);
  border: none;
  border-top: 1px solid var(--bdr);
  font: inherit;
  font-size: var(--fs-xs);
  cursor: pointer;
  text-align: left;
}
#route-planner-panel .rp-sidebar-widen:hover { color: var(--amber-ink); background: var(--bg3); }

/* Collapse handle sits on the sidebar's right edge and floats above the
   map. When collapsed it still hangs off the left edge so the user can
   pop the sidebar back out. */
#route-planner-panel .rp-sidebar-collapse {
  position: absolute;
  top: 12px;
  left: 300px;
  transform: translateX(-50%);
  width: 22px;
  height: 36px;
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  cursor: pointer;
  z-index: 1000;
  font-size: var(--fs-base);
  line-height: 1;
  transition: left 0.18s ease;
}
#route-planner-panel .rp-sidebar.collapsed ~ .rp-sidebar-collapse {
  left: 0;
  transform: none;
}
#route-planner-panel .rp-sidebar-collapse:hover { border-color: var(--amber-ink); }

/* The sidebar collapse handle straddles the map's left edge (protruding
   11px when open, occupying 0–22px when collapsed). Offset the Leaflet
   top-left control stack so the fullscreen button clears the handle by a
   ~7px gap. Leaflet adds a 10px control margin-left, so
   corner-left = target_inset − 10.
     open:      11 protrusion + 7 gap = 18 inset → left 8
     collapsed: 22 handle width + 7 gap = 29 inset → left 19 */
#route-planner-panel .rp-main .leaflet-top.leaflet-left {
  left: 8px;
}
#route-planner-panel:has(.rp-sidebar.collapsed) .rp-main .leaflet-top.leaflet-left {
  left: 19px;
}

#route-planner-panel .rp-list { display: flex; flex-direction: column; gap: 6px; }

#route-planner-panel .rp-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--bdr);
  cursor: pointer;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
}
#route-planner-panel .rp-row:hover { background: var(--bg3); }

#route-planner-panel .rp-row-main { flex: 1; min-width: 0; }
#route-planner-panel .rp-row-title {
  font-weight: 600;
  font-size: var(--fs-base);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#route-planner-panel .rp-row-meta {
  font-size: var(--fs-xs);
  color: var(--dim);
  margin-top: 2px;
}
#route-planner-panel .rp-empty {
  color: var(--dim2);
  font-size: var(--fs-base);
  padding: 20px 8px;
  text-align: center;
}
#route-planner-panel .rp-error { color: var(--red); }

#route-planner-panel .rp-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  position: relative;
}
#route-planner-panel .rp-main[hidden] { display: none; }

#route-planner-panel .rp-map {
  flex: 1;
  min-height: 0;
  background: var(--bg2);
  /* Prevent iOS callout/action menus on long-press so touches reach
     Leaflet's tapHold handler for the route-planner context menu. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  touch-action: none;
}
/* Crosshair cursor — toggled via rpState.crosshairCursor.
   Leaflet adds .leaflet-container to the SAME element as .rp-map,
   so selectors must use .rp-crosshair.leaflet-container (no space).
   The native `crosshair` cursor is hard to spot on busy map tiles, so we
   ship a 32px SVG with a white halo + dark stroke + a small ring at the
   centre. Hotspot is the centre (16,16). Falls back to native if the
   browser refuses inline SVG cursors. */
#route-planner-panel .rp-map.rp-crosshair,
#route-planner-panel .rp-map.rp-crosshair * {
  cursor:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'><line x1='16' y1='1' x2='16' y2='31' stroke='white' stroke-width='3' stroke-linecap='round'/><line x1='1' y1='16' x2='31' y2='16' stroke='white' stroke-width='3' stroke-linecap='round'/><line x1='16' y1='1' x2='16' y2='31' stroke='%230f172a' stroke-width='1.4' stroke-linecap='round'/><line x1='1' y1='16' x2='31' y2='16' stroke='%230f172a' stroke-width='1.4' stroke-linecap='round'/><circle cx='16' cy='16' r='4' fill='none' stroke='white' stroke-width='2.4'/><circle cx='16' cy='16' r='4' fill='none' stroke='%230f172a' stroke-width='1'/></svg>") 16 16,
    crosshair !important;
}

/* Leaflet's default z-index sits above any fixed panels on the page, which
   can cause its tile layer to leak through modals/drawers. Clamp it here. */
#route-planner-panel .rp-map .leaflet-pane,
#route-planner-panel .rp-map .leaflet-top,
#route-planner-panel .rp-map .leaflet-bottom { z-index: 10; }

/* The overlay layers (hillshade/contour/Sectors) live in CUSTOM panes with an
   inline z-index (250–350) that outranks the clamp above, so without this they'd
   cover the route line, waypoints, tooltips and popups. Lift the interactive
   panes back above those overlays. Values stay in the same low band (≤ 390, and
   the basemap keeps tilePane's clamped z:10) so tiles still can't leak through
   the drawers (z:200). Order: hillshade 250 < contour 260 < sectors 350 <
   route 360 < markers 370 < tooltips 380 < popups 390. */
#route-planner-panel .rp-map .leaflet-overlay-pane { z-index: 360; }
#route-planner-panel .rp-map .leaflet-shadow-pane  { z-index: 365; }
#route-planner-panel .rp-map .leaflet-marker-pane  { z-index: 370; }
#route-planner-panel .rp-map .leaflet-tooltip-pane { z-index: 380; }
#route-planner-panel .rp-map .leaflet-popup-pane   { z-index: 390; }

/* Small hide/show profile toggle — sits at top-right, above profile panel */
#route-planner-panel .rp-profile-toggle {
  flex-shrink: 0;
  align-self: flex-end;
  background: none;
  border: none;
  color: var(--dim);
  padding: 2px 10px;
  font-size: var(--fs-xs);
  cursor: pointer;
}
#route-planner-panel .rp-profile-toggle:hover { color: var(--txt); }
#route-planner-panel .rp-profile-toggle[hidden] { display: none; }

#route-planner-panel .rp-profile {
  flex-shrink: 0;
  height: 150px;
  background: var(--bg1);
  border-top: 1px solid var(--bdr);
  padding: 0 10px 4px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}
#route-planner-panel .rp-profile[hidden] { display: none; }
/* Resize drag handle at the top of the profile box */
#route-planner-panel .rp-profile-resize {
  height: 6px;
  cursor: ns-resize;
  background: transparent;
  position: relative;
  flex-shrink: 0;
}
#route-planner-panel .rp-profile-resize::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 2px;
  transform: translateX(-50%);
  width: 36px;
  height: 3px;
  border-radius: 2px;
  background: var(--dim, var(--dim));
  opacity: 0.35;
}
#route-planner-panel .rp-profile-resize:hover::after {
  opacity: 0.7;
}
#route-planner-panel .rp-profile-chart-wrap {
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
  position: relative;
  overflow: hidden;
}
#route-planner-panel .rp-profile-chart-wrap canvas {
  display: block;
}
/* ── Profile window tabs (Route / Sector) ─────────────────────────────────── */
#route-planner-panel .rp-profile-tabs {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
  padding: 1px 0 3px;
}
#route-planner-panel .rp-profile-tabs[hidden] { display: none; }
#route-planner-panel .rp-profile-tab {
  border: 0;
  background: transparent;
  color: var(--dim, var(--dim));
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: 2px 9px;
  border-radius: 5px;
  cursor: pointer;
}
#route-planner-panel .rp-profile-tab.active { background: var(--bg0); color: var(--txt); }
#route-planner-panel .rp-profile-tab[hidden] { display: none; }
/* Only the active tab's panel shows. */
#route-planner-panel .rp-profile-panel { display: none; }
#route-planner-panel .rp-profile-panel.active { display: block; }
#route-planner-panel .rp-sector-profile { flex: 1; min-height: 0; overflow-y: auto; }
#route-planner-panel .rp-sector-profile.active { display: flex; flex-direction: column; gap: 3px; }
.rp-sp-head { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; font-size: var(--fs-sm); }
.rp-sp-name { font-weight: 600; color: var(--txt); }
.rp-sp-cat {
  font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: 0.03em;
  color: #fff; background: #e8792e; border-radius: 8px; padding: 0 6px;
}
.rp-sp-meta { color: var(--dim, var(--dim)); }
/* "Surfaced road ends at the summit — the climb continues as gravel" (TKB-285).
   In-panel, so tokens here, unlike the popup twin which is drawn on the basemap. */
.rp-sp-cont {
  font-size: var(--fs-sm); color: var(--dim);
  margin: 4px 0 0; padding-left: 8px; border-left: 2px solid var(--bdr);
}
/* Difficulty-score chip (colour set inline per band) — shared by the popup + tab. */
.rp-diff-chip {
  display: inline-block;
  padding: 0 6px;
  border-radius: 8px;
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.6;
  vertical-align: middle;
}
/* Fills the remaining window height like the route elevation chart, so it scales
   when the profile window is resized (fixed rows below keep their size). */
.rp-sp-chart { width: 100%; flex: 1 1 auto; min-height: 44px; }
.rp-sp-svg { width: 100%; height: 100%; display: block; background: var(--bg0); border-radius: 4px; }
.rp-sp-legend { display: flex; flex-wrap: wrap; gap: 8px; font-size: var(--fs-xs); color: var(--dim, var(--dim)); }
.rp-sp-key { display: inline-flex; align-items: center; gap: 3px; }
.rp-sp-key i { width: 11px; height: 8px; border-radius: 2px; display: inline-block; }
.rp-sp-pace { font-size: var(--fs-sm); color: var(--txt); font-family: var(--font-data); font-variant-numeric: tabular-nums; }
.rp-sp-adv { color: var(--dim, var(--dim)); }
.rp-sp-effort { display: flex; align-items: center; gap: 8px; font-size: var(--fs-xs); color: var(--dim, var(--dim)); }
.rp-sp-effort input[type=range] { flex: 1; margin: 0; }
.rp-sp-noprofile { font-size: var(--fs-sm); color: var(--dim, var(--dim)); padding: 8px 0; }
/* ── Route summary sidebar section ─────────────────────────────────────── */
/* At-a-glance summary of the open route (distance / time / climbing) plus the
   surface + roads composition bars, moved here from under the elevation
   profile. Rendered by renderRouteSummary() in route-planner.js. */
#route-planner-panel .rp-summary {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
}
#route-planner-panel .rp-summary-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: var(--fs-base);
  color: var(--txt);
}
#route-planner-panel .rp-summary-ic {
  flex: none;
  width: 18px;
  text-align: center;
  font-size: var(--fs-base);
  opacity: 0.8;
}
#route-planner-panel .rp-summary-val {
  font-weight: 600;
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
}
#route-planner-panel .rp-summary-lbl {
  color: var(--dim2);
  font-size: var(--fs-sm);
}
/* The avg-speed control on the ride-time row (TKF-332): "ride time at [22] km/h".
   It reuses the panel's number+suffix styling, narrowed to the two-and-a-half
   digits it holds so the row stays one line. */
#route-planner-panel .rp-summary-speed {
  display: inline-flex;
  align-items: baseline;
  margin-left: 2px;
}
#route-planner-panel .rp-summary-speed .rp-rp-suffixed input[type="number"] {
  width: 52px;
  padding: 2px 5px;
  font-size: var(--fs-sm);
}
/* Surface / roads composition blocks (cycle.travel style). */
#route-planner-panel .rq-block {
  padding: 4px 12px 10px;
}
#route-planner-panel .rq-block-title {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--fs-micro);
  font-weight: 600;
  color: var(--dim);
  margin-bottom: 5px;
}
#route-planner-panel .rq-bar {
  display: flex;
  height: 9px;
  border-radius: 4px;
  overflow: hidden;
  background: rgba(0,0,0,0.10);
}
#route-planner-panel .rq-bar-seg { height: 100%; }
#route-planner-panel .rq-legend {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 6px;
}
#route-planner-panel .rq-legend-row {
  display: grid;
  /* minmax(0,1fr) lets the label column shrink so a long label ellipsises
     instead of wrapping to a second line or overflowing the row. */
  grid-template-columns: 14px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-sm);
  color: var(--txt);
}
#route-planner-panel .rq-swatch {
  flex: none;
  width: 11px;
  height: 11px;
  border-radius: 3px;
}
#route-planner-panel .rq-legend-label {
  color: var(--txt);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#route-planner-panel .rq-legend-dist,
#route-planner-panel .rq-legend-pct {
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
  color: var(--dim2);
  text-align: right;
}
#route-planner-panel .rq-legend-pct { min-width: 38px; }
/* A row or bar segment lights its category on the route line (TKF-316). The
   pointer is withheld on a block the planner cannot resolve on this route —
   `.rq-inert`, set by markRqRows: Trail/IMBA always (the line only carries a
   four-way fold of those grades), Roads on a save that predates `cls`.

   The lit row is a PINNED state, not a hover: it stays while the rider clicks
   the map and zooms in on what lit up (TKB-360), so it has to read as selected
   from across the panel, not merely as tinted. Same idiom as .nav-link.active —
   amber wash, amber-ink label, 600 weight — plus the climb list's amber left
   rule, and the block's other rows dim (.rq-has-active) so one row stands out
   the way one colour does on the line. Negative margin lets the wash run a
   little past the text on a row that has no padding of its own. */
#route-planner-panel .rq-block[data-rq-kind]:not(.rq-inert) .rq-legend-row,
#route-planner-panel .rq-block[data-rq-kind]:not(.rq-inert) .rq-bar-seg { cursor: pointer; }
#route-planner-panel .rq-block[data-rq-kind]:not(.rq-inert) .rq-legend-row {
  position: relative;
  padding: 2px 6px;
  margin: 0 -6px;
  border-radius: 4px;
  transition: background 0.12s;
}
#route-planner-panel .rq-block[data-rq-kind]:not(.rq-inert) .rq-legend-row::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  border-radius: 2px;
  background: var(--amber-ink);
  opacity: 0;
  transition: opacity 0.12s;
}
#route-planner-panel .rq-block[data-rq-kind]:not(.rq-inert) .rq-legend-row:hover { background: var(--bg2); }
#route-planner-panel .rq-legend-row.rq-active,
#route-planner-panel .rq-legend-row.rq-active:hover { background: rgba(var(--amber-wash), 0.14); }
#route-planner-panel .rq-legend-row.rq-active::before { opacity: 1; }
#route-planner-panel .rq-legend-row.rq-active .rq-legend-label { color: var(--amber-ink); font-weight: 600; }
#route-planner-panel .rq-legend-row.rq-active .rq-legend-dist,
#route-planner-panel .rq-legend-row.rq-active .rq-legend-pct { color: var(--txt); }
#route-planner-panel .rq-block.rq-has-active .rq-legend-row:not(.rq-active) { opacity: 0.55; }
#route-planner-panel .rq-block.rq-has-active .rq-legend-row:not(.rq-active):hover { opacity: 1; }
/* A layer switch that has no meaning on the current basemap (TKF-225). Dimmed rather
   than removed: a control that comes and goes makes the panel reflow under the cursor,
   and the title attribute carries the reason. */
#route-planner-panel .rp-rp-check.rp-check-disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
/* "No graded trail on this route" — the honest empty state for the trail-difficulty
   blocks (TKB-225). Dimmed and unbarred so it reads as an absence of data rather than
   as a measurement of zero. */
#route-planner-panel .rq-none {
  font-size: var(--fs-sm);
  line-height: 1.4;
  color: var(--dim2);
}
/* Drag-select highlight overlay — positioned by profile.js */
.rp-profile-selection {
  position: absolute;
  pointer-events: none;
  background: rgba(var(--amber-wash), 0.18);
  z-index: 2;
  display: none;
}
/* Draggable edge handles — thin strips at left/right edge */
.rp-profile-sel-edge {
  position: absolute;
  top: 0; bottom: 0;
  width: 8px;
  pointer-events: auto;
  cursor: ew-resize;
  z-index: 3;
}
.rp-profile-sel-edge::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 2px;
  background: var(--amber);
  border-radius: 1px;
}
.rp-profile-sel-edge-l {
  left: -4px;
}
.rp-profile-sel-edge-l::after {
  left: 4px;
}
.rp-profile-sel-edge-r {
  right: -4px;
}
.rp-profile-sel-edge-r::after {
  right: 4px;
}
.rp-profile-sel-edge:hover::after {
  width: 3px;
  background: var(--amber-ink);
}

#route-planner-panel .rp-statusbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 14px;
  background: var(--bg1);
  border-top: 1px solid var(--bdr);
  font-size: var(--fs-sm);
}
#route-planner-panel .rp-route-name {
  color: var(--amber-ink);
  font-size: var(--fs-sm);
  font-weight: 600;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#route-planner-panel .rp-route-name:empty { display: none; }

/* Location search — top of the left column's Plan block (TKF-429). */
#route-planner-panel .rp-search {
  position: relative;
  width: 100%;
}
#route-planner-panel .rp-search input {
  width: 100%;
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 6px;
  padding: 6px 10px;
  font: inherit;
  font-size: var(--fs-sm);
  box-sizing: border-box;
}
#route-planner-panel .rp-search input:focus {
  outline: none;
  border-color: var(--amber-ink);
}
#route-planner-panel .rp-search-results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--bg2);
  border: 1px solid var(--bdr);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  z-index: 1500;
  max-height: 280px;
  overflow-y: auto;
}
#route-planner-panel .rp-search-results[hidden] { display: none; }
#route-planner-panel .rp-search-item,
#route-planner-panel .rp-search-empty {
  padding: 8px 10px;
  font-size: var(--fs-sm);
  cursor: pointer;
  border-bottom: 1px solid var(--bdr);
}
#route-planner-panel .rp-search-item:last-child { border-bottom: 0; }
#route-planner-panel .rp-search-item:hover { background: var(--bg3); }
/* Distance badge on a far-away hit (TKF-307). Dim and right-aligned: it is a
   caveat on the row, not a second label competing with the place name. */
#route-planner-panel .rp-search-far {
  float: right;
  margin-left: 8px;
  color: var(--dim2);
  font-size: var(--fs-xs);
  white-space: nowrap;
}
#route-planner-panel .rp-search-empty {
  color: var(--dim2);
  cursor: default;
}

#route-planner-panel .rp-endpoint-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
}
#route-planner-panel .rp-search-endpoint {
  display: flex;
  align-items: center;
  gap: 6px;
}
#route-planner-panel .rp-search-endpoint input {
  flex: 1;
  min-width: 0;
}
#route-planner-panel .rp-endpoint-label {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: .4px;
  width: 38px;
  flex-shrink: 0;
}

#route-planner-panel .rp-icon-btn {
  padding: 6px 10px;
  font-size: var(--fs-md);
  line-height: 1;
}
#route-planner-panel .rp-btn.active {
  border-color: var(--amber-ink);
  color: var(--amber-ink);
}

/* Compact button variant — used in list filter bars. */
#route-planner-panel .rp-btn-sm {
  padding: 5px 9px;
  font-size: var(--fs-sm);
}

/* Search + filter toggle row above each list. */
#route-planner-panel .rp-list-search {
  display: flex;
  gap: 6px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--bdr);
}
#route-planner-panel .rp-list-q {
  flex: 1;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--bdr);
  border-radius: 4px;
  background: var(--bg0);
  color: var(--txt);
  font: inherit;
  font-size: var(--fs-base);
}
#route-planner-panel .rp-list-q:focus {
  outline: none;
  border-color: var(--amber-ink);
}

/* Collapsible filter panel. */
#route-planner-panel .rp-list-filter {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--bdr);
  background: var(--bg2);
}
#route-planner-panel .rp-filter-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-sm);
  color: var(--dim);
}
#route-planner-panel .rp-filter-row > span:first-child {
  flex: 0 0 90px;
}
#route-planner-panel .rp-filter-row select,
#route-planner-panel .rp-filter-row input {
  flex: 1;
  min-width: 0;
  padding: 4px 6px;
  border: 1px solid var(--bdr);
  border-radius: 4px;
  background: var(--bg0);
  color: var(--txt);
  font: inherit;
  font-size: var(--fs-sm);
}
#route-planner-panel .rp-filter-range {
  display: flex;
  gap: 4px;
  flex: 1;
  min-width: 0;
}

/* POI sidebar rows + map pins. */
#route-planner-panel .rp-poi-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: var(--bg2);
  border: 1px solid var(--bdr);
  border-radius: 6px;
  cursor: pointer;
  margin-bottom: 6px;
}
#route-planner-panel .rp-poi-row:hover { background: var(--bg3); }
#route-planner-panel .rp-poi-glyph {
  font-size: var(--fs-lg);
  flex-shrink: 0;
}

.leaflet-marker-icon.rp-poi {
  background: transparent !important;
  border: none !important;
}
.leaflet-marker-icon.rp-poi .rp-poi-pin {
  width: 28px;
  height: 28px;
  background: var(--amber-ink);
  border: 2px solid var(--bg0);
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
}
.leaflet-marker-icon.rp-poi .rp-poi-pin > * { transform: rotate(45deg); }

/* Chad POI hover tooltip on map */
.rp-poi-highlight-tip {
  background: rgba(231, 76, 60, 0.9);
  border: none;
  border-radius: 4px;
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: 600;
  padding: 4px 8px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.4);
  white-space: nowrap;
}
.rp-poi-highlight-tip::before {
  border-top-color: rgba(231, 76, 60, 0.9) !important;
}
.rp-poi-highlight-tip.rp-poi-highlight-amber {
  background: var(--amber);
  color: var(--on-amber);
}
.rp-poi-highlight-tip.rp-poi-highlight-amber::before {
  border-top-color: var(--amber) !important;
}
.rp-highlight-popup { text-align: center; }
.rp-highlight-name {
  font-size: var(--fs-base);
  font-weight: 700;
  margin-bottom: 6px;
  color: #111;
}
.rp-highlight-details {
  text-align: left;
  margin: 4px 0 8px;
  padding: 6px 0;
  border-top: 1px solid var(--bdr);
  border-bottom: 1px solid var(--bdr);
  font-size: var(--fs-xs);
  color: #333;
  line-height: 1.4;
}
.rp-highlight-row { margin: 2px 0; word-break: break-word; }
.rp-highlight-row.rp-highlight-open   { color: var(--green, var(--green)); font-weight: 600; }
.rp-highlight-row.rp-highlight-closed { color: var(--red, var(--red));   font-weight: 600; }
.rp-highlight-label { font-weight: 700; color: #555; }
.rp-highlight-row a { color: #2563eb; text-decoration: none; }
.rp-highlight-row a:hover { text-decoration: underline; }
.rp-highlight-actions { display: flex; gap: 6px; justify-content: center; }
.rp-highlight-pin, .rp-highlight-via {
  background: var(--blue);
  color: #fff;
  border: none;
  border-radius: 5px;
  padding: 4px 10px;
  font-family: inherit;
  font-size: var(--fs-xs);
  font-weight: 700;
  cursor: pointer;
  transition: filter .15s;
}
.rp-highlight-pin:hover, .rp-highlight-via:hover { filter: brightness(1.15); }

/* Custom cue flag markers — distinct from POIs (square teal flag with
   pole) so the user can tell at a glance which is which. */
.leaflet-marker-icon.rp-cue-flag-icon {
  background: transparent !important;
  border: none !important;
}
.leaflet-marker-icon.rp-cue-flag-icon .rp-cue-flag {
  position: relative;
  width: 26px;
  height: 26px;
  background: var(--teal);
  color: #ffffff;
  border: 2px solid var(--bg0);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-base);
  line-height: 1;
  font-weight: 700;
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
  cursor: pointer;
}
.leaflet-marker-icon.rp-cue-flag-icon .rp-cue-flag::after {
  content: '';
  position: absolute;
  left: 11px;
  top: 100%;
  width: 2px;
  height: 6px;
  background: var(--bg0);
}

/* POI edit popup form (inside Leaflet popup). */
.rp-poi-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 220px;
}
.rp-poi-form select,
.rp-poi-form input,
.rp-poi-form textarea {
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  padding: 6px 8px;
  font: inherit;
  font-size: var(--fs-sm);
}
.rp-poi-form textarea { resize: vertical; }
.rp-poi-eta {
  font-size: var(--fs-xs);
  color: var(--dim);
  margin-bottom: 2px;
}
.rp-poi-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}
.rp-poi-form .rp-btn {
  background: var(--bg3);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  padding: 5px 10px;
  font: inherit;
  font-size: var(--fs-sm);
  cursor: pointer;
}
.rp-poi-form .rp-btn.danger {
  color: var(--red);
  border-color: var(--red);
}

/* Climb sidebar rows — flat rows parted by a hairline, the same list language
   as .rp-row and .rp-cue-row above. They were bordered cards until TKB-288:
   three outlined boxes stacked inside an outlined accordion inside an outlined
   sidebar, where the frames read as clutter rather than as structure.
   The border colour used to carry the map↔list hover link, so with the border
   gone that moves to an amber left rule — .rp-climb-row-hover is driven from
   the elevation chart, so it has to be readable at a glance, not just a tint. */
#route-planner-panel .rp-climb-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--bdr);
  cursor: pointer;
  transition: background 0.12s;
}
#route-planner-panel .rp-climb-row:last-child { border-bottom: 0; }
#route-planner-panel .rp-climb-row::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--amber-ink);
  opacity: 0;
  transition: opacity 0.12s;
}
#route-planner-panel .rp-climb-row:hover,
#route-planner-panel .rp-climb-row-hover { background: var(--bg2); }
#route-planner-panel .rp-climb-row:hover::before,
#route-planner-panel .rp-climb-row-hover::before { opacity: 1; }
#route-planner-panel .rp-climb-cat {
  flex: 0 0 auto;
  min-width: 38px;
  text-align: center;
  font-size: var(--fs-xs);
  font-weight: 700;
  padding: 4px 6px;
  border-radius: 4px;
  letter-spacing: 0.02em;
}
/* Climb category is an ordered data scale, not chrome: HC is hardest and the
   ramp must stay monotonic. These are deliberately theme-INDEPENDENT solid
   fills — a Cat 1 climb is the same red on paper as on the dark ground.
   Do not tokenise them. (TKF-226)
   Cat 3 was the exception that proved it: as var(--amber-ink) it followed the
   theme, so on the dark ground it painted white on #f59e0b at 2.15:1 while the
   comment above claimed it could not. Pinned to the share page's #d97706, and
   the analysis drawer now uses these same five (TKB-293).

   THE INK CHANGES HALFWAY DOWN AND THE FILLS DO NOT (TKB-294). This block used
   to say white read on all five; it did not. White clears 4.5:1 on the two dark
   reds (10.02:1, 6.47:1) and is nowhere near it on the orange/amber/yellow half
   — 3.56, 3.19, 2.94, where 12px bold text needs 4.5 — so those three take a
   near-black ink instead: 4.97, 5.55, 6.02. Darkening the FILLS was the other
   way out and was rejected: it would have put HC and Cat 4 at the same weight,
   and the badge would stop getting visibly lighter as the climb gets easier.

   #1b1813 is not a token value, deliberately. palette.js's repaintDom() is
   keyed by colour VALUE, and the obvious near-black — #201d17 — is light-theme
   --txt, which a theme switch would flip to near-white: white on yellow, the
   exact thing this fixes (TKB-251, TKB-252). */
#route-planner-panel .rp-climb-cat-hc   { background: #7f1d1d; color: #fff; }
#route-planner-panel .rp-climb-cat-cat1 { background: #b91c1c; color: #fff; }
#route-planner-panel .rp-climb-cat-cat2 { background: #ea580c; color: #1b1813; }
#route-planner-panel .rp-climb-cat-cat3 { background: #d97706; color: #1b1813; }
#route-planner-panel .rp-climb-cat-cat4 { background: #ca8a04; color: #1b1813; }
/* No category means no colour to carry, so no pill either — a plain tabular
   index, held at the pill's width so the titles line up in one column whether
   a climb is categorised or not (TKB-288). */
#route-planner-panel .rp-climb-cat-none {
  background: none;
  color: var(--dim);
  font-weight: 600;
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  padding-left: 0;
  padding-right: 0;
}

/* Cue sheet toolbar (export PDF button + hint). */
#route-planner-panel .rp-cues-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 6px 10px;
  border-bottom: 1px solid var(--bdr);
  margin-bottom: 4px;
}
#route-planner-panel .rp-cues-toolbar-hint {
  font-size: var(--fs-xs);
  color: var(--dim);
  flex: 1;
}

/* Custom-cue rows in the merged cue list. */
#route-planner-panel .rp-cue-row-custom {
  background: rgba(20, 184, 166, 0.10);
}
#route-planner-panel .rp-cue-row-custom .rp-cue-text {
  font-weight: 600;
  color: var(--teal);
}

/* Cue sheet rows — last column reserved for the ETA at that turn, sized
   to content so it collapses to 0 when no rider speed is set. */
#route-planner-panel .rp-cue-row {
  display: grid;
  grid-template-columns: 54px 24px 1fr auto;
  gap: 6px;
  align-items: center;
  padding: 6px 8px;
  border-bottom: 1px solid var(--bdr);
  font-size: var(--fs-sm);
  cursor: pointer;
}
#route-planner-panel .rp-cue-eta {
  font-size: var(--fs-xs);
  color: var(--dim);
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 44px;
}
#route-planner-panel .rp-cue-row:hover { background: var(--bg2); }
#route-planner-panel .rp-cue-dist {
  font-weight: 600;
  color: var(--amber-ink);
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
  font-size: var(--fs-xs);
}
#route-planner-panel .rp-cue-dir {
  font-size: var(--fs-md);
  color: var(--txt);
  text-align: center;
}
#route-planner-panel .rp-cue-text {
  color: var(--txt);
  line-height: 1.3;
}
#route-planner-panel #rp-status-dist {
  font-weight: 600;
  color: var(--amber-ink);
  font-size: var(--fs-base);
  min-width: 120px;
}
#route-planner-panel .rp-status-hint {
  color: var(--dim2);
  flex: 1;
}
#route-planner-panel .rp-status-state { color: var(--dim); white-space: nowrap; }
#route-planner-panel .rp-status-state.dirty   { color: var(--orange); font-weight: 600; }
#route-planner-panel .rp-status-state.saved   { color: var(--green, var(--green)); font-weight: 600; }
#route-planner-panel .rp-status-state.routing { color: var(--blue); }
/* Collapse empty status spans so they don't leave a phantom flex gap in the
   slimmed status bar (distance slot is idle-empty; state is empty when clean). */
#route-planner-panel #rp-status-dist:empty,
#route-planner-panel .rp-status-state:empty { display: none; }

#route-planner-panel .rp-btn {
  background: var(--bg3);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 6px;
  padding: 7px 14px;
  font-weight: 600;
  cursor: pointer;
}
#route-planner-panel .rp-btn:hover:not(:disabled) { border-color: var(--amber-ink); }
#route-planner-panel .rp-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

#route-planner-panel .rp-btn-accent {
  background: var(--amber);
  color: var(--on-amber);
  border-color: var(--amber);
}
#route-planner-panel .rp-btn-accent:hover:not(:disabled) {
  background: var(--amber-ink);
  border-color: var(--amber-ink);
}
#route-planner-panel .rp-btn-accent:disabled {
  opacity: 0.5;
}
/* Out & back toggle in Location section */
#route-planner-panel .rp-toggle-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0 0;
  cursor: pointer;
  font-size: var(--fs-base);
  color: var(--dim);
  user-select: none;
}
#route-planner-panel .rp-toggle-row:hover {
  color: var(--txt);
}
#route-planner-panel .rp-toggle-row input[type="checkbox"] {
  accent-color: var(--accent, var(--blue));
  width: 16px;
  height: 16px;
  cursor: pointer;
}
#route-planner-panel .rp-toggle-label {
  flex: 1;
}

/* Active row in sidebar (currently open route). */
#route-planner-panel .rp-row.active {
  background: var(--bg3);
}

/* Waypoint markers: divIcons need their default background/border cleared
   so only our SVG/dot shows. */
.leaflet-marker-icon.rp-wp {
  background: transparent !important;
  border: none !important;
  cursor: grab;
}
.leaflet-marker-icon.rp-wp:active { cursor: grabbing; }

/* Direction arrow markers along the route polyline. */
.rp-arrow-marker {
  background: transparent !important;
  border: none !important;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Distance markers (1, 2, 3…) along the route. */
.rp-dist-marker {
  background: var(--bg0, var(--bg0)) !important;
  border: 2px solid var(--amber, var(--amber-ink)) !important;
  border-radius: 50% !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
  font-weight: 700;
  color: var(--amber, var(--amber));
  line-height: 1;
}
.rp-dist-marker span {
  display: block;
  text-align: center;
  width: 100%;
}

.leaflet-marker-icon.rp-wp-flag svg {
  display: block;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
}

/* Out-and-back mode: the start and finish flags share a coordinate. By
   default they're splayed into an X (rp-wp-cross-*); once the user drags
   the start, they fall back to a vertical back-to-back layout (no extra
   class — the pre-mirrored start SVG handles its own pole-on-right look). */
.leaflet-marker-icon.rp-wp-cross-left svg {
  transform: rotate(-45deg);
  transform-origin: 24px 30px;   /* mirrored start flagpole base */
}
.leaflet-marker-icon.rp-wp-cross-right svg {
  transform: rotate(45deg);
  transform-origin: 2px 30px;    /* finish flagpole base */
}

/* Centre the dot inside its 22×22 icon box. The box is anchored at its CENTRE
   (iconAnchor [11,11] in editor.js), but a plain block <span> sits at the box's
   top-left — and with the global `box-sizing: border-box` reset the 16px dot
   (border inside) then rendered with its centre at (8,8), i.e. 3px up-and-left
   of the waypoint's true coordinate. That's why the route line appeared to run
   past the SIDE of a waypoint instead of through its centre. Flex-centring pins
   the dot's centre to the anchor regardless of dot size/border/box-sizing.
   Flags are deliberately excluded — they anchor at the flagpole base, not the
   centre (iconAnchor [2,30]). */
.leaflet-marker-icon.rp-wp-mid,
.leaflet-marker-icon.rp-wp-return,
.leaflet-marker-icon.rp-wp-lock {
  display: flex;
  align-items: center;
  justify-content: center;
}

.leaflet-marker-icon.rp-wp-mid .rp-wp-dot {
  display: block;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--amber);
  border: 2px solid var(--bg0);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* Return-leg waypoints — pink dots matching RETURN_LEG_COLOR (editor.js) and the
   return polyline, so they read as part of the return half. */
.leaflet-marker-icon.rp-wp-return .rp-wp-dot-return {
  display: block;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--pink);
  border: 2px solid var(--bg0);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* Lock-mode anchors — slightly smaller blue dots so users can see at a
   glance which segments still hold the original imported GPS line versus
   the editable amber dots. */
.leaflet-marker-icon.rp-wp-lock .rp-wp-dot-lock {
  display: block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--blue);
  border: 2px solid var(--bg0);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  margin: 1px;
}

/* Hover ghost — a translucent "add a waypoint here" marker that tracks the
   cursor along the route line so the left-click-to-insert affordance is
   obvious. Sized/coloured like the amber mid-waypoint it becomes, but
   see-through with a plus glyph. The marker itself is non-interactive so it
   never intercepts the line's mouse events. */
.leaflet-marker-icon.rp-wp-ghost-wrap {
  background: transparent !important;
  border: none !important;
}
.leaflet-marker-icon .rp-wp-ghost {
  position: relative;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(var(--amber-wash), 0.5);
  border: 2px solid color-mix(in srgb, var(--bg0) 60%, transparent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}
.leaflet-marker-icon .rp-wp-ghost::before,
.leaflet-marker-icon .rp-wp-ghost::after {
  content: '';
  position: absolute;
  background: var(--bg0);
  opacity: 0.75;
}
.leaflet-marker-icon .rp-wp-ghost::before { left: 50%; top: 3px; bottom: 3px; width: 2px; transform: translateX(-50%); }
.leaflet-marker-icon .rp-wp-ghost::after  { top: 50%; left: 3px; right: 3px; height: 2px; transform: translateY(-50%); }

/* Waypoint context menu (appended to body so it can escape #rp-map).
   z-index sits above the collection detail modal backdrop (10000) so the
   menu spawned from inside the overlay isn't clipped behind it. */
.rp-wp-menu {
  position: fixed;
  z-index: 10002;
  min-width: 170px;
  background: var(--bg2);
  border: 1px solid var(--bdr);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  padding: 4px 0;
  font-size: var(--fs-base);
  color: var(--txt);
  user-select: none;
}
.rp-wp-menu[hidden] { display: none; }
.rp-wp-menu-item {
  padding: 7px 14px;
  cursor: pointer;
}
.rp-wp-menu-item:hover { background: var(--bg3); }
.rp-wp-menu-item.disabled {
  color: var(--dim3);
  cursor: default;
}
.rp-wp-menu-item.disabled:hover { background: transparent; }
.rp-wp-menu-item.danger { color: var(--red); }
.rp-wp-menu-item.danger:hover { background: var(--red); color: #fff; }
.rp-wp-menu-sep {
  height: 1px;
  background: var(--bdr);
  margin: 4px 0;
}


/* ── Full-screen map mode ─────────────────────────────────────────────── */
/* Hides the sidebar and its collapse handle so the map + elevation profile
   fill the entire width. (The right panel it also hid went in TKF-429.) */
#route-planner-panel.rp-fullscreen .rp-sidebar,
#route-planner-panel.rp-fullscreen .rp-sidebar-collapse {
  width: 0;
  border: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition: width 0.18s ease, opacity 0.18s ease;
}

/* Leaflet fullscreen button (top-left) */
.rp-fullscreen-btn {
  width: 36px;
  height: 36px;
  background: var(--bg1, var(--bg1));
  color: var(--txt, var(--txt));
  border: 2px solid rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  font-size: var(--fs-lg);
  line-height: 30px;
  text-align: center;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.rp-fullscreen-btn:hover {
  background: var(--bg2, var(--bg2));
  color: var(--amber, var(--amber));
}

/* ── On-map "Layers" control (top-right) ───────────────────────────────
   Collapsed = an icon+label button. Open = a translucent panel hosting
   the relocated #rp-layers-panel. The inner .rp-rp-field/.rp-rp-check/
   .rp-rp-poi-layers controls keep their existing styling because #rp-map
   is still a descendant of #route-planner-panel. */
/* Align the fullscreen (top-left) and Map Layers (top-right) Leaflet
   controls with the sidebar collapse chevron, which is at top:12px,
   height:36px. Match top + height so they line up. Map Layers sits at
   Leaflet's own 10px from the right edge: the 18px it had was to clear the
   right panel's handle, which went with the panel (TKF-429). */
#route-planner-panel .rp-map .leaflet-top .rp-fullscreen-btn,
#route-planner-panel .rp-map .leaflet-top .tk-ml-ctl {
  margin-top: 12px;
}
/* The scale bar's place in the bottom-right corner is core/map-layers.css now
   (TKB-302). It used to be pinned here with two eyeball offsets — `right: 50px`
   to clear the zoom control and `bottom: 32px` to lift it — which landed 6px
   above the zoom's bottom edge, and which the two activity maps mounting the
   same control never had at all. The shared rule lays the corner out instead of
   measuring it, so all three surfaces agree by construction. */
/* The control chrome — button, drop-down panel, frosted background, the TKB-243
   opacity floor — moved to core/map-layers.css when the Map options section
   became shared (TKF-257). What is left here is only what the PLANNER's own rows
   need once they are living inside that panel. */

/* Hidden until map.js reparents it into the shared section, so it never flashes
   in the sidebar during the wire()→initMap() gap. */
#rp-layers-panel { display: none; }
/* Once reparented it becomes one child of the shared section's flex column, so
   it has to lay its own rows out — a plain `display: block` would collapse the
   6px gap the shared rows above it sit on. */
.tk-ml-section-body #rp-layers-panel {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* All label text in the panel: one colour, so it reads as a unit — the sidebar
   styles otherwise dim some labels to --dim/--dim2. !important to beat those
   id-scoped colour rules cleanly. */
#route-planner-panel .tk-ml-body .rp-rp-field > span,
#route-planner-panel .tk-ml-body .rp-rp-check span,
#route-planner-panel .tk-ml-body .rp-rp-poi-layers-head,
#route-planner-panel .tk-ml-body .rp-rp-hint,
#route-planner-panel .tk-ml-body label {
  color: var(--txt-hi) !important;
}
/* Planner rows inside the over-map panel: tighten the sidebar spacing a touch,
   and match the gap the shared rows above them sit on. */
.tk-ml-body .rp-rp-field,
.tk-ml-body .rp-rp-check,
.tk-ml-body .rp-rp-row-split { margin: 0; }
/* Heatmap / Sectors / POI layers are still the planner's own collapsible groups
   and still hang off .rp-rp-poi-layers, but they are SIBLINGS of the Map options
   section in the panel, not rows inside it — map.js hoists them out of
   #rp-layers-panel after reparenting it (TKB-328). So they sit on the shared
   section rhythm, `.tk-ml-section + .tk-ml-section`: 8px above the divider, 8px
   below it. .rp-rp-poi-layers supplies the divider and the 8px under it already;
   only the margin above needs restating, and it needs the id to outrank
   `#route-planner-panel .rp-rp-poi-layers { margin-top: 4px }` — the sidebar
   value, which is what a bare-class rule here quietly lost to. */
#route-planner-panel .tk-ml-body .rp-rp-poi-layers { margin-top: 8px; }
/* …and their rows sit on the same 6px rhythm as the shared rows above (TKB-310).
   The `margin: 0` above is half of a pair: it strips the sidebar's per-row
   margins so the PARENT's gap owns the spacing. .tk-ml-section-body and
   #rp-layers-panel both supply that gap; these group bodies never had a layout
   rule at all, so they stayed plain blocks and their rows ran flush while
   Basemap and Polyline style breathed. */
.tk-ml-body .rp-rp-poi-layers-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* The POI grid brought its own bottom margin from the sidebar; with a gap above
   it that reads as a double space. The gap owns the rhythm now. Needs the id in
   the selector to outrank #route-planner-panel .rp-poi-layer-grid. */
#route-planner-panel .tk-ml-body .rp-poi-layer-grid { margin-bottom: 0; }

/* Custom-objective sliders (Route style = "Custom (sliders)"). */
#route-planner-panel .rp-custom-sliders {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 2px 0 4px;
  padding: 8px 10px;
  background: var(--bg2);
  border: 1px solid var(--bdr);
  border-radius: 6px;
}
#route-planner-panel .rp-custom-sliders[hidden] { display: none; }
#route-planner-panel .rp-custom-hint {
  font-size: var(--fs-xs);
  color: var(--dim2);
}
#route-planner-panel .rp-custom-slider { display: flex; flex-direction: column; gap: 2px; }
#route-planner-panel .rp-custom-ends {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-xs);
  color: var(--dim2);
}
#route-planner-panel .rp-custom-slider input[type="range"] {
  width: 100%;
  margin: 0;
  accent-color: var(--amber);
  cursor: pointer;
}

/* ── Routing + Preferences (TKF-428) ─────────────────────────────────────
   One row in Location & Routing: the Routing button, which names the current
   choice, and a square gear. Each opens a .rp-pop beside it. */
#route-planner-panel .rp-popbar {
  display: flex;
  align-items: stretch;
  gap: 6px;
}
#route-planner-panel .rp-routing-btn {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  text-align: left;
  font: inherit;
}
#route-planner-panel .rp-routing-btn-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
/* The label is the amber, as on the draw-mode indicator (TKF-310). */
#route-planner-panel .rp-routing-btn-kicker {
  color: var(--amber-ink);
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
#route-planner-panel .rp-routing-btn-value,
#route-planner-panel .rp-routing-btn-extra {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#route-planner-panel .rp-routing-btn-value {
  color: var(--txt);
  font-size: var(--fs-base);
  font-weight: 600;
}
#route-planner-panel .rp-routing-btn-extra {
  color: var(--dim2);
  font-size: var(--fs-xs);
}
#route-planner-panel .rp-routing-btn-extra[hidden] { display: none; }
#route-planner-panel .rp-routing-btn-caret {
  flex-shrink: 0;
  color: var(--dim);
  font-size: var(--fs-xs);
}
#route-planner-panel .rp-prefs-btn {
  flex: 0 0 44px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--txt);
}
/* The nav rail's Settings gear, at a size that holds its own beside the
   Routing button — the ⚙ text glyph rendered at about half this and read as
   a speck (Darren, 2026-09-25: "Is this cog really noticeable?"). */
#route-planner-panel .rp-prefs-icon { width: 22px; height: 22px; display: block; }
#route-planner-panel .rp-prefs-btn:hover:not(:disabled),
#route-planner-panel .rp-prefs-btn.active { color: var(--amber-ink); }
#route-planner-panel .rp-routing-btn.active,
#route-planner-panel .rp-prefs-btn.active { border-color: var(--amber-ink); }

/* The popovers. position:fixed and placed by positionPop() in JS, so no
   scrolling or collapsing ancestor can clip them. Same frosted chrome as the Map options
   panel (core/map-layers.css .tk-ml-body), so the three read as one family — a
   touch more opaque, since these sit half over the panel. z-index: over Leaflet's
   controls (1000), under the search list (1500) and every dialog (10000+). */
#route-planner-panel .rp-pop {
  position: fixed;
  z-index: 1200;
  width: 280px;
  max-width: calc(100vw - 16px);
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px 12px;
  border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--dim) 35%, transparent);
  background: color-mix(in srgb, var(--bg1) 94%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  backdrop-filter: blur(16px) saturate(1.2);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.3);
  color: var(--txt);
}
#route-planner-panel .rp-pop[hidden] { display: none; }
#route-planner-panel .rp-pop-title {
  color: var(--txt);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
#route-planner-panel .rp-pop-group {
  margin-top: 2px;
  padding-top: 8px;
  border-top: 1px solid var(--bdr);
  color: var(--dim);
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
}

/* ── One column (TKF-429) ─────────────────────────────────────────────────
   The right panel is gone: what every route needs sits in the Plan block under
   the toolbar, the rare actions behind •••, the map tools on the map, and the
   headline figures over the profile. */

/* ••• — straight after the last button, on the toolbar's own gap: pushed to
   the far end it read as detached from the buttons it belongs with. The
   toolbar is back to four buttons since Import and Export went into it
   (TKF-432), so it keeps its original spacing. */
#route-planner-panel .rp-routes-toolbar .rp-more-btn {
  padding: 7px 5px;
  letter-spacing: 1px;
  line-height: 1;
}

/* Plan block: fixed under the toolbar; the sections below it scroll. */
#route-planner-panel .rp-plan {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border-bottom: 1px solid var(--bdr);
}
#route-planner-panel .rp-verbs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}
#route-planner-panel .rp-verbs .rp-btn {
  min-width: 0;
  padding: 7px 8px;
  font-size: var(--fs-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#route-planner-panel .rp-trace-active[hidden] { display: none; }

/* ••• menu: the same .rp-pop, holding buttons that read as menu items. */
#route-planner-panel .rp-pop-menu {
  width: 260px;
  gap: 2px;
  padding: 8px;
}
#route-planner-panel .rp-pop-menu > .rp-pop-group { margin-top: 6px; padding: 8px 8px 2px; }
#route-planner-panel .rp-pop-menu > .rp-pop-group:first-child { margin-top: 0; padding-top: 2px; border-top: 0; }
#route-planner-panel .rp-pop-item {
  width: 100%;
  text-align: left;
  background: transparent;
  border-color: transparent;
  font-weight: 400;
  padding: 6px 8px;
}
#route-planner-panel .rp-pop-item:hover:not(:disabled) { background: var(--bg3); border-color: transparent; }

/* Share (TKF-432) — outlined in amber so it reads as the thing to do once a
   route exists, without competing with + New's fill. */
#route-planner-panel .rp-routes-toolbar .rp-share-btn:not(:disabled) {
  border-color: var(--amber-ink);
  color: var(--amber-ink);
}
/* 🔗 Shared — beside the route name while the route has a live link. */
#route-planner-panel .rp-shared-tag {
  padding: 2px 8px;
  border: 1px solid color-mix(in srgb, var(--amber-ink) 55%, transparent);
  border-radius: 999px;
  background: transparent;
  color: var(--amber-ink);
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
#route-planner-panel .rp-shared-tag:hover { border-color: var(--amber-ink); }
#route-planner-panel .rp-shared-tag[hidden] { display: none; }

/* Map tools — beside the full-screen button, on the row it and Map Layers sit
   on. Hidden until mountMapTools() moves the node onto the map. */
#route-planner-panel .rp-body > .rp-map-tools { display: none; }
#route-planner-panel .rp-map .leaflet-left .rp-map-tools {
  clear: none;
  margin-top: 12px;
  margin-left: 8px;
  display: flex;
  gap: 8px;
}
#route-planner-panel .rp-maptool-bar {
  display: flex;
  border: 2px solid rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  overflow: hidden;
  background: var(--bg1);
}
#route-planner-panel .rp-maptool-btn {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  background: var(--bg1);
  color: var(--txt);
  font-size: var(--fs-lg);
  line-height: 1;
  cursor: pointer;
}
#route-planner-panel .rp-maptool-btn + .rp-maptool-btn { border-left: 1px solid var(--bdr); }
#route-planner-panel .rp-maptool-btn:hover:not(:disabled) { background: var(--bg2); color: var(--amber-ink); }
#route-planner-panel .rp-maptool-btn:disabled { color: var(--dim3); cursor: default; }
#route-planner-panel .rp-map-tools .rp-rp-seg {
  margin-top: 0;
  border: 2px solid rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  background: var(--bg1);
}
#route-planner-panel .rp-map-tools .rp-rp-seg-btn { height: 32px; padding: 0 10px; white-space: nowrap; }

/* My location — the top button of Leaflet's zoom bar, dressed as its
   neighbours (`.leaflet-bar a` in leaflet.css). It cannot simply BE one of
   them: an <a href="#"> would move the URL hash the planner syncs its view to. */
#route-planner-panel .leaflet-bar .rp-locate-btn {
  display: block;
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  border: 0;
  border-bottom: 1px solid #ccc;
  border-radius: 4px 4px 0 0;
  background: #fff;
  color: #000;
  font: 18px/26px system-ui, sans-serif;
  text-align: center;
  cursor: pointer;
}
#route-planner-panel .leaflet-touch .leaflet-bar .rp-locate-btn { width: 30px; height: 30px; line-height: 30px; }
#route-planner-panel .leaflet-bar .rp-locate-btn:hover { background: #f4f4f4; }

/* Headline stats over the profile. The bar is the row the profile toggle
   always sat on; it takes a background only while there are figures in it, so
   with no route it is the bare toggle it used to be. */
#route-planner-panel .rp-statsbar {
  flex-shrink: 0;
  display: flex;
  align-items: flex-end;
  min-width: 0;
}
#route-planner-panel .rp-statsbar:has(> .rp-stats:not([hidden])) {
  background: var(--bg1);
  border-top: 1px solid var(--bdr);
}
/* …and then the figures and the chart read as one panel. */
#route-planner-panel .rp-statsbar:has(> .rp-stats:not([hidden])) + .rp-profile { border-top: 0; }
#route-planner-panel .rp-stats {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 4px 26px;
  padding: 8px 14px 4px;
}
#route-planner-panel .rp-stats[hidden],
#route-planner-panel .rp-stat[hidden] { display: none; }
#route-planner-panel .rp-stat {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
#route-planner-panel .rp-stat-val {
  color: var(--txt);
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-lg);
  font-weight: 600;
  white-space: nowrap;
}
#route-planner-panel .rp-stat-lbl {
  display: flex;
  align-items: baseline;
  gap: 4px;
  color: var(--dim2);
  font-size: var(--fs-xs);
  white-space: nowrap;
}
/* "ride time at" is the lowercase phrase the old summary row used, and still
   its catalog string; a caption starts with a capital. */
#route-planner-panel .rp-stat-cap { display: inline-block; }
#route-planner-panel .rp-stat-cap::first-letter { text-transform: uppercase; }
#route-planner-panel .rp-stats .rp-summary-speed { margin-left: 0; }

#route-planner-panel .rp-rp-caret {
  display: inline-block;
  transition: transform 0.15s ease;
  font-size: var(--fs-xs);
  color: var(--dim);
}
/* Label colour is --txt, NOT --dim: these sit interleaved with .rp-rp-check
   rows ("Avoid ferries", "Auto waypoints") in the same panel, and both are
   labels for something the rider sets. Dimming only one of the two kinds read
   as the select rows being disabled. (TKB-248) */
#route-planner-panel .rp-rp-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  color: var(--txt);
  font-size: var(--fs-sm);
}
/* Both children must be allowed to SHRINK. Flex items default to
   min-width:auto, so a <select> sized to its widest option ("Custom (sliders)")
   refuses to narrow — and once the label grows with translation
   ("Route style" → "Routencharakter") the row overflows the panel to the right.
   Setting min-width:0 is what actually permits the shrink; the rest just makes
   the result read well. */
#route-planner-panel .rp-rp-field > span {
  min-width: 0;
  overflow-wrap: anywhere;
}
/* A field that is not offered on the current profile — Max trail grade off MTB/gravel
   (TKF-331). The flex display above would otherwise beat the `hidden` attribute. */
#route-planner-panel .rp-rp-field[hidden] { display: none; }
#route-planner-panel .rp-rp-field select {
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  padding: 4px 6px;
  font: inherit;
  font-size: var(--fs-sm);
  min-width: 0;
  max-width: 62%;
  text-overflow: ellipsis;
}
/* Same reasoning for the number+suffix control in this panel. */
#route-planner-panel .rp-rp-field .rp-rp-suffixed {
  min-width: 0;
}
#route-planner-panel .rp-rp-value {
  color: var(--txt);
  font-weight: 600;
}
#route-planner-panel .rp-rp-suffixed {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
#route-planner-panel .rp-rp-suffixed input[type="number"] {
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  padding: 4px 6px;
  font: inherit;
  font-size: var(--fs-sm);
  width: 64px;
  text-align: right;
}
#route-planner-panel .rp-rp-suffix {
  color: var(--dim);
  font-size: var(--fs-xs);
}
/* Row that pairs a checkbox with a small inline select (e.g. distance
   markers + spacing). The select sits flush right at field-width parity
   with other right-side controls in the panel. */
#route-planner-panel .rp-rp-row-split {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
#route-planner-panel .rp-rp-check-inline {
  margin: 0;
  flex: 1 1 auto;
}
#route-planner-panel .rp-rp-inline-select {
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  padding: 3px 6px;
  font: inherit;
  font-size: var(--fs-xs);
}
/* POI browse layer toggle grid — sits inside Map & Display. 2 columns at
   typical sidebar width; each cell is a compact checkbox with a glyph. */
#route-planner-panel .rp-rp-poi-layers {
  border-top: 1px solid var(--bdr);
  padding-top: 8px;
  margin-top: 4px;
}
#route-planner-panel .rp-rp-poi-layers-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}
#route-planner-panel .rp-rp-poi-layers-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 0;
  padding: 2px 0;
  font: inherit;
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: inherit;
  cursor: pointer;
}
#route-planner-panel .rp-rp-poi-layers-toggle:hover { color: var(--amber-ink); }
#route-planner-panel .rp-poi-clear-all,
#route-planner-panel .rp-poi-enable-all {
  background: none;
  border: 1px solid var(--bdr2, var(--bdr2));
  border-radius: 4px;
  padding: 2px 8px;
  font: inherit;
  font-size: var(--fs-xs);
  color: inherit;
  cursor: pointer;
  white-space: nowrap;
}
#route-planner-panel .rp-poi-clear-all:hover,
#route-planner-panel .rp-poi-enable-all:hover {
  border-color: var(--amber-ink);
  color: var(--amber-ink);
}
/* Collapsed = hide the grid + hint; rotate the caret like the sidebar sections. */
#route-planner-panel .rp-rp-poi-layers.collapsed .rp-rp-poi-layers-body {
  display: none;
}
#route-planner-panel .rp-rp-poi-layers.collapsed .rp-rp-caret {
  transform: rotate(-90deg);
}
#route-planner-panel .rp-poi-layer-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 8px;
  margin-bottom: 6px;
}
#route-planner-panel .rp-poi-layer-cell {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-xs);
  color: var(--txt);
  cursor: pointer;
  user-select: none;
}
#route-planner-panel .rp-poi-layer-cell input[type="checkbox"] {
  margin: 0;
}
#route-planner-panel .rp-poi-layer-glyph {
  font-size: var(--fs-base);
  width: 16px;
  text-align: center;
}
/* Nearby tab — list of OSM POIs along the active route, grouped by type. */
#route-planner-panel .rp-nearby-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  font-size: var(--fs-xs);
  color: var(--dim);
  border-bottom: 1px solid var(--bdr);
}
/* Count text absorbs leftover horizontal space so the toggle + refresh
   buttons sit flush right. */
#route-planner-panel .rp-nearby-total { flex: 1 1 auto; }
#route-planner-panel .rp-nearby-toggle-all,
#route-planner-panel .rp-nearby-refresh,
#route-planner-panel .rp-nearby-radius {
  background: transparent;
  color: var(--dim);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  padding: 2px 8px;
  font: inherit;
  font-size: var(--fs-xs);
  cursor: pointer;
  flex: 0 0 auto;
}
#route-planner-panel .rp-nearby-radius { padding: 2px 6px; }
#route-planner-panel .rp-nearby-toggle-all:hover,
#route-planner-panel .rp-nearby-refresh:hover,
#route-planner-panel .rp-nearby-radius:hover { color: var(--txt); }
#route-planner-panel .rp-nearby-group { padding-bottom: 6px; }
/* Header style matches .rp-rp-header in the right panel: uppercase,
   letter-spaced, --fs-xs / 10px-12px padding, 8px gap. Same affordance as the
   collapsible sections on the other side of the planner. The emoji glyph
   ignores text-transform but renders fine; we constrain its size so it
   doesn't blow up the line-height. */
#route-planner-panel .rp-nearby-group-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 12px;
  background: var(--bg2);
  color: var(--txt);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: left;
  border: 0;
  border-bottom: 1px solid var(--bdr);
  cursor: pointer;
}
#route-planner-panel .rp-nearby-group-head:hover { background: var(--bg3, var(--bg3)); }
#route-planner-panel .rp-nearby-group-title {
  flex: 1 1 auto;
  font-size: var(--fs-sm);
  line-height: 1.2;
}
/* Title goes amber only while the header is hovered — same pattern as the
   right-panel section headers. Caret + count stay dim so the eye lands
   first on the active title, not on every header at once. */
#route-planner-panel .rp-nearby-group-head:hover .rp-nearby-group-title {
  color: var(--amber-ink);
}
#route-planner-panel .rp-nearby-caret {
  display: inline-block;
  font-size: var(--fs-xs);
  color: var(--dim);
  transition: transform 0.15s ease;
}
#route-planner-panel .rp-nearby-group.collapsed .rp-nearby-caret {
  transform: rotate(-90deg);
}
#route-planner-panel .rp-nearby-group.collapsed .rp-nearby-group-body {
  display: none;
}
#route-planner-panel .rp-nearby-count {
  color: var(--dim);
  font-weight: 400;
}
#route-planner-panel .rp-nearby-row {
  display: grid;
  grid-template-columns: 54px 1fr auto;
  gap: 6px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--bdr);
  font-size: var(--fs-sm);
  cursor: pointer;
}
#route-planner-panel .rp-nearby-row:hover { background: var(--bg2); }
#route-planner-panel .rp-nearby-row:hover .rp-nearby-name { color: var(--amber-ink); }
#route-planner-panel .rp-nearby-km {
  color: var(--amber-ink);
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
  font-size: var(--fs-xs);
}
#route-planner-panel .rp-nearby-name {
  color: var(--txt);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#route-planner-panel .rp-nearby-off {
  color: var(--dim);
  font-size: var(--fs-xs);
}
#route-planner-panel .rp-color-input {
  width: 40px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--bdr);
  border-radius: 4px;
  background: var(--bg2);
  cursor: pointer;
}
#route-planner-panel .rp-color-input::-webkit-color-swatch-wrapper { padding: 2px; }
#route-planner-panel .rp-color-input::-webkit-color-swatch { border: none; border-radius: 2px; }
#route-planner-panel .rp-color-presets {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: -4px 0 6px;
}
#route-planner-panel .rp-swatch {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: 1px solid var(--bdr);
  padding: 0;
  cursor: pointer;
  transition: transform 0.08s ease, box-shadow 0.08s ease;
}
#route-planner-panel .rp-swatch:hover { transform: scale(1.1); }
#route-planner-panel .rp-swatch.active {
  box-shadow: 0 0 0 2px var(--amber);
  border-color: var(--amber-ink);
}

/* Click-mode indicator: a persistent hint so the user always knows what a
   left-click on the map will do. RWG's invisible-mode trap made us want
   this loud. */
#route-planner-panel .rp-mode-indicator {
  background: var(--bg2);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  padding: 8px 10px;
}
/* The label is the amber, not the box's edge (TKF-310). */
#route-planner-panel .rp-mode-label {
  color: var(--amber-ink);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
#route-planner-panel .rp-mode-value {
  color: var(--txt);
  font-size: var(--fs-base);
  font-weight: 600;
  margin-top: 2px;
}
#route-planner-panel .rp-mode-hint {
  color: var(--dim2);
  font-size: var(--fs-xs);
  margin-top: 4px;
  line-height: 1.3;
}

/* Segmented control (draw mode: Routed / Straight line). */
#route-planner-panel .rp-rp-seg {
  display: flex;
  gap: 0;
  margin-top: 8px;
  border: 1px solid var(--bdr);
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg2);
}
#route-planner-panel .rp-rp-seg-btn {
  flex: 1;
  padding: 7px 8px;
  background: transparent;
  color: var(--dim);
  border: none;
  border-right: 1px solid var(--bdr);
  font: inherit;
  font-size: var(--fs-sm);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
#route-planner-panel .rp-rp-seg-btn:last-child { border-right: none; }
#route-planner-panel .rp-rp-seg-btn:hover { background: var(--bg3); color: var(--txt); }
#route-planner-panel .rp-rp-seg-btn.active {
  background: var(--amber);
  color: var(--on-amber);
  font-weight: 600;
}
#route-planner-panel .rp-rp-seg-glyph { font-size: var(--fs-base); }

/* Generic right-panel hint line (e.g. "Save the route first to share it.") */
#route-planner-panel .rp-rp-hint {
  color: var(--dim2);
  font-size: var(--fs-xs);
  line-height: 1.4;
}

/* Checkbox row inside a right-panel section (e.g. export options). */
#route-planner-panel .rp-rp-check {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-sm);
  color: var(--txt);
  cursor: pointer;
  padding: 2px 0;
}
#route-planner-panel .rp-rp-check input[type="checkbox"] {
  accent-color: var(--amber);
  cursor: pointer;
  margin: 0;
}

/* iOS-style toggle for the public/private switch. */
#route-planner-panel .rp-switch {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 20px;
}
#route-planner-panel .rp-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
#route-planner-panel .rp-switch-slider {
  position: absolute;
  inset: 0;
  background: var(--bg3);
  border: 1px solid var(--bdr);
  border-radius: 20px;
  cursor: pointer;
  transition: background 0.15s ease;
}
#route-planner-panel .rp-switch-slider::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 1px;
  width: 14px;
  height: 14px;
  background: var(--dim);
  border-radius: 50%;
  transition: transform 0.15s ease, background 0.15s ease;
}
#route-planner-panel .rp-switch input:checked + .rp-switch-slider {
  background: var(--amber);
  border-color: var(--amber);
}
#route-planner-panel .rp-switch input:checked + .rp-switch-slider::before {
  transform: translateX(16px);
  background: #fff;
}

/* Share URL input + Copy button row (right panel + export dialog). */
#route-planner-panel .rp-share-link,
.rp-export-card .rp-share-link {
  display: flex;
  gap: 6px;
  align-items: stretch;
}
/* The flex above outranks the UA's [hidden] rule, so a private route showed an
   empty link box and a Copy button under "Private — only you can see this
   route" (TKB-419). renderShareSection() hides the row; this lets it. */
#route-planner-panel .rp-share-link[hidden],
.rp-export-card .rp-share-link[hidden] { display: none; }
#route-planner-panel .rp-share-link input,
.rp-export-card .rp-share-link input {
  flex: 1;
  min-width: 0;
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bdr);
  border-radius: 4px;
  padding: 6px 8px;
  font: inherit;
  font-size: var(--fs-xs);
  font-family: monospace;
}
#route-planner-panel .rp-share-link .rp-btn,
.rp-export-card .rp-share-link .rp-btn {
  padding: 6px 10px;
  font-size: var(--fs-xs);
}

/* ── Branded dialog overlay ──────────────────────────────────────────────
   Replaces native alert / confirm / prompt so dialogs match the dark theme
   and don't surface the browser chrome (which leaks the hostname). Lives
   on document.body so it sits above every feature panel, not scoped. */
.rp-dialog-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  z-index: 100000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  backdrop-filter: blur(2px);
  font-family: inherit;
}
.rp-dialog-overlay[hidden] { display: none; }
.rp-dialog-card {
  background: var(--bg1);
  color: var(--txt);
  border: 1px solid var(--bg3);
  border-radius: 10px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.7);
  min-width: 320px;
  max-width: 480px;
  width: 100%;
  padding: 18px 20px 16px;
}
.rp-dialog-title {
  color: var(--amber-ink);
  font-size: var(--fs-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 10px;
}
.rp-dialog-body { font-size: var(--fs-base); }
.rp-dialog-msg {
  margin: 0 0 14px;
  line-height: 1.45;
  color: var(--txt);
  white-space: pre-wrap;
  word-wrap: break-word;
}
.rp-dialog-body a {
  color: var(--amber, var(--amber));
  text-decoration: none;
}
.rp-dialog-body a:hover { text-decoration: underline; }
.rp-dialog-input {
  width: 100%;
  background: var(--bg0);
  color: var(--txt);
  border: 1px solid var(--bg3);
  border-radius: 6px;
  padding: 8px 10px;
  font: inherit;
  font-size: var(--fs-base);
  margin-bottom: 14px;
  box-sizing: border-box;
}
.rp-dialog-input:focus {
  outline: none;
  border-color: var(--amber-ink);
  box-shadow: 0 0 0 2px rgba(var(--amber-wash), 0.25);
}
/* Form layout for structured dialogs (e.g. loop route) */
.rp-dialog-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 14px;
}
.rp-dialog-form-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: var(--fs-base);
  color: var(--txt);
}
.rp-dialog-form-row span { flex-shrink: 0; }
.rp-dialog-input-sm {
  width: 160px;
  margin-bottom: 0;
}
.rp-dialog-msg-dim { color: var(--dim); }
/* Itemised disclosure lists (e.g. the Coach Chat consent scope). Deliberately
   NOT .rp-dialog-msg: that carries white-space: pre-wrap, which turns the
   whitespace between <li> tags into blank lines the moment anyone reformats
   the markup. */
.rp-dialog-list {
  margin: 0 0 14px;
  padding-left: 20px;
  line-height: 1.45;
  color: var(--txt);
}
.rp-dialog-list li { margin-bottom: 5px; }
.rp-dialog-search { margin-bottom: 8px; }
.rp-dialog-list {
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid var(--bg3);
  border-radius: 6px;
  background: var(--bg0);
  margin-bottom: 14px;
}
.rp-dialog-list-item {
  padding: 8px 10px;
  border-bottom: 1px solid var(--bg1);
  cursor: pointer;
  color: var(--txt);
}
.rp-dialog-list-item:last-child { border-bottom: none; }
.rp-dialog-list-item:hover { background: var(--bg1); }
.rp-dialog-list-item.selected {
  background: rgba(var(--amber-wash), 0.18);
  border-left: 3px solid var(--amber-ink);
  padding-left: 7px;
}
.rp-dialog-list-label { font-size: var(--fs-base); font-weight: 500; }
.rp-dialog-list-sub {
  font-size: var(--fs-sm);
  color: var(--dim);
  margin-top: 2px;
}
.rp-dialog-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
/* Confirm dialogs: keep the right-clustered cluster, but render the
   affirmative button first so it sits on the left of the cluster (closer
   to the message body). Other dialogs (prompts, pickers, forms) inherit
   the same right cluster from .rp-dialog-actions. */
.rp-dialog-actions-confirm {
  justify-content: flex-end;
}
.rp-dialog-actions .rp-btn {
  padding: 8px 16px;
  font-size: var(--fs-base);
  min-width: 80px;
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bg3);
  border-radius: 6px;
  cursor: pointer;
}
.rp-dialog-actions .rp-btn:hover { background: var(--bg3); }
.rp-dialog-actions .rp-btn-primary {
  background: var(--amber);
  color: var(--on-amber);
  border-color: var(--amber);
  font-weight: 600;
}
.rp-dialog-actions .rp-btn-primary:hover { background: var(--amber-ink); }
.rp-dialog-actions .rp-btn-danger {
  background: var(--red);
  color: #fff;
  border-color: var(--red);
  font-weight: 600;
}
.rp-dialog-actions .rp-btn-danger:hover { background: var(--red); }

/* ── Route alternatives picker ───────────────────────────────────────── */
.rp-alt-picker {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  background: color-mix(in srgb, var(--bg1) 94%, transparent);
  border: 1px solid var(--bg3);
  border-radius: 10px;
  padding: 10px 14px;
  min-width: 300px;
  max-width: 420px;
  box-shadow: 0 4px 20px rgba(0,0,0,.45);
  backdrop-filter: blur(8px);
  font-size: var(--fs-base);
  color: var(--txt);
}
.rp-alt-header {
  font-weight: 600;
  font-size: var(--fs-base);
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: .5px;
  margin-bottom: 8px;
}
.rp-alt-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 10px;
}
.rp-alt-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  cursor: pointer;
  transition: background .15s;
}
.rp-alt-row:hover { background: var(--bg3); }
.rp-alt-row.active {
  background: var(--bg3);
  outline: 1.5px solid var(--amber);
}
.rp-alt-swatch {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  flex-shrink: 0;
}
.rp-alt-label {
  flex: 1;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rp-alt-dist {
  color: var(--dim);
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rp-alt-elev {
  color: var(--dim2);
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
  white-space: nowrap;
  min-width: 50px;
  text-align: right;
}
.rp-alt-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* Import dialog — URL paste + GPX/FIT drop-zone in one card. Slightly wider
   than the default rp-dialog-card because two stacked sections plus a status
   panel get cramped at 480px. */
.rp-import-card { max-width: 560px; }
/* Inline section buttons (e.g. "Import from URL", "Download GPX") need the
   same branding as .rp-dialog-actions buttons but live outside that wrapper,
   so style them from the card scope. Same rule covers both import and
   export dialogs. */
.rp-import-card .rp-btn,
.rp-export-card .rp-btn {
  padding: 8px 16px;
  font-size: var(--fs-base);
  min-width: 80px;
  background: var(--bg2);
  color: var(--txt);
  border: 1px solid var(--bg3);
  border-radius: 6px;
  cursor: pointer;
}
.rp-import-card .rp-btn:hover,
.rp-export-card .rp-btn:hover { background: var(--bg3); }

/* ── Share dialog (TKF-432, core/share-dialog.js) ──────────────────────────
   Borrows the export card's buttons and link row (.rp-export-card) and adds
   the visibility levels, the QR code and the recipient's preview card. */
.rp-share-levels {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
}
.rp-share-level {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--bg3);
  border-radius: 8px;
  cursor: pointer;
}
.rp-share-level:has(input:checked) {
  border-color: var(--amber-ink);
  background: color-mix(in srgb, var(--amber) 8%, transparent);
}
.rp-share-level:has(input:disabled) { opacity: 0.6; cursor: progress; }
.rp-share-level input { accent-color: var(--amber); margin: 3px 0 0; flex-shrink: 0; }
.rp-share-level b { display: block; color: var(--txt); font-weight: 600; }
.rp-share-level small {
  display: block;
  margin-top: 2px;
  color: var(--dim);
  font-size: var(--fs-sm);
  line-height: 1.4;
}
.rp-share-error { margin: 0 0 10px; color: var(--red); font-size: var(--fs-sm); }
.rp-share-hint  { margin: 0 0 14px; color: var(--dim); font-size: var(--fs-sm); }
.rp-share-note  { margin: 0; color: var(--dim); font-size: var(--fs-xs); line-height: 1.4; }
.rp-share-live {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}
.rp-share-card .rp-share-native { align-self: flex-start; }
.rp-share-error[hidden], .rp-share-hint[hidden], .rp-share-live[hidden],
.rp-share-card .rp-share-native[hidden], .rp-share-visuals figure[hidden] { display: none; }
.rp-share-visuals {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 14px;
}
.rp-share-visuals figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.rp-share-visuals figcaption { max-width: 240px; color: var(--dim); font-size: var(--fs-xs); }
/* The caption wraps under the code rather than widening its column — German's
   is twice the code's width and pushed the preview onto a line of its own. */
.rp-share-qr figcaption { max-width: 132px; }
/* Black on white whatever the theme — a scanner wants contrast, not a palette. */
.rp-share-qr svg { display: block; border-radius: 4px; }
.rp-share-preview img {
  display: block;
  width: 240px;
  height: auto;
  aspect-ratio: 1200 / 630;
  object-fit: cover;
  border: 1px solid var(--bg3);
  border-radius: 6px;
  background: var(--bg2);
}
.rp-import-card .rp-btn-primary,
.rp-export-card .rp-btn-primary {
  background: var(--amber);
  color: var(--on-amber);
  border-color: var(--amber);
  font-weight: 600;
}
.rp-import-card .rp-btn-primary:hover,
.rp-export-card .rp-btn-primary:hover { background: var(--amber-ink); }
.rp-import-card .rp-btn:disabled,
.rp-export-card .rp-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Export modal — two-column grid for download formats, full-width rows for
   the cue-sheet PDF and the push targets. */
.rp-export-card { max-width: 520px; }
.rp-export-subtitle {
  margin: -4px 0 12px;
  color: var(--dim);
  font-size: var(--fs-base);
  font-style: italic;
}
.rp-export-section { margin-bottom: 14px; }
.rp-export-section:last-of-type { margin-bottom: 0; }
.rp-export-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin: 6px 0 10px;
}
.rp-export-full { grid-column: 1 / -1; }
.rp-export-check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-base);
  color: var(--txt2);
  padding: 4px 0;
  cursor: pointer;
}
.rp-export-check input[type="checkbox"] { accent-color: var(--amber); }
.rp-import-section { margin-bottom: 14px; }
.rp-import-section:last-of-type { margin-bottom: 0; }
.rp-import-label {
  display: block;
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 6px;
}
.rp-import-fineprint {
  font-size: var(--fs-sm);
  color: var(--dim);
  margin: 8px 0 10px;
  line-height: 1.4;
}
/* The negative top margin this used to carry unconditionally was tuned for
   ONE of its two uses — under .rp-dialog-input, which brings its own 14px
   bottom margin. The other use sits under the drop zone, which brings none,
   so the pull-up put the sentence on the dashed border. Scope it. (TKB-244) */
.rp-dialog-input + .rp-import-fineprint { margin-top: -6px; }
.rp-import-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 4px 0 10px;
  color: var(--dim2);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.rp-import-divider::before,
.rp-import-divider::after {
  content: '';
  flex: 1 1 auto;
  height: 1px;
  background: var(--bg3);
}
.rp-import-drop {
  border: 1px dashed var(--bdr2);
  border-radius: 8px;
  padding: 18px 14px;
  text-align: center;
  background: var(--bg0);
  color: var(--txt2);
  font-size: var(--fs-base);
  transition: border-color .15s, background .15s;
}
.rp-import-drop.dragging {
  border-color: var(--amber-ink);
  background: var(--bg0);
}
.rp-import-drop-text { line-height: 1.4; }
.rp-link-btn {
  background: none;
  border: 0;
  color: var(--amber-ink);
  cursor: pointer;
  font: inherit;
  padding: 0;
  text-decoration: underline;
}
.rp-link-btn:hover { color: var(--amber-ink); }
.rp-import-status {
  margin: 10px 0 14px;
  padding: 10px 12px;
  border-radius: 6px;
  font-size: var(--fs-base);
  line-height: 1.4;
  background: var(--bg0);
  border: 1px solid var(--bg3);
  display: none;
}
.rp-import-status-loading,
.rp-import-status-ok,
.rp-import-status-err,
.rp-import-status-partial { display: block; }
.rp-import-status-loading { color: var(--txt2); }
.rp-import-status-ok      { border-color: #166534; color: var(--green); }
.rp-import-status-err     { border-color: #b91c1c; color: var(--red); }
.rp-import-status-partial { border-color: #b45309; color: var(--amber-ink); }
.rp-import-err-row {
  margin-top: 6px;
  font-size: var(--fs-sm);
  color: var(--red);
}
/* Bulk-import progress (TKF-043). A whole Komoot library is minutes of work, so
   the panel has to show real movement and offer a way out — a spinner would say
   nothing about whether route 4 or route 190 is going through. */
.rp-import-progress {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.rp-import-progress-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--bg1);
  overflow: hidden;
}
.rp-import-progress-bar > span {
  display: block;
  height: 100%;
  min-width: 2px;                 /* the first route still shows a sliver */
  background: var(--amber);
  border-radius: 3px;
  transition: width 180ms ease-out;
}
.rp-import-progress-text {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  align-items: baseline;
  font-size: var(--fs-base);
  color: var(--txt2);
}
.rp-import-progress-counts {
  color: var(--dim);
  font-size: var(--fs-sm);
}
.rp-import-stop { align-self: flex-start; }
@media (prefers-reduced-motion: reduce) {
  .rp-import-progress-bar > span { transition: none; }
}
/* "Load & edit" buttons under the import result — open a just-imported route
   straight in the editor. */
.rp-import-loaded {
  margin-top: 8px;
}
.rp-import-load-btn {
  width: 100%;
  text-align: center;
}

/* Toast styles moved to core/toast.css — one shared toast for the whole app
   (TKB-028). */

/* ── Sectors layer (SecteuR) — filter row under the "Sectors" checkbox ──────── */

/* ── Sectors layer (SecteuR) — click-popup for a detected climb/sector ──────── */
.rp-sector-popup {
  min-width: 190px;
  font: 14px/1.4 system-ui, sans-serif;
}
.rp-sector-popup .rp-sector-name {
  font-weight: 600;
  font-size: var(--fs-base);
  color: #111827;
  margin-bottom: 1px;
}
.rp-sector-popup .rp-sector-cat {
  font-size: var(--fs-sm);
  color: #6b7280;
  margin-bottom: 7px;
}
/* "Surfaced road ends here — the climb continues as gravel" (TKB-285). Sits
   between the category line and the stats grid, and carries the same literal
   colours as the rest of this popup — it is drawn on the basemap, which does not
   follow the UI theme. */
.rp-sector-popup .rp-sector-cont {
  font-size: var(--fs-sm);
  color: #6b7280;
  margin: -3px 0 7px;
  padding-left: 8px;
  border-left: 2px solid #d1d5db;
}
.rp-sector-popup .rp-sector-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 14px;
  margin: 0;
}
.rp-sector-popup .rp-sector-stats > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.rp-sector-popup .rp-sector-stats dt {
  color: #6b7280;
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.rp-sector-popup .rp-sector-stats dd {
  margin: 0;
  font-weight: 600;
  color: #111827;
  font-family: var(--font-data); font-variant-numeric: tabular-nums;
}
