:root {
  --bg: #0f1720;
  --bg-2: #16202b;
  --bg-3: #1d2936;
  --line: #2a3846;
  --text: #e6edf3;
  --muted: #93a4b4;
  --accent: #12a594;
  --accent-2: #0d8578;
  --bus: #e8a33d;
  --rail: #2f9e5e;
  --tram: #a970d6;
  --walk: #7d8da0;
  --danger: #e5735e;
  --radius: 10px;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font: 14px/1.5 "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}
h1, h2, h3, p { margin: 0; }
button { font: inherit; color: inherit; cursor: pointer; }

#app { display: flex; height: 100%; }

/* The seam between the panel and the map, draggable so the map can be given
   the room the list is taking. It straddles the border rather than taking space
   of its own: the negative margin cancels its width, so widening the grab area
   does not move anything. */
#panel-grip {
  flex: 0 0 9px; width: 9px; margin: 0 -5px 0 -4px; z-index: 600;
  cursor: col-resize; background: transparent; touch-action: none;
  position: relative;
}
/* The line you actually see, which is the panel border until you go near it. */
#panel-grip::after {
  content: ''; position: absolute; inset: 0 auto 0 3px; width: 3px;
  border-radius: 3px; background: transparent; transition: background .15s;
}
#panel-grip:hover::after, #panel-grip:focus-visible::after,
#app.resizing #panel-grip::after { background: var(--accent); }
#panel-grip:focus-visible { outline: none; }
/* Nothing to resize when the panel is put away. */
#app.panel-hidden #panel-grip { display: none; }
/* While dragging, the pointer belongs to the grip: the map must not take the
   move as a pan, and a stray selection of the list text helps nobody. */
#app.resizing { cursor: col-resize; user-select: none; }
#app.resizing #map-wrap { pointer-events: none; }

/* ------------------------------------------------------------------ panel */
/* The panel's size is a variable so the collapse below, the grip and the
   stored width all move together - see panel.js, which sets it. */
#app { --panel-w: 400px; --panel-h: 55vh; }

#panel {
  width: var(--panel-w);
  flex: 0 0 var(--panel-w);
  background: var(--bg);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-height: 0;
  transition: margin-left .25s ease;
  z-index: 500;
}
#app.panel-hidden #panel { margin-left: calc(-1 * var(--panel-w)); }
#app.panel-hidden #panel-toggle { transform: rotate(180deg); }

