/* Map view, routing panel and settings page.
   Loaded after app.css and leaflet.css — every colour goes through the tokens
   defined in app.css so the map honours the same dark/light switch. */

/* ── Liste | Karte toggle ─────────────────────────────── */
.view-toggle { display: none; gap: 0; margin-bottom: .6rem;
  border: 1px solid var(--border-ui); border-radius: 20px; overflow: hidden;
  width: max-content; background: var(--surface); }
.view-toggle.on { display: inline-flex; }
.view-toggle button { background: transparent; color: var(--text-muted); border: none;
  padding: .3rem 1rem; font-size: .82rem; font-family: inherit; cursor: pointer; }
.view-toggle button.on { background: #2471a3; color: #fff; }

/* ── Map shell ────────────────────────────────────────── */
/* position+z-index open a stacking context of their own. Without one, Leaflet's
   positioned descendants land in the root context and compare directly against
   our values — its controls sit at 800..1000, the drawer at 60, so the map won
   and covered the open menu and the filter bar. Containing it beats raising our
   own numbers, which would be a race against someone else's library. */
.map-wrap { display: none; background: var(--surface); border-radius: 10px;
  overflow: hidden; box-shadow: 0 1px 4px var(--shadow);
  position: relative; z-index: 0; }
.map-wrap.on { display: block; }
#map { height: min(70vh, 620px); width: 100%; background: var(--row-hover); }
/* Leaflet paints its own white chrome; the tokens keep it in the dark theme. */
.leaflet-container { font-family: inherit; background: var(--row-hover); }
html.dark .leaflet-control-layers,
html.dark .leaflet-bar a { background: var(--surface); color: var(--text); }
html.dark .leaflet-bar a:hover { background: var(--row-hover); }
html.dark .leaflet-control-attribution { background: rgba(30,32,41,.8); color: var(--text-muted); }
html.dark .leaflet-control-attribution a { color: var(--link); }

/* Switch and map controls share one line; on a narrow screen they wrap rather
   than squeeze. */
.view-row { display: flex; align-items: center; flex-wrap: wrap; gap: .6rem;
  margin-bottom: .6rem; }
.view-row .view-toggle { margin-bottom: 0; }

/* No border-top any more: it separated the note from the map it used to sit
   under, and there is nothing above it to separate from now. */
.map-note { display: none; flex-wrap: wrap; align-items: center; gap: .5rem;
  padding: 0; font-size: .78rem; color: var(--text-muted); }
.map-note.on { display: flex; }
.map-note .mn-warn { color: #e67e22; font-weight: 600; }

/* ── Transport mode selector ──────────────────────────── */
/* Icons only: naming the mode in words was explicitly rejected. */
.mode-pick { display: flex; gap: .3rem; align-items: center; }
.mode-pick button { background: var(--input-bg); border: 1px solid var(--border-ui);
  color: var(--text); border-radius: 20px; padding: .2rem .55rem; cursor: pointer;
  font-size: .95rem; line-height: 1.2; font-family: inherit; }
.mode-pick button.on { border-color: #2471a3; background: #e8f4fd; }
html.dark .mode-pick button.on { background: #1a2a3a; }
/* Der Hinweis, der an die Stelle der Knoepfe tritt, wenn nichts gewaehlt ist.
   ⚠️ Kein eigener Farbton und keine Daempfung ueber opacity: er erbt
   --text-muted von .map-note, und dessen Kontrast rechnet
   tests/test_kontrast.py in beiden Themes nach. Nur schrumpfen darf er, damit
   der Satz auf einem schmalen Schirm nicht aus der Zeile laeuft. */
.mode-pick .mode-none { flex: 1 1 auto; min-width: 0; }

/* ── Markers ──────────────────────────────────────────── */
.pin-home { display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 50%; font-size: 1rem;
  background: #2471a3; color: #fff; border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.4); }
.pin-listing { display: flex; align-items: center; justify-content: center;
  min-width: 26px; height: 26px; padding: 0 .3rem; border-radius: 13px;
  font-size: .68rem; font-weight: 700; color: #fff; border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.35); white-space: nowrap; }
/* Der gewaehlte Pin. Ring statt anderer Farbe: die Farbe gehoert der
   Plattform, und zwei Bedeutungen auf einem Merkmal liest niemand auseinander. */
.pin-listing.pin-selected { outline: 3px solid #fff; outline-offset: 1px;
  transform: scale(1.25); box-shadow: 0 2px 8px rgba(0,0,0,.55); z-index: 1000; }
html.dark .pin-listing.pin-selected { outline-color: #e2e4ea; }

.pin-ricardo { background: #e8843a; }
.pin-tutti   { background: #3d9be9; }
.pin-anibis  { background: #3faf6a; }
.pin-other   { background: #777; }

/* ── Angedocktes Blatt (nur schmale Schirme) ──────────── */
/* Es ueberdeckt die Karte, statt sie zu kuerzen: so bleibt der Ausschnitt exakt
   stehen - genau darum ging es. Der Preis ist, dass Pins im unteren Drittel
   darunter verschwinden. */
/* Am Bildschirmrand, nicht am Kartenrahmen: die Karte ist auf dem Handy 62vh
   hoch und endet unter der Falz - ein dort angedocktes Blatt waere nur zur
   Haelfte zu sehen, und man muesste zum Lesen scrollen. Fixed geht, weil kein
   Vorfahr eine transform traegt, die es einfangen wuerde. */
.map-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 500;
  max-height: 58vh; overflow-y: auto; padding: .7rem .8rem;
  padding-bottom: calc(.7rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--border); border-radius: 10px 10px 0 0;
  box-shadow: 0 -2px 12px var(--shadow);
  /* Halbdurchsichtig, damit die Karte darunter zu erahnen ist. Der Blur ist die
     eigentliche Absicherung: ueber dem Luftbild waere Text auf blossem
     Halbtransparent schwer zu lesen. */
  background: rgba(245, 245, 240, .88);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
html.dark .map-sheet { background: rgba(30, 32, 41, .88); }
/* ⚠️ Ohne diese Regel bleibt das hidden-Attribut wirkungslos: es haengt allein
   an der Browser-Vorgabe display:none, und die Regel oben schlaegt sie. */
.map-sheet[hidden] { display: none; }
/* Kompakter als im Popup: hier konkurriert das Bild mit der Karte um Platz,
   im Popup nicht. */
.map-sheet .rp-img img { height: 110px; }
.ms-close { float: right; background: none; border: none; cursor: pointer;
  font-size: 1.1rem; line-height: 1; padding: 0 0 .2rem .4rem;
  color: var(--text-muted); }
.ms-close:hover { color: var(--text); }

/* ── Routing panel (inside the marker popup) ──────────── */
.leaflet-popup-content { margin: .7rem .8rem; min-width: 210px; }
html.dark .leaflet-popup-content-wrapper,
html.dark .leaflet-popup-tip { background: var(--surface); color: var(--text); }
/* Leaflet's ✕ is near-black and vanishes on the dark surface. */
html.dark .leaflet-container a.leaflet-popup-close-button { color: var(--text-muted); }
html.dark .leaflet-container a.leaflet-popup-close-button:hover { color: var(--text); }
/* Bilder oberhalb der Zahlen: das Inserat erkennt man am Foto, nicht an der
   Reisezeit. Ein Klick oeffnet dieselbe Lightbox wie in der Liste. */
.rp-img { position: relative; margin: -.2rem -.2rem .5rem; border-radius: 6px;
  overflow: hidden; background: var(--row-hover); line-height: 0;
  /* pan-y ist der ganze Punkt: senkrecht scrollt das Blatt weiter, waagrecht
     bekommt das Blaettern. Ohne die Zeile verschluckt der Browser die Geste. */
  touch-action: pan-y; }
.rp-img img { width: 100%; height: 150px; object-fit: cover; cursor: zoom-in; display: block; }
.rp-img.broken { display: none; }
/* Ueber dem Bild, nicht daneben: der Popup ist 300px breit und jede eigene
   Zeile ginge von der Hoehe ab, die das Foto braucht. */
.rp-img-nav { position: absolute; top: 50%; transform: translateY(-50%);
  background: rgba(0,0,0,.45); color: #fff; border: none; cursor: pointer;
  font-size: 1.2rem; line-height: 1; padding: .25rem .45rem; border-radius: 4px; }
.rp-img-nav:hover { background: rgba(0,0,0,.7); }
.rp-img-prev { left: .25rem; }
.rp-img-next { right: .25rem; }
.rp-img-count { position: absolute; right: .3rem; bottom: .3rem; font-size: .68rem;
  color: #fff; background: rgba(0,0,0,.5); border-radius: 3px; padding: .05rem .3rem;
  line-height: 1.5; }
/* Auf Touch wird geblaettert, nicht geklickt - dieselbe Entscheidung wie bei
   .lb-nav in der Lightbox: die Pfeile liegen auf dem Foto und stehlen Tipps.
   Der Zaehler bleibt und ist dort die einzige Anzeige, dass es mehr gibt. */
@media (hover: none) and (pointer: coarse) {
  .rp-img-nav { display: none !important; }
}
.rp-title { font-size: .85rem; font-weight: 600; line-height: 1.35; margin-bottom: .15rem; }
.rp-title a { color: var(--link); }
.rp-sub { font-size: .75rem; color: var(--text-muted); margin-bottom: .5rem; }
.rp-price { font-weight: 700; color: var(--text); }
.rp-rows { display: grid; grid-template-columns: auto 1fr auto; gap: .1rem .5rem;
  align-items: center; }
.rp-row { display: contents; }
.rp-row.on .rp-num, .rp-row.on .rp-icon { font-weight: 700; }
.rp-icon { font-size: 1.05rem; line-height: 1.9; }
/* Tabular figures keep the four rows' numbers in one column. */
.rp-num { font-size: .8rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* No value means no value — an estimate was explicitly rejected. */
.rp-num.rp-none { color: var(--text-muted); }
.rp-go { font-size: .78rem; white-space: nowrap; }
.rp-go[aria-disabled="true"] { color: var(--text-muted); pointer-events: none; }
.rp-foot { margin-top: .5rem; padding-top: .4rem; border-top: 1px solid var(--row-border);
  font-size: .72rem; color: var(--text-muted); }
.rp-tip { font-size: .75rem; color: var(--text-muted); }
/* The drawn line is still on its way. opendata can take ten seconds for a long
   connection, and until this existed that was indistinguishable from a dead
   endpoint. Pulsing, because a static line of text reads as a result. */
.rp-line-wait { animation: rp-pulse 1.2s ease-in-out infinite; }
@keyframes rp-pulse { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .rp-line-wait { animation: none; } }
/* Answered, and the answer was "no line" — never a straight one instead. */
.rp-line-none { font-style: italic; }
/* Wie in der Liste, und genauso endgueltig - deshalb dieselbe Beschriftung und
   derselbe Tooltip, damit niemand zwei verschiedene Dinge dahinter vermutet. */
.rp-hide { display: block; margin-top: .35rem; background: none; border: none;
  padding: 0; cursor: pointer; font-family: inherit; font-size: .72rem;
  color: var(--text-muted); text-decoration: underline; }
.rp-hide:hover { color: var(--danger); }

/* ── Settings page ────────────────────────────────────── */
/* Left-aligned, not centred: a narrow column floating in the middle of a wide
   screen read as a different product than the rest of the app. */
.set-wrap { max-width: 860px; margin: 2rem 0 2rem 0; padding: 0 1.5rem;
  display: flex; flex-direction: column; gap: 1.1rem; }
.set-box { background: var(--surface); border-radius: 10px; padding: 1.2rem;
  box-shadow: 0 1px 4px var(--shadow); }
.set-box h2 { font-size: 1rem; margin-bottom: .8rem; }

/* Ueberschrift einer Gruppe von Kaesten. Kein eigener Kasten, sondern eine
   Beschriftung darueber: die Seite hatte fuenf gleich aussehende Bloecke, und
   welcher wozu gehoerte, musste man aus dem Titel raten. */
.set-group { font-size: .78rem; text-transform: uppercase; letter-spacing: .06em;
             color: var(--text-muted); margin: 1.6rem 0 .6rem .2rem; font-weight: 600; }
.set-group:first-of-type { margin-top: 0; }

/* Die zwei Ansichtsschalter. Sie standen bis v0.14.32 in der Schublade und
   tragen dort wie hier die Klasse .btn-toggle -- gleiches Aussehen, neuer Ort. */
.set-toggles { display: flex; gap: .5rem; flex-wrap: wrap; }
.set-toggles .btn-toggle { flex: 1 1 10rem; }
.set-hint { font-size: .78rem; color: var(--text-muted); line-height: 1.5; }
.set-row { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.set-row input[type=text] { flex: 1; min-width: 180px; padding: .5rem .75rem;
  border: 1px solid var(--border-ui); border-radius: 6px; font-size: .87rem;
  background: var(--input-bg); color: var(--text); font-family: inherit; }
.set-icon-btn { background: var(--input-bg); border: 1px solid var(--border-ui);
  color: var(--text); border-radius: 6px; padding: .45rem .7rem; cursor: pointer;
  font-size: 1rem; line-height: 1.2; }
.set-icon-btn:hover { border-color: #2471a3; }
.set-resolved { margin-top: .55rem; font-size: .83rem; }
.set-resolved.err { color: var(--danger); }
.set-mini-map { display: none; height: 240px; margin-top: .7rem; border-radius: 8px;
  overflow: hidden; background: var(--row-hover); }
.set-mini-map.on { display: block; }
.set-defs { display: grid; grid-template-columns: max-content 1fr; gap: .35rem .9rem;
  font-size: .87rem; }
.set-defs dt { color: var(--text-muted); }
.set-defs dd { word-break: break-word; }
.set-back { font-size: .85rem; }

/* Danger zone — visually separated, not just a red button. */
.set-danger { border: 1px solid #c0392b; }
/* ⚠️ #c0392b lag im dunklen Theme bei 2.98:1 auf --surface. --danger traegt
   dort #e45d4f (4.62:1) und hell weiterhin #c0392b (5.44:1). */
.set-danger h2 { color: var(--danger); }
.set-danger .set-hint { color: var(--text); }
.set-del-panel { display: none; margin-top: .9rem; padding-top: .8rem;
  border-top: 1px dashed #c0392b; }
.set-del-panel.on { display: block; }
.set-del-panel input { text-transform: none; letter-spacing: .08em; }
.set-del-state { margin-top: .5rem; font-size: .82rem; color: var(--text-muted); }

@media (max-width: 768px) {
  #map { height: 62vh; }
  .set-wrap { padding: 0 .75rem; margin: 1rem 0; }
  .set-box { padding: 1rem; }
  .set-defs { grid-template-columns: 1fr; gap: .1rem; }
  .set-defs dd { margin-bottom: .4rem; }
}


/* ── Collapsible settings boxes ───────────────────────── */
/* Same .on convention as .set-mini-map and .set-del-panel, so the page has one
   way of opening things rather than three. */
.set-box h2 { margin-bottom: 0; }
.set-box.on h2 { margin-bottom: .8rem; }
.set-toggle { display: flex; align-items: center; justify-content: space-between; width: 100%;
  background: none; border: none; padding: 0; margin: 0; cursor: pointer;
  font: inherit; color: inherit; text-align: left; }
.set-caret { flex-shrink: 0; margin-left: .6rem; transition: transform .15s ease;
  color: var(--text-muted); font-size: .8rem; }
.set-caret::before { content: "▾"; }
.set-box:not(.on) .set-caret { transform: rotate(-90deg); }
.set-body { display: none; }
.set-box.on .set-body { display: block; }
.set-logout { margin-top: .9rem; padding-top: .7rem; border-top: 1px solid var(--row-border); }


/* FAQ step lists — same muted size as .set-hint, but numbered and indented. */
.faq-steps { margin: .6rem 0 .8rem 1.1rem; padding: 0; font-size: .82rem;
  line-height: 1.7; color: var(--text); }
.faq-steps li { margin-bottom: .2rem; }

/* ── Impressum und Datenschutzerklärung ───────────────── */
/* Zwei öffentliche Seiten ohne Menü. Ohne diese Zeile bliebe auf breiten
   Schirmen die Spalte für eine Schublade reserviert, die es hier nicht gibt
   (siehe das min-width:1024px-Raster in app.css). */
@media (min-width: 1024px) {
  body.legal { display: block; }
  /* Mit dem Raster faellt auch die Inhaltsspalte weg, die die Box getragen hat:
     .set-wrap hat seitlich margin 0 und klebte deshalb am linken Schirmrand,
     waehrend dieselbe Box auf der Einstellungsseite in der Rasterspalte sitzt.
     margin-inline:auto stellt die Mitte wieder her, ohne das Raster
     zurueckzuholen. */
  body.legal .set-wrap { margin-inline: auto; }
  /* Der Kopf zieht mit: auf der Einstellungsseite fluchtet der Titel mit der
     linken Kante des ersten Kastens, weil beide in derselben Rasterspalte
     beginnen. Bliebe er hier am Schirmrand stehen, haetten Titel und Inhalt
     nichts mehr miteinander zu tun. Dasselbe Mass wie .set-wrap: 860px plus
     dessen seitliche 1.5rem. */
  body.legal header { padding-inline: 0; }
  body.legal header .title { max-width: 860px; margin-inline: auto; padding-inline: 1.5rem; }
}
.legal-text { font-size: .87rem; line-height: 1.65; }
.legal-adresse { font-size: .92rem; line-height: 1.7; }
.legal-adresse + .legal-adresse { margin-top: .8rem; }
.legal-liste { margin: 0 0 0 1.1rem; padding: 0; font-size: .87rem; line-height: 1.65; }
.legal-liste li { margin-bottom: .5rem; }
.legal-liste li:last-child { margin-bottom: 0; }
.legal-text + .legal-liste { margin-top: .6rem; }
.legal-liste + .set-hint { margin-top: .7rem; }
.legal-text + .set-hint { margin-top: .7rem; }

/* Reisearten je Konto (DID-267). Native Kaestchen mit Beschriftung —
   jedes ist fuer sich anklickbar und mit der Tastatur erreichbar. */
.set-modes { display: flex; flex-wrap: wrap; gap: .4rem .9rem; margin-bottom: .6rem; }
.set-mode { display: inline-flex; align-items: center; gap: .35rem;
  min-height: 32px; font-size: .9rem; cursor: pointer; }
/* Eine Zeile je Reiseart. Vorher ein <dl>, dort stapeln sich dt und dd:
   "Velo" stand auf einer Zeile fuer sich, der Wert darunter. */
.set-list { list-style: none; margin: .2rem 0 .6rem; padding: 0;
  font-size: .85rem; color: var(--text-muted); }
.set-list li { padding: .1rem 0; }