.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 14px 12px;
  border-bottom: 1px solid var(--line);
}
.brand-mark { display: flex; }
.brand-text { min-width: 0; flex: 1; }
.brand h1 { font-size: 16px; font-weight: 650; letter-spacing: .2px; }
.brand p { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.icon-btn {
  background: var(--bg-3); border: 1px solid var(--line); color: var(--muted);
  width: 30px; height: 30px; border-radius: 8px; line-height: 1;
  display: grid; place-items: center; flex: none; transition: .15s;
}
.icon-btn:hover { color: var(--text); border-color: var(--accent); }

.tabs { display: flex; gap: 4px; padding: 10px 12px 0; border-bottom: 1px solid var(--line); }
.tab {
  background: none; border: 0; border-bottom: 2px solid transparent;
  padding: 7px 11px; color: var(--muted); font-size: 13px; font-weight: 550;
}
.tab:hover { color: var(--text); }
.tab.is-active { color: var(--text); border-bottom-color: var(--accent); }

.tab-body { display: none; padding: 14px; overflow-y: auto; flex: 1; min-height: 0; }
.tab-body.is-active { display: block; }

/* ---------------------------------------------------------------- inputs */
.control, input[type="search"], input[type="text"], input[type="date"], input[type="time"], select {
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 8px;
  padding: 8px 10px;
  font: inherit;
  outline: none;
}
.control:focus, input:focus { border-color: var(--accent); }
.field { display: block; margin-bottom: 10px; min-width: 0; flex: 1; }
.field > span { display: block; font-size: 11.5px; color: var(--muted); margin-bottom: 4px; text-transform: uppercase; letter-spacing: .5px; }
.field > span b { color: var(--text); font-weight: 600; }
.row { display: flex; gap: 8px; }
input[type="range"] { width: 100%; accent-color: var(--accent); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.chip {
  background: var(--bg-2); border: 1px solid var(--line); color: var(--muted);
  border-radius: 999px; padding: 4px 12px; font-size: 12.5px;
}
.chip.is-active { background: var(--accent); border-color: var(--accent); color: #04120f; font-weight: 600; }
/* Trips set before, offered back under the two boxes. */
.recent { margin: 2px 0 12px; }
.recent-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 6px;
}
.link-btn {
  background: none; border: 0; padding: 0; color: var(--muted); cursor: pointer;
  font: inherit; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  text-decoration: underline; text-underline-offset: 3px;
}
.link-btn:hover { color: var(--text); }
.chip.trip-chip {
  display: flex; align-items: baseline; gap: 5px; max-width: 100%;
  color: var(--text); text-align: left;
}
.chip.trip-chip .trip-end {
  max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip.trip-chip .trip-arrow { color: var(--muted); flex: none; }
.chip.trip-chip.is-active .trip-arrow { color: inherit; }

/* A line chip carries the colour it draws in as a bar under the number -
   striped when the line runs more than one way from the stop. */
.chip.line-chip { position: relative; padding-bottom: 6px; }
.chip.line-chip::after {
  content: ''; position: absolute; left: 8px; right: 8px; bottom: 3px; height: 3px;
  border-radius: 2px; background: var(--rule, transparent);
  /* Outlined, or a line whose colour is close to its chip's disappears. */
  box-shadow: 0 0 0 1px rgba(0,0,0,.45);
}

.primary-btn {
  width: 100%; background: var(--accent); border: 0; color: #04120f;
  font-weight: 650; padding: 11px; border-radius: 9px; margin-top: 4px;
}
.primary-btn:hover { background: var(--accent-2); color: #fff; }
.primary-btn:disabled { opacity: .55; cursor: default; }
.add-btn, .more-btn {
  width: 100%; background: var(--bg-2); border: 1px dashed var(--line);
  color: var(--muted); padding: 9px; border-radius: 9px; margin: 4px 0 14px;
}
.add-btn:hover, .more-btn:hover { border-color: var(--accent); color: var(--text); }
.ghost-btn {
  background: var(--bg-3); border: 1px solid var(--line); color: var(--muted);
  border-radius: 7px; padding: 5px 10px; font-size: 12.5px;
}
.ghost-btn:hover { color: var(--text); border-color: var(--accent); }
.ghost-btn.is-active { background: var(--accent); color: #04120f; border-color: var(--accent); font-weight: 600; }

.hint { color: var(--muted); font-size: 12.5px; margin-bottom: 12px; }
.result-count { color: var(--muted); font-size: 12px; margin: 2px 0 8px; }

/* --------------------------------------------------------------- line list */
.list { display: flex; flex-direction: column; gap: 6px; }
.line-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 9px 10px; text-align: left; width: 100%;
}
.line-row:hover { border-color: var(--accent); background: var(--bg-3); }
.badge {
  flex: none; min-width: 44px; padding: 4px 7px; border-radius: 7px;
  font-weight: 700; font-size: 12.5px; text-align: center; color: #10161d;
  background: var(--bus); letter-spacing: .3px;
}
.badge.rail { background: var(--rail); color: #fff; }
.badge.tram { background: var(--tram); color: #fff; }
.badge.other { background: var(--walk); color: #fff; }
.line-main { min-width: 0; flex: 1; }
/* Blocks, not the spans they are in the markup: an inline box ignores overflow,
   so as a span the ellipsis never fires and a long name spills past the panel
   onto the map - which the narrower the panel is dragged, the worse it gets. */
.line-name { display: block; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.line-sub { display: block; font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ------------------------------------------------------------ line detail */
.back-btn { background: none; border: 0; color: var(--accent); padding: 0 0 10px; font-size: 13px; }
.detail-head { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px; }
.detail-head h2 { font-size: 15px; line-height: 1.35; }
.detail-head .line-sub { white-space: normal; }
.stats { display: flex; gap: 14px; margin: 10px 0 14px; }
.stat { background: var(--bg-2); border: 1px solid var(--line); border-radius: 9px; padding: 7px 10px; flex: 1; }
.stat b { display: block; font-size: 15px; }
.stat span { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .4px; }

.dir-tabs { display: flex; gap: 6px; margin-bottom: 10px; flex-wrap: wrap; }
.section-title {
  font-size: 11.5px; color: var(--muted); text-transform: uppercase;
  letter-spacing: .6px; margin: 16px 0 8px; font-weight: 600;
}
.stop-list { border-left: 2px solid var(--line); margin-left: 6px; padding-left: 0; }
.stop-item {
  display: flex; align-items: baseline; gap: 8px; position: relative;
  padding: 5px 6px 5px 16px; width: 100%; background: none; border: 0; text-align: left;
  border-radius: 6px;
}
.stop-item::before {
  content: ""; position: absolute; left: -5px; top: 12px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--line);
  border: 2px solid var(--bg);
}
.stop-item:hover { background: var(--bg-2); }
.stop-item:hover::before { background: var(--accent); }
.stop-item .n { color: var(--muted); font-size: 11px; min-width: 18px; }
.stop-item .nm { font-size: 12.5px; }

.timetable { display: flex; flex-wrap: wrap; gap: 5px; }
.tt {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 6px;
  padding: 4px 7px; font-size: 12px; font-variant-numeric: tabular-nums;
}
.tt:hover { border-color: var(--accent); }
.tt.overnight { color: var(--tram); }

/* -------------------------------------------------------------- waypoints */
.wp {
  display: flex; gap: 8px; align-items: flex-start;
  background: var(--bg-2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 9px; margin-bottom: 8px;
}
.wp-dot {
  flex: none; width: 22px; height: 22px; border-radius: 50%; margin-top: 4px;
  display: grid; place-items: center; font-size: 11px; font-weight: 700;
  background: var(--accent); color: #04120f;
}
.wp.is-end .wp-dot { background: var(--danger); color: #1a0b07; }
.wp.is-via .wp-dot { background: var(--bg-3); color: var(--text); border: 1px solid var(--line); }
.wp-body { flex: 1; min-width: 0; position: relative; }
.wp-actions { display: flex; gap: 4px; margin-top: 6px; }
.wp input { padding: 7px 9px; }
.wp .picked { font-size: 11.5px; color: var(--accent); margin-top: 5px; }

.suggest {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 20;
  background: var(--bg-3); border: 1px solid var(--line); border-radius: 9px;
  margin-top: 4px; max-height: 240px; overflow-y: auto; box-shadow: 0 12px 30px rgba(0,0,0,.5);
}
.suggest button {
  display: block; width: 100%; text-align: left; background: none; border: 0;
  padding: 8px 10px; font-size: 12.5px; border-bottom: 1px solid var(--line);
}
.suggest button:last-child { border-bottom: 0; }
.suggest button:hover { background: var(--bg-2); }
.suggest .s-sub { color: var(--muted); font-size: 11px; }
.suggest .s-head {
  padding: 5px 10px; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--muted); background: var(--bg-2);
}

/* --------------------------------------------------------- route builder */
/* The chain is the trip so far; the next step is what the map is asking for. */
.chain { margin: 12px 0 10px; }
.chain .leg .wp-dot { margin-top: 1px; }
.leg.pending { opacity: .75; }
.leg.pending .leg-time b { color: var(--muted); }

.next-step {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 11px 12px; margin: 10px 0 12px;
}
.next-step .hint { margin: 4px 0 0; }
.next-step .stop-list, .next-step .chips { margin-top: 9px; }
.next-step .stop-list { max-height: 300px; overflow-y: auto; }
.step-head {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin: 0; font-size: 13px; font-weight: 600;
}
.next-step.is-active { border-color: var(--accent); }

.line-chip { cursor: pointer; font-weight: 650; }
.line-chip:hover { filter: brightness(1.15); }

.builder-actions { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 4px; }

/* ------------------------------------------------------------- itinerary */
.summary {
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px; margin: 14px 0 10px;
}
.summary-top { display: flex; align-items: baseline; gap: 8px; }
.summary-top .big { font-size: 21px; font-weight: 650; font-variant-numeric: tabular-nums; }
.summary-top .arrow { color: var(--muted); }
.summary-meta { color: var(--muted); font-size: 12px; margin-top: 4px; }
.mini-legs { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-top: 10px; }
.mini {
  font-size: 11.5px; font-weight: 650; padding: 3px 7px; border-radius: 6px;
  background: var(--bus); color: #10161d;
}
.mini.rail { background: var(--rail); color: #fff; }
.mini.tram { background: var(--tram); color: #fff; }
.mini.walk { background: var(--bg-3); color: var(--muted); font-weight: 500; }
.mini-sep { color: var(--muted); font-size: 10px; }

.leg-group { margin-bottom: 6px; }
.leg-group > h3 {
  font-size: 12px; color: var(--muted); margin: 14px 0 8px; font-weight: 600;
  display: flex; justify-content: space-between; gap: 8px;
}
.leg {
  display: flex; gap: 10px; padding: 8px 0;
  border-bottom: 1px solid var(--line);
}
.leg:last-child { border-bottom: 0; }
.leg-time {
  flex: none; width: 46px; font-variant-numeric: tabular-nums;
  font-size: 12.5px; color: var(--muted);
}
.leg-time b { display: block; color: var(--text); font-weight: 600; }
.leg-rail { flex: none; width: 4px; border-radius: 2px; background: var(--walk); }
.leg-rail.bus { background: var(--bus); }
.leg-rail.rail { background: var(--rail); }
.leg-rail.tram { background: var(--tram); }
.leg-rail.walk { background: repeating-linear-gradient(180deg, var(--walk) 0 4px, transparent 4px 8px); }
.leg-body { flex: 1; min-width: 0; }
.leg-title { font-size: 13px; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.leg-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.leg-stops { margin-top: 6px; }
.leg-stops summary { font-size: 11.5px; color: var(--accent); cursor: pointer; }
.leg-stops ol { margin: 6px 0 0; padding-left: 18px; color: var(--muted); font-size: 12px; }
.leg-stops li { padding: 1px 0; }
.leg-stops li b { color: var(--text); font-weight: 500; }

/* A result with no transit at all is a fallback, not an itinerary - say so. */
.summary.walk-only { border-color: rgba(229,115,94,.45); background: rgba(229,115,94,.07); }

.notice {
  background: rgba(229,115,94,.12); border: 1px solid rgba(229,115,94,.4);
  color: #f0b3a5; border-radius: 9px; padding: 9px 11px; font-size: 12.5px; margin: 10px 0;
}
.empty { color: var(--muted); font-size: 13px; padding: 20px 0; text-align: center; }
.spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid var(--line);
  border-top-color: var(--accent); border-radius: 50%; animation: spin .7s linear infinite; vertical-align: -2px; }
@keyframes spin { to { transform: rotate(360deg); } }

/* -------------------------------------------------------------------- map */
#map-wrap { flex: 1; position: relative; min-width: 0; }
#map { position: absolute; inset: 0; background: #101820; }
.map-controls { position: absolute; right: 12px; top: 12px; z-index: 450; display: flex; flex-direction: column; gap: 6px; }
.map-controls .icon-btn { background: var(--bg-2); box-shadow: 0 2px 10px rgba(0,0,0,.4); }
.map-badge {
  position: absolute; left: 50%; transform: translateX(-50%); top: 12px; z-index: 450;
  background: var(--bg-2); border: 1px solid var(--accent); color: var(--text);
  padding: 7px 14px; border-radius: 999px; font-size: 12.5px; box-shadow: 0 4px 18px rgba(0,0,0,.5);
}
/* Said out loud, because a basemap that will not load just looks like a bug. */
.tile-note {
  /* Above the toast, which owns the bottom of the screen. */
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 62px; z-index: 450;
  background: rgba(229,115,94,.14); border: 1px solid rgba(229,115,94,.5);
  color: #f0b3a5; padding: 6px 13px; border-radius: 999px; font-size: 12px;
  box-shadow: 0 4px 18px rgba(0,0,0,.5); pointer-events: none;
}

.legend {
  position: absolute; left: 12px; bottom: 22px; z-index: 450;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 9px;
  padding: 8px 11px; font-size: 12px; max-width: 260px;
}
.legend div { display: flex; align-items: center; gap: 7px; padding: 2px 0; }
.legend i { width: 16px; height: 3px; border-radius: 2px; flex: none; }

.leaflet-container { background: #101820; font: inherit; }
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
  background: var(--bg-2); color: var(--text); border: 1px solid var(--line);
}
.leaflet-popup-content { margin: 10px 12px; font-size: 12.5px; }
.leaflet-popup-content b { font-size: 13px; }
.leaflet-popup-content a { color: var(--accent); }
.leaflet-bar a { background: var(--bg-2); color: var(--text); border-color: var(--line); }
.leaflet-bar a:hover { background: var(--bg-3); color: var(--text); }
.leaflet-control-attribution { background: rgba(15,23,32,.85) !important; color: var(--muted) !important; }
.leaflet-control-attribution a { color: var(--muted) !important; }

/* A stop tooltip carries the lines that call there, filled in on first hover. */
.leaflet-tooltip.stop-tip {
  background: var(--bg-2); border: 1px solid var(--line); color: var(--text);
  box-shadow: 0 8px 22px rgba(0,0,0,.5); max-width: 240px; white-space: normal;
  padding: 7px 9px; font-size: 12.5px;
}
.leaflet-tooltip.stop-tip::before { border-top-color: var(--line); }
.leaflet-tooltip.stop-tip { max-width: 360px; width: max-content; }
.stop-tip .tip-lines { margin-top: 6px; }
.stop-tip .tip-line {
  display: flex; gap: 6px; padding: 4px 0; border-top: 1px solid var(--line);
}
.stop-tip .tip-line > i {
  flex: none; align-self: flex-start; font-style: normal; font-size: 11px;
  font-weight: 700; line-height: 1.5; padding: 1px 5px; border-radius: 5px;
}
.stop-tip .tip-dirs { flex: 1; min-width: 0; }
/* The rule down the left carries this direction's colour on the map. It is the
   only thing tying the seven paths on screen to the seven rows here. */
.stop-tip .tip-dirblock {
  border-left: 3px solid var(--dir); padding-left: 7px; margin-bottom: 4px;
}
.stop-tip .tip-dirblock:last-child { margin-bottom: 0; }
.stop-tip .tip-dir { display: flex; gap: 6px; align-items: baseline; }
.stop-tip .tip-to {
  font-size: 12px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stop-tip .tip-n { color: var(--muted); font-size: 10.5px; flex: none; }
/* The onward run gets one line each: as many stops as the width allows, then a
   chevron and an ellipsis. Wrapping it would make a busy stop taller than the
   map. */
.stop-tip .tip-stops {
  color: var(--muted); font-size: 11px; line-height: 1.5; margin-bottom: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stop-tip .tip-stops em { font-style: normal; color: var(--muted); opacity: .5; padding: 0 4px; }
.stop-tip .tip-rest { color: var(--accent); }
.stop-tip .tip-more { color: var(--muted); font-size: 11px; margin-top: 4px; }
.stop-tip .tip-none { color: var(--muted); font-size: 11.5px; margin-top: 4px; }
.stop-tip small { display: block; color: var(--accent); font-size: 11px; margin-top: 5px; }

/* ---------------------------------------------------- map context menu -- */
.ctx-menu {
  position: absolute; z-index: 900; min-width: 210px; max-width: 280px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.55); padding: 5px; overflow: hidden;
}
.ctx-title {
  padding: 6px 9px 7px; font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); border-bottom: 1px solid var(--line); margin-bottom: 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ctx-item {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: none; border: 0; border-radius: 7px; color: var(--text);
  font: inherit; font-size: 13px; padding: 7px 9px;
}
.ctx-item:hover { background: var(--bg-3); }
.ctx-item.has-badge { display: flex; align-items: center; gap: 8px; }
.ctx-item.has-badge .mini { flex: none; }
.ctx-item .ctx-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctx-item small { display: block; color: var(--muted); font-size: 11px; margin-top: 1px; }
/* Why the rows under it read the way they do. */
.ctx-note {
  padding: 5px 12px 7px; font-size: 11.5px; line-height: 1.35;
  color: var(--muted); max-width: 280px;
}

.ctx-sep { height: 1px; background: var(--line); margin: 4px 2px; }
/* Ties a menu row to the path it draws. Striped when the line runs more than
   one way from the stop, since each direction is drawn in its own colour. */
.ctx-item .ctx-rule { flex: none; width: 3px; align-self: stretch; border-radius: 2px; }

/* Where a hovered line ends up, printed at the end of its path. */
.path-end span {
  position: absolute; transform: translate(-50%, -160%); white-space: nowrap;
  background: rgba(9,14,20,.88); border: 1px solid var(--dir); border-left-width: 3px;
  color: #eaf0f6; font-size: 11px; font-weight: 600; padding: 2px 7px; border-radius: 6px;
  box-shadow: 0 3px 12px rgba(0,0,0,.55); pointer-events: none;
}

.wp-marker {
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent); color: #04120f; font-weight: 700; font-size: 12px;
  border: 2px solid #04120f; box-shadow: 0 2px 8px rgba(0,0,0,.5);
}
.wp-marker.end { background: var(--danger); color: #1a0b07; }
.wp-marker.via { background: #cdd8e3; color: #10161d; }
/* Where the browser says you are. Blue rather than the accent green, because
   it is not part of the route being built and should not read as one. */
.here-dot {
  width: 14px; height: 14px; border-radius: 50%;
  background: #4ea1ff; border: 2px solid #06121f;
  box-shadow: 0 0 0 2px rgba(78,161,255,.35), 0 2px 8px rgba(0,0,0,.5);
  animation: here-pulse 2.4s ease-out infinite;
}
@keyframes here-pulse {
  0%   { box-shadow: 0 0 0 2px rgba(78,161,255,.45), 0 2px 8px rgba(0,0,0,.5); }
  70%  { box-shadow: 0 0 0 12px rgba(78,161,255,0), 0 2px 8px rgba(0,0,0,.5); }
  100% { box-shadow: 0 0 0 2px rgba(78,161,255,0), 0 2px 8px rgba(0,0,0,.5); }
}
@media (prefers-reduced-motion: reduce) { .here-dot { animation: none; } }

/* Waypoints can be dragged straight on the map. */
.wp-marker.draggable { cursor: grab; }
.wp-marker.draggable:hover { transform: scale(1.12); box-shadow: 0 3px 12px rgba(0,0,0,.6); }
.leaflet-dragging .wp-marker.draggable,
.wp-marker.draggable:active { cursor: grabbing; transform: scale(1.2); }
.wp-marker { transition: transform .12s ease, box-shadow .12s ease; }

.toast {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  background: var(--bg-3); border: 1px solid var(--accent); color: var(--text);
  padding: 9px 16px; border-radius: 999px; font-size: 13px; z-index: 900;
  box-shadow: 0 8px 26px rgba(0,0,0,.55);
}

/* --------------------------------------------------------------- narrow */
@media (max-width: 820px) {
  #app { flex-direction: column-reverse; }
  #panel {
    width: 100%; flex: 0 0 var(--panel-h);
    border-right: 0; border-top: 1px solid var(--line);
  }
  #app.panel-hidden #panel { margin-left: 0; margin-bottom: calc(-1 * var(--panel-h)); }
  #map-wrap { flex: 1 1 auto; min-height: 0; }
  /* Stacked, the seam is horizontal and so is the drag. */
  #panel-grip {
    flex: 0 0 11px; width: auto; height: 11px; margin: -5px 0 -6px;
    cursor: row-resize;
  }
  #panel-grip::after { inset: 4px 0 auto; width: auto; height: 3px; }
  #app.resizing { cursor: row-resize; }
}

/* Dark basemap: one tile source, recoloured in the browser. */
/* Dark mode inverts the basemap rather than fetching a second one. Saturation
   comes down hard because inverting a street map leaves whatever green the
   parks were as an olive cast over everything; near-grey reads as a real dark
   map, and the route lines drawn on top keep all the colour. */
.leaflet-container.tiles-dark .leaflet-tile-pane {
  filter: invert(1) hue-rotate(180deg) brightness(.88) contrast(.95) saturate(.15);
}
