:root {
  --bg:        #f4f6f8;
  --panel:     #ffffff;
  --surface:   #ffffff;   /* Karten, Listen, schwebende Leisten */
  --sunken:    #eef2f6;   /* zurückgesetzte Flächen, zweitrangige Tasten */
  --hover:     #f0f7f2;
  --glass:     rgba(255,255,255,.94);  /* halbtransparent über der Karte */
  --ink:       #1c2733;
  --ink-soft:  #5b6b7b;
  --line:      #e2e8ee;
  --brand:     #1e824c;
  --brand-dk:  #166138;
  --accent:    #2d7dd2;
  --danger:    #d9534f;
  --shadow:    0 2px 10px rgba(20,40,60,.08);
  --radius:    10px;
  --poi-scale: 1;         /* wächst beim Hineinzoomen, gesetzt von map.js */
  /* Meldungsleiste: eigene Farben, weil sie sich vom Untergrund absetzen muss
     und nicht mit ihm mitwandern darf. Sie stand vorher auf var(--ink) mit
     weißer Schrift – im Nachtmodus wurde daraus Weiß auf Fast-Weiß. */
  --toast-bg:  #1c2733;
  --toast-ink: #ffffff;
}

/* ===== Nachtmodus =====
   Wird von map.js gesetzt, sobald die dunkle Karte gewählt ist. Zweck ist
   nicht Geschmack, sondern Akkulaufzeit: auf einem OLED-Display kostet ein
   schwarzes Pixel praktisch nichts. Eine weiße Reiterleiste über der
   schwarzen Karte hätte den Effekt zunichte gemacht und obendrein geblendet.
   Nur die Farbwerte werden getauscht — kein Bauteil kennt den Modus. */
:root[data-theme="dark"] {
  --bg:      #0d1117;
  --panel:   #131a22;
  --surface: #161e27;
  --sunken:  #1e2832;
  --hover:   #1c2c24;
  --glass:   rgba(19,26,34,.94);
  --ink:     #e6edf3;
  --ink-soft:#93a3b3;
  --line:    #2a3641;
  /* Beide Marken-Töne aufgehellt: das satte Grün/Blau von Tag verschwand auf
     dunklem Grund fast, der Kontrast reichte nicht mehr fürs Fahren. */
  --brand:   #2ea365;
  --brand-dk:#258452;
  --accent:  #3f8fd4;
  --danger:  #e5706c;
  --shadow:  0 2px 10px rgba(0,0,0,.55);
  /* Nachts umgekehrt: heller Riegel mit dunkler Schrift. Auf der fast
     schwarzen Karte ist das der stärkste Kontrast, den es gibt. */
  --toast-bg:  #e8eef5;
  --toast-ink: #0d1117;
}

/* MapLibres eigene Bedienelemente kennen unsere Tokens nicht. */
:root[data-theme="dark"] .maplibregl-ctrl-group,
:root[data-theme="dark"] .maplibregl-ctrl-group button,
:root[data-theme="dark"] .maplibregl-popup-content {
  background: var(--surface);
  color: var(--ink);
}
:root[data-theme="dark"] .maplibregl-popup-tip { border-top-color: var(--surface); border-bottom-color: var(--surface); }
:root[data-theme="dark"] .maplibregl-popup-close-button { color: var(--ink); }
:root[data-theme="dark"] .maplibregl-ctrl-group button + button { border-top-color: var(--line); }
/* Die Icons sind schwarze SVGs – auf dunklem Grund unsichtbar. */
:root[data-theme="dark"] .maplibregl-ctrl-icon { filter: invert(1) brightness(1.6); }
:root[data-theme="dark"] .maplibregl-ctrl-attrib { background: var(--glass) !important; }
:root[data-theme="dark"] .maplibregl-ctrl-attrib a { color: var(--ink-soft); }
:root[data-theme="dark"] input[type="text"],
:root[data-theme="dark"] input[type="email"],
:root[data-theme="dark"] input[type="password"],
:root[data-theme="dark"] select,
:root[data-theme="dark"] textarea {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--line);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  color: var(--ink);
  background: var(--bg);
  overflow-x: hidden;   /* kein seitliches Scrollen auf dem Handy */
}

/* ---------- Layout ---------- */
.app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 18px;
  background: var(--brand);
  color: #fff;
  box-shadow: var(--shadow);
  z-index: 10;
  /* Angemeldet kommen Name + Abmelden dazu. Ohne diese beiden Zeilen wuchs die
     Zeile über die Displaybreite hinaus, schob Logo und Titel aus dem Bild und
     machte die ganze Seite seitlich verschiebbar. */
  min-width: 0;
  overflow: hidden;
  flex-wrap: nowrap;
}
.topbar .logo { font-size: 22px; flex: 0 0 auto; }
.topbar h1 { font-size: 17px; margin: 0; font-weight: 600; letter-spacing: .2px; flex: 0 1 auto; white-space: nowrap; }
.topbar .tag { font-size: 12px; opacity: .85; margin-left: auto; }
.topbar.bike { background: var(--accent); }
.appnav { margin-left: auto; display: flex; gap: 6px; flex: 0 0 auto; }
.appnav a {
  color: #fff; text-decoration: none; font-size: 13px; font-weight: 600;
  padding: 5px 11px; border-radius: 6px; opacity: .82; transition: background .15s, opacity .15s;
}
.appnav a:hover { opacity: 1; background: rgba(255,255,255,.16); }
.appnav a.active { background: rgba(255,255,255,.22); opacity: 1; }

.main {
  flex: 1;
  display: flex;
  min-height: 0;
  position: relative;   /* Bezug für die schwebende Melde-Leiste */
}

.sidebar {
  width: 370px;
  flex-shrink: 0;
  background: var(--panel);
  border-right: 1px solid var(--line);
  overflow-y: auto;
  overflow-x: hidden;
  padding: 16px;
}

#map {
  flex: 1;
  min-width: 0;
}

/* Trennt Suchen- von Einstellungen-Inhalt auf dem Desktop, wo beide Blöcke
   ohne Tab-Umschaltung untereinanderstehen (siehe .panel-settings weiter unten
   für die mobile Sichtbarkeitslogik). */
.panel-settings {
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

/* ---------- Modus-Umschalter ---------- */
.modes {
  display: flex;
  gap: 6px;
  background: var(--bg);
  padding: 5px;
  border-radius: var(--radius);
  margin-bottom: 14px;
}
.mode-btn {
  flex: 1;
  border: none;
  background: transparent;
  padding: 9px 6px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  transition: background .15s, color .15s;
}
.mode-btn .ic { font-size: 18px; }
.mode-btn:hover { background: var(--sunken); }
.mode-btn.active {
  background: var(--brand);
  color: #fff;
  box-shadow: var(--shadow);
}

.hint {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-soft);
  background: var(--hover);
  border-left: 3px solid var(--brand);
  padding: 9px 11px;
  border-radius: 6px;
  margin-bottom: 16px;
}

/* ---------- Eingabe ---------- */
.section-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--ink-soft);
  margin: 4px 0 8px;
  font-weight: 700;
}

.address-input { position: relative; }
.address-input .row {
  /* Adressen wie "Stadtmauer 1, 31535 Neustadt am Rübenberge" passen bei
     flex:1 neben dem Suchen-Button oft nicht in die schmale Sidebar – der
     eingegebene Text scrollt beim Tippen aus dem Feld. Der Button rutscht
     jetzt in eine eigene Zeile, sobald für Feld+Button nicht genug Platz ist,
     statt das Feld auf Briefmarkenbreite zu quetschen. */
  flex-wrap: wrap;
}
.address-input .row input[type="text"] { min-width: 220px; }
.addr-plz-row { margin-bottom: 8px; align-items: center; flex-wrap: nowrap; }
.addr-plz-row #addrPlz { flex: 0 0 auto; width: 90px; min-width: 90px; }
.addr-plz-row #addrBtn { flex: 0 0 auto; }
.ort-chip {
  border: 1px dashed var(--line);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 13px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  text-align: left;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Vorschlag: noch nicht bestätigt, ein Klick übernimmt den Ort. */
.ort-chip.suggest { border-style: solid; border-color: var(--brand); color: var(--ink); }
/* Bestätigt: Ort ist fix, Klick setzt PLZ+Ort wieder zurück zum Bearbeiten. */
.ort-chip.confirmed { border-style: solid; border-color: var(--brand); background: var(--brand); color: #fff; }
.row { display: flex; gap: 8px; }
input[type="text"] {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 14px;
  outline: none;
}
input[type="text"]:focus { border-color: var(--accent); }

.btn {
  border: none;
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  background: var(--brand);
  color: #fff;
  transition: background .15s;
  white-space: nowrap;
}
.btn:hover { background: var(--brand-dk); }
.btn:disabled { opacity: .55; cursor: default; }
.btn.secondary { background: var(--sunken); color: var(--ink); }
.btn.secondary:hover { background: var(--line); }

/* Geocode-Vorschläge */
.suggestions {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--shadow);
  position: absolute;
  left: 0; right: 0;
  z-index: 20;
  max-height: 220px;
  overflow-y: auto;
}
.suggestions:empty { display: none; }
.suggestions li {
  padding: 9px 12px;
  font-size: 13px;
  cursor: pointer;
  border-bottom: 1px solid var(--line);
}
.suggestions li:last-child { border-bottom: none; }
.suggestions li:hover { background: var(--hover); }
.suggestions li .src { font-size: 10.5px; color: var(--ink-soft); }

/* CSV */
.csv-box {
  margin: 12px 0 18px;
  border: 1px dashed var(--line);
  border-radius: 8px;
  padding: 12px;
  text-align: center;
  font-size: 12.5px;
  color: var(--ink-soft);
}
.csv-box input { display: none; }
.csv-box code { background: var(--sunken); padding: 1px 5px; border-radius: 4px; font-size: 11.5px; }

/* Wegpunkt-Liste */
.waypoints { list-style: none; margin: 0; padding: 0; }
.waypoints li {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 8px;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.wp-num {
  width: 24px; height: 24px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.wp-num.start { background: var(--brand); }
.wp-num.via   { background: #7b4bd6; }
.wp-body { flex: 1; min-width: 0; }
/* Beide als Block: an einem inline-Element greifen overflow/text-overflow
   nicht, die vollständige Adresse schob die Seitenleiste um ihre halbe Breite
   nach rechts – auf dem Telefon ließ sich damit die ganze Seite verschieben. */
.wp-label { font-weight: 600; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wp-addr  { display: block; color: var(--ink-soft); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wp-eta {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--brand-dk);
  font-variant-numeric: tabular-nums;
}
.wp-actions { display: flex; gap: 4px; flex-shrink: 0; }
.icon-btn {
  border: none; background: transparent; cursor: pointer;
  font-size: 15px; padding: 3px 5px; border-radius: 6px; line-height: 1;
}
.icon-btn:hover { background: var(--sunken); }
.icon-btn:disabled { opacity: .25; cursor: default; }
.icon-btn:disabled:hover { background: transparent; }
/* Pfeile schmaler halten, damit die Aktionsleiste nicht umbricht */
.icon-btn.js-up, .icon-btn.js-down { font-size: 11px; padding: 3px 2px; }

.empty { color: var(--ink-soft); font-size: 13px; text-align: center; padding: 18px 8px; }

.counter { font-size: 12px; color: var(--ink-soft); margin: 10px 0 4px; }

.toast {
  position: fixed;
  bottom: 18px; left: 50%;
  transform: translateX(-50%);
  background: var(--toast-bg);
  color: var(--toast-ink);
  padding: 10px 18px;
  border-radius: 8px;
  font-size: 13px;
  box-shadow: var(--shadow);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s;
  z-index: 1000;
}
.toast.show { opacity: 1; pointer-events: auto; }
.toast-undo {
  margin-left: 12px;
  /* currentColor: folgt der Schriftfarbe der Leiste, damit der Knopf in
     beiden Ansichten lesbar bleibt. */
  border: 1px solid currentColor;
  background: transparent; color: inherit;
  border-radius: 6px; padding: 5px 11px;
  font-size: 12.5px; font-weight: 700; cursor: pointer; opacity: .9;
}
.toast-undo:hover { opacity: 1; }

/* ===== Schnellerfassung: vier Tasten rechts an der Karte =====
   Absichtlich große Flächen – das muss im Fahren und mit Handschuhen
   getroffen werden, nicht am Schreibtisch mit der Maus. */
/* Liegt neben der Karte im .main-Container (nicht in der Karte), damit sie im
   Querformat eine echte Seitenleiste werden kann. Am Schreibtisch schwebt sie
   weiterhin rechts über der Karte. */
.qp-bar {
  position: absolute;
  right: 10px; top: 50%;
  transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 8px;
  z-index: 5;
}
.qp-head { display: flex; flex-direction: column; gap: 8px; align-items: center; }
.qp-grid { display: flex; flex-direction: column; gap: 8px; }
/* Eigene Ortungs-/3D-Knöpfe: nur im Querformat sichtbar, sonst nutzt die App
   MapLibres eigene Bedienelemente oben rechts in der Karte. */
.qp-ctrl { display: none; }
.qp-title {
  font-size: 10px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-soft);
  background: var(--glass);
  padding: 3px 7px; border-radius: 5px; text-align: center;
  box-shadow: var(--shadow);
}
/* Die Grafiken bringen ihre eigene gerundete Fläche mit -> der Knopf selbst
   bleibt unsichtbar. overflow:hidden schneidet die weißen Ecken der PNGs weg. */
.qp-btn {
  width: 46px; height: 46px;
  border: none; padding: 0;
  background: transparent;
  border-radius: 12px;
  overflow: hidden;
  cursor: pointer;
  box-shadow: var(--shadow);
  display: flex; align-items: center; justify-content: center;
  transition: transform .1s;
}
/* contain statt cover: sollte der Knopf je nicht exakt quadratisch sein,
   entsteht ein unsichtbarer Rand – aber nie ein Beschnitt der Grafik. */
.qp-img         { width: 100%; height: 100%; display: block; object-fit: contain; }
.qp-btn:active  { transform: scale(.92); }
.qp-ico         { font-size: 22px; line-height: 1; }
.qp-btn.busy    { opacity: .5; pointer-events: none; }
.qp-btn.busy .qp-img { animation: qp-pulse .8s ease-in-out infinite; }
@keyframes qp-pulse { 50% { opacity: .3; } }

/* Marker der gemeldeten Punkte */
/* Eigene Meldungen teilen sich Form und Größe mit den übrigen POIs
   (.poi-marker weiter unten); hier bleibt nur, was sie davon unterscheidet.
   Zwei Klassen im Selektor, damit dieses --poi-w gewinnt: .poi-marker steht
   weiter unten und würde es sonst allein durch seine Position überschreiben. */
.poi-marker.qp-marker { --poi-w: 30px; background: var(--poi-col); padding: 2.5px; }
/* Farbe wandert nach außen als Ring, innen bleibt Weiß – nur so ist die
   Zeichnung der Melde-Taste im Marker überhaupt zu erkennen. */
.poi-marker.qp-marker > span { background: #fff; }
.qp-marker-img {
  width: 88%; height: 88%;
  object-fit: contain;
  display: block;
  pointer-events: none;
}

/* ===== Rückfrage über der Karte =====
   Erscheint im Fahren, wenn der Suchmodus etwas gefunden hat. Bewusst groß und
   nur zwei Flächen: mit Handschuhen, in Bewegung, mit einem Blick. Sie liegt
   über der Melde-Leiste, damit man nicht versehentlich daneben trifft. */
.ask-box {
  position: absolute;
  left: 10px; right: 10px; bottom: 10px;
  z-index: 30;
  display: none;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: var(--toast-bg);
  color: var(--toast-ink);
  border-radius: 14px;
  box-shadow: 0 4px 20px rgba(0,0,0,.5);
}
.ask-box.an { display: flex; }
.ask-text { font-size: 17px; font-weight: 700; line-height: 1.3; }
.ask-row { display: flex; gap: 10px; }
.ask-btn {
  flex: 1 1 0;
  border: none;
  border-radius: 10px;
  padding: 16px 10px;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}
.ask-btn.ja   { background: var(--brand); color: #fff; }
.ask-btn.nein { background: transparent; color: inherit; border: 1.5px solid currentColor; }
.ask-btn:active { transform: scale(.97); }

/* ===== Merkmal-Raster (Dach/WC) vor dem Eintragen =====
   Erscheint nach einem Druck auf eine Melde-Taste, die mehrere Varianten
   derselben Sache zusammenfasst (Rastmöglichkeit: Bank, mit Dach, mit WC -
   seit der Zusammenlegung keine eigenständigen Punkt-Typen mehr, siehe
   quickpoi.js ATTRS_BY_TYPE). Gleiche Optik+Position wie die Rückfrage-Box
   oben - beide erscheinen nie gleichzeitig (Melden- vs. Finden-Modus). */
.qp-attr-box {
  position: absolute;
  left: 10px; right: 10px; bottom: 10px;
  z-index: 30;
  display: none;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: var(--toast-bg);
  color: var(--toast-ink);
  border-radius: 14px;
  box-shadow: 0 4px 20px rgba(0,0,0,.5);
}
.qp-attr-box.an { display: flex; }
.qp-attr-title { font-size: 15px; font-weight: 700; }
.qp-attr-toggles { display: flex; gap: 10px; }
.qp-attr-toggle {
  flex: 1 1 0;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  border: 1.5px solid currentColor;
  background: transparent;
  color: inherit;
  border-radius: 10px;
  padding: 10px 6px;
  font-size: 12.5px; font-weight: 700;
  cursor: pointer;
}
.qp-attr-ico svg { width: 22px; height: 22px; display: block; }
.qp-attr-toggle.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.qp-attr-row { display: flex; gap: 10px; }
.qp-attr-btn {
  border: none;
  border-radius: 10px;
  padding: 14px 10px;
  font-size: 18px;
  font-weight: 700;
  cursor: pointer;
}
/* Grüner Haken bestätigt, wie beim Ja/Nein oben - Abbrechen bleibt schmal
   und zurückhaltend, damit der Daumen nicht aus Versehen dort landet. */
.qp-attr-btn.cancel  { flex: 0 0 56px; background: transparent; color: inherit; border: 1.5px solid currentColor; }
.qp-attr-btn.confirm { flex: 1 1 0; background: var(--brand); color: #fff; }
.qp-attr-btn:active { transform: scale(.97); }

/* ===== Umschalter Melden / Finden =====
   Sitzt über den vier Melde-Tasten und sagt an, was der nächste Druck tut.
   Absichtlich ein sichtbarer Schalter statt langem Druck oder Doppeltipp:
   Was Timing verlangt, misslingt mit Handschuhen auf schlechtem Weg. */
.qp-mode {
  display: flex;
  /* Am Rechner ist die Melde-Leiste nur eine schmale Spalte – nebeneinander
     wären die Beschriftungen dort abgeschnitten. Hochkant am Telefon läuft die
     Leiste über die volle Breite, dort schaltet die Medienabfrage auf eine
     Zeile um. */
  flex-direction: column;
  gap: 4px;
  background: var(--sunken);
  border-radius: 9px;
  padding: 3px;
  flex: 0 0 auto;
  min-width: 0;
}
.qp-mode-btn {
  flex: 1 1 0;
  min-width: 0;
  border: none;
  background: transparent;
  border-radius: 7px;
  padding: 7px 4px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
  cursor: pointer;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
/* Wort nur dort, wo Platz ist (Medienabfrage weiter unten schaltet es ein). */
.qp-mode-txt { display: none; }
.qp-mode-ico { font-size: 15px; line-height: 1; }
.qp-mode-btn.active { background: var(--brand); color: #fff; }
.qp-mode-btn[data-mode="finden"].active { background: #b45309; }
/* Im Suchmodus bekommt der Schalter einen warmen Rand – man soll nicht aus
   Versehen etwas eintragen wollen und umgekehrt. Der Rand sitzt am Schalter
   und nicht an der Leiste: die ist hochkant durchsichtig, ein Kasten um nichts
   herum sähe nach Fehler aus. */
.qp-bar.finden .qp-mode { box-shadow: 0 0 0 2px #b45309; }

.spinner {
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid rgba(255,255,255,.4);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin .7s linear infinite;
  vertical-align: -2px;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Route-Optionen */
.route-opts { margin-bottom: 12px; }
.opt-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  font-size: 13px;
  color: var(--ink);
}
/* Autor-Regel schlägt sonst IMMER den UA-Standard für [hidden] (unabhängig von
   Reihenfolge/Spezifität) – ohne das hier bleibt jede per .hidden=true
   versteckte Zeile trotzdem sichtbar. Gleicher Bug wie bei .radar-strip
   weiter oben, hier zusätzlich für die Stimmwahl-Zeile aufgefallen. */
.opt-row[hidden] { display: none; }
/* min-width:0 auf select nötig, sonst wächst es auf die Breite des längsten
   Stimmennamens (z.B. "Microsoft Hedda - German (Germany) (de-DE, lokal)")
   und schiebt den Testen-Knopf aus der Seitenleiste heraus. */
.voice-row { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1; }
.voice-row select { flex: 1; min-width: 0; text-overflow: ellipsis; }
.voice-row button { flex: 0 0 auto; white-space: nowrap; }
.opt-row select {
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: 7px;
  font-size: 13px;
  background: var(--surface);
}
.opt-row.switch input { width: 18px; height: 18px; accent-color: var(--brand); }
.opt-row.col { flex-direction: column; align-items: stretch; gap: 6px; }
.opt-row.col > span { font-weight: 600; color: var(--ink-soft); font-size: 12px; }
.chk { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 400; cursor: pointer; }
.chk input { width: 16px; height: 16px; accent-color: var(--brand); }
.chk.sub { margin-left: 22px; color: var(--ink-soft); }
/* Zwei Spalten für die kurzen Schalter – spart rund die halbe Höhe. Fällt bei
   sehr schmalen Geräten von selbst auf eine Spalte zurück. */
.chk-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 2px 10px;
  margin-top: 2px;
}
.chk.disabled { opacity: .45; cursor: default; }
/* Schnellwahl-Profile über den Rad-Präferenzen */
.preset-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.preset-btn {
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  border-radius: 999px; padding: 6px 11px; font-size: 12px; cursor: pointer;
}
.preset-btn:hover { background: var(--hover); }
.preset-btn.active { background: var(--brand); color: #fff; border-color: var(--brand); }
.chk.sub small { opacity: .75; }
.seg { display: flex; gap: 4px; background: var(--bg); padding: 3px; border-radius: 7px; }
.seg-btn {
  border: none; background: transparent; cursor: pointer;
  padding: 6px 10px; border-radius: 5px; font-size: 12.5px; font-weight: 600; color: var(--ink-soft);
}
.seg-btn.active { background: var(--brand); color: #fff; }

.btn.wide { width: 100%; padding: 12px; font-size: 15px; margin-bottom: 12px; }

.result {
  background: var(--hover);
  border: 1px solid #cfe6d8;
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 8px;
}
.res-main { font-size: 20px; font-weight: 700; color: var(--brand-dk); }
.res-sub  { font-size: 12px; color: var(--ink-soft); margin-top: 3px; }
.res-ankunft { font-size: 13px; font-weight: 600; margin-top: 5px; }
.res-stau { font-size: 12.5px; font-weight: 600; color: #b45309; margin-top: 3px; }

.legend { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 12px; font-size: 12px; color: var(--ink-soft); }
.legend span { display: inline-flex; align-items: center; gap: 5px; }
.legend i { width: 14px; height: 4px; border-radius: 2px; display: inline-block; }

/* Karten-Layer-Buttons */
/* flex-wrap: bei 5 Tasten (Laden/Rast/Betriebe/Radnetz/Regenradar) reicht eine
   Zeile auf dem Handy nicht mehr – ohne Umbruch schob das den ganzen Block
   nach rechts aus dem Rahmen. */
.layers { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.layer-btn {
  flex: 1 1 calc(50% - 8px);
  min-width: 90px;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 8px;
  padding: 9px 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: background .15s, border-color .15s;
}
.layer-btn:hover { background: var(--hover); }
.layer-btn.active { background: var(--brand); color: #fff; border-color: var(--brand); }
.layer-btn .badge {
  background: rgba(255,255,255,.25);
  border-radius: 10px;
  padding: 0 6px;
  font-size: 11px;
}
.layer-btn:not(.active) .badge { background: var(--sunken); color: var(--ink-soft); }

.spinner.dark { border-color: rgba(0,0,0,.2); border-top-color: var(--brand); }

/* Zeitschritte fürs Regenradar – als Kartensteuerung statt Sidebar-Leiste:
   nur in der Sidebar (Einstellungen) sichtbar zu sein half beim Planen
   nichts, wenn man gerade auf die Karte schaut. Sitzt daher direkt auf der
   Karte, gleich unter dem Wetter-Badge (beide top-left). */
.ctrl-radar-badge {
  display: flex; align-items: center; gap: 2px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  padding: 3px 6px; box-shadow: 0 1px 4px rgba(0,0,0,.15);
}
/* Ohne diese Zeile gewinnt die Klassenregel (display:flex) gegen das
   hidden-Attribut, weil Autor-CSS grundsätzlich vor dem UA-Standardstil des
   Browsers steht – gleicher Bug wie beim Vorgänger .radar-strip, hier gleich
   von Anfang an mitgedacht. */
.ctrl-radar-badge[hidden] { display: none; }
.ctrl-radar-badge .icon-btn { width: 28px; height: 28px; font-size: 13px; }
.ctrl-radar-badge .icon-btn.active { background: var(--brand); color: #fff; }
.radar-time { min-width: 96px; text-align: center; font-size: 12px;
              font-weight: 600; font-variant-numeric: tabular-nums; padding: 0 4px; }

/* Wetter-Badge: immer sichtbar (auch ohne Route), oben links auf der Karte. */
.ctrl-weather-badge {
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  padding: 5px 10px; font-size: 13px; font-weight: 700; color: var(--ink);
  box-shadow: 0 1px 4px rgba(0,0,0,.15); white-space: nowrap;
}

/* Melde-Button (Streckenplaner): ⚠️-Knopf klappt eine kleine Auswahl auf,
   sitzt unter Wetter/Regenradar (alle top-left). */
.ctrl-report-badge .icon-btn {
  width: 29px; height: 29px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  font-size: 14px; box-shadow: 0 1px 4px rgba(0,0,0,.15);
}
.report-panel {
  margin-top: 4px;
  display: flex; flex-direction: column; gap: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
  padding: 6px; box-shadow: 0 1px 4px rgba(0,0,0,.15);
}
/* Gleicher [hidden]-vs-Autor-Regel-Bug wie bei .ctrl-radar-badge oben. */
.report-panel[hidden] { display: none; }
.report-btn {
  border: 1px solid var(--line); border-radius: 6px; background: var(--surface);
  color: var(--ink); font-size: 12.5px; font-weight: 600; text-align: left;
  padding: 6px 9px; cursor: pointer; white-space: nowrap;
}
.report-btn:hover { background: var(--hover); }
.report-radius { display: flex; gap: 4px; padding-left: 8px; }
.report-radius[hidden] { display: none; }
.report-btn.small { flex: 1; text-align: center; padding: 5px 4px; font-size: 12px; }

/* 3D-Umschalter (Karten-Control) */
.ctrl-3d {
  width: 29px; height: 29px;
  background: var(--surface); border: none; cursor: pointer;
  font-weight: 700; font-size: 12px; color: var(--ink);
  display: flex; align-items: center; justify-content: center;
}
.ctrl-3d:hover { background: var(--hover); }
.ctrl-3d.active { background: var(--brand); color: #fff; }

/* Hell/Dunkel-Umschalter, sitzt direkt unter dem 3D-Knopf. Unterwegs muss der
   Wechsel mit einem Daumendruck gehen – wenn die Sonne aufs Display fällt,
   sucht niemand erst die Auswahlliste in der Suchansicht. */
.ctrl-theme {
  width: 29px; height: 29px;
  background: var(--surface); border: none; cursor: pointer;
  font-size: 14px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.ctrl-theme:hover { background: var(--hover); }

/* Kartenneigung: ziehbarer Regler, sitzt direkt unter Hell/Dunkel. Ersetzt
   die Zwei-Finger-Geste – die bricht ab, sobald einer der beiden Finger
   seitlich abrutscht (Handschuhe, Vibration im Fahren). */
.ctrl-pitch {
  position: relative;
  width: 29px; height: 90px;
  background: var(--surface);
  cursor: ns-resize;
  touch-action: none;
  -webkit-user-select: none; user-select: none;
}
.ctrl-pitch:hover { background: var(--hover); }
.ctrl-pitch::before {
  content: '';
  position: absolute;
  left: 50%; top: 6px; bottom: 6px; width: 4px;
  margin-left: -2px;
  background: var(--line);
  border-radius: 2px;
}
.ctrl-pitch-fill {
  position: absolute;
  left: 50%; bottom: 0; width: 4px;
  margin-left: -2px;
  background: var(--brand);
  border-radius: 2px;
  pointer-events: none;
}
.ctrl-pitch-thumb {
  position: absolute;
  left: 50%; bottom: 0;
  width: 17px; height: 17px;
  background: #fff;
  border: 2px solid var(--brand);
  border-radius: 50%;
  transform: translate(-50%, 50%);
  box-shadow: 0 1px 3px rgba(0,0,0,.4);
  pointer-events: none;
}
.ctrl-pitch.dragging .ctrl-pitch-thumb {
  transform: translate(-50%, 50%) scale(1.15);
}

/* POI-Marker (MapLibre DOM-Marker) */
/* Numbered map markers */
.num-marker {
  width: 26px; height: 26px;
  background: var(--accent);
  color: #fff;
  border: 2px solid #fff;
  border-radius: 50%;
  font-weight: 700;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
.num-marker.start { background: var(--brand); }
.num-marker.end   { background: var(--danger); }
.num-marker.via   { background: #7b4bd6; width: 20px; height: 20px; font-size: 11px; }

/* ---------- Höhenmeter und Höhenprofil ---------- */
.res-hoehe {
  display: flex; gap: 14px;
  margin-top: 6px;
  font-size: 13px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.res-hoehe .auf { color: #d97706; }
.res-hoehe .ab  { color: #0d9488; }
.res-flach { margin-top: 6px; font-size: 12px; color: var(--ink-soft); }

/* Ruhe-Score: Balken in denselben Farben wie die Streckeneinfärbung (KLASS_COLOR in map.js) */
.res-ruhe { margin-top: 8px; }
.ruhe-kopf { display: flex; justify-content: space-between; font-size: 12.5px; color: var(--ink-soft); }
.ruhe-kopf strong { color: var(--ink); font-variant-numeric: tabular-nums; }
.ruhe-bar { display: flex; height: 6px; border-radius: 3px; overflow: hidden; margin-top: 4px; background: var(--sunken); }
.ruhe-seg { display: block; height: 100%; }
.ruhe-detail { font-size: 11.5px; color: var(--ink-soft); margin-top: 3px; }

/* Wetter am Streckenstart */
.res-wetter { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; font-size: 12.5px; color: var(--ink-soft); }
.res-wetter .wt-jetzt { color: var(--ink); font-weight: 600; }
.res-wetter .wt-warnung {
  color: #b45309; font-weight: 700; background: rgba(180,83,9,.12);
  border-radius: 6px; padding: 4px 8px; margin-bottom: 2px;
}

/* Autobahn-GmbH-Hinweise im Ergebnis – rein informativ, klickbar (fliegt hin). */
.res-autobahn { margin-top: 8px; font-size: 12.5px; }
.res-autobahn-head { font-weight: 600; color: var(--ink-soft); margin-bottom: 3px; }
.res-autobahn-item {
  display: flex; gap: 6px; align-items: flex-start;
  padding: 4px 6px; border-radius: 6px; cursor: pointer; color: var(--ink);
}
.res-autobahn-item:hover { background: var(--hover); }
.res-autobahn-mehr { color: var(--ink-soft); padding: 2px 6px; }

.res-profil { position: relative; margin-top: 8px; }
.res-profil svg { display: block; width: 100%; height: 64px; }
.pf-flaeche { fill: var(--brand); opacity: .18; }
.pf-linie   { fill: none; stroke: var(--brand); stroke-width: 1.6;
              vector-effect: non-scaling-stroke; }
/* Beschriftung nicht mit preserveAspectRatio verzerren – deshalb als HTML
   über dem SVG und nicht als <text> darin. */
.pf-max, .pf-min {
  position: absolute; right: 4px;
  font-size: 10.5px; font-weight: 700; color: var(--ink-soft);
  background: var(--glass); padding: 0 3px; border-radius: 3px;
}
.pf-max { top: 0; }
.pf-min { bottom: 0; }

/* ---------- POI-Marker ----------
   Sechseckig statt rund. Die Wegpunkte der Route sind Kreise; solange die POIs
   ebenfalls Kreise waren, war auf der Karte nicht zu erkennen, was zur Route
   gehört und was nur in der Gegend steht. Die Form trägt die Unterscheidung,
   die Farbe und das Zeichen sagen, worum es sich handelt. */
.poi-marker {
  --poi-col: #2563eb;
  --poi-w: 26px;
  /* Größe wächst mit dem Zoom (--poi-scale setzt map.js). Ein fester 26-Pixel-
     Punkt war im Stand gut zu sehen, im Fahren aber zu unauffällig – man soll
     ihn im Vorbeirollen bemerken und nicht suchen müssen. */
  width:  calc(var(--poi-w) * var(--poi-scale, 1));
  height: calc(var(--poi-w) * var(--poi-scale, 1) * 1.1);
  /* Bewusst hart weiß, nicht var(--surface): der helle Ring ist der Kontrast
     zur Karte und muss auch im Nachtmodus über der schwarzen Karte stehen. */
  background: #fff;
  padding: 2px;
  box-sizing: border-box;
  cursor: pointer;
  clip-path: polygon(50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%);
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.5));
  transition: width .12s linear, height .12s linear;
}
.poi-marker > span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%; height: 100%;
  background: var(--poi-col);
  color: #fff;
  font-weight: 700;
  line-height: 1;
  /* Emoji der Melde-Tasten füllen das Sechseck, ohne über die Kanten zu laufen */
  font-size: calc(var(--poi-w) * var(--poi-scale, 1) * 0.5);
  clip-path: polygon(50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%);
}
.poi-marker > span svg { width: 60%; height: 60%; }
.poi-marker.cluster > span {
  font-family: system-ui, sans-serif;
  font-size: calc(var(--poi-w) * var(--poi-scale, 1) * 0.4);
}
/* Noch ungeprüfte eigene Meldung: gelber statt weißer Ring – unterscheidbar,
   ohne dass der Punkt schlechter zu sehen wäre. */
.poi-marker.pending { background: #fbbf24; }
/* Hindernis-Meldung, strittig nach Community-Abstimmung (wartet auf Admin). */
.poi-marker.disputed { background: #ef4444; }

/* Hindernis-Popup (obstacles.js): Status, Stimmenzahl, Bestätigen/Bestreiten. */
.ob-popup { min-width: 160px; }
.ob-reason { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.ob-status { font-size: 12.5px; font-weight: 600; margin-top: 6px; }
.ob-counts { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.ob-vote-row { display: flex; gap: 6px; margin-top: 8px; }
.ob-vote-btn {
  flex: 1; border-radius: 6px; padding: 6px 8px; font-size: 12.5px; font-weight: 600;
  cursor: pointer; border: 1px solid var(--line); background: var(--surface); color: var(--ink);
}
.ob-vote-btn.ob-yes:hover { background: var(--brand); border-color: var(--brand); color: #fff; }
.ob-vote-btn.ob-no:hover  { background: var(--danger); border-color: var(--danger); color: #fff; }
.ob-voted-hint { font-size: 12px; color: var(--ink-soft); margin-top: 6px; font-style: italic; }

/* Wegpunkt aus dem Kartenpopup heraus löschen – unterwegs am Telefon ist die
   Liste in der Seitenleiste zu weit weg. */
.popup-del {
  margin-top: 8px;
  border: none;
  background: var(--danger);
  color: #fff;
  border-radius: 7px;
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  width: 100%;
}

/* ---------- Kartenlegende für die POI-Layer ---------- */
.poi-legend {
  position: absolute;
  /* Bezugsrahmen ist .main, nicht die Karte – deshalb die Breite der
     Seitenleiste dazurechnen, sonst läge die Legende darüber. */
  left: 380px; top: 10px;
  z-index: 9;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 8px 10px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow);
  font-size: 12px;
  color: var(--ink);
  pointer-events: none;
}
.poi-legend[hidden] { display: none; }
/* .poi-legend selbst ist pointer-events:none, damit die Karte darunter
   bedienbar bleibt (Kommentar weiter unten bei ähnlichen Overlays) – die
   Kopfzeile muss das gezielt zurücknehmen, sonst lässt sich der Auf/Zu-
   Knopf nie anklicken. War seit dem Einbau des Knopfs so, ist nur erst
   jetzt aufgefallen. */
.poi-legend-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 11px; font-weight: 700; color: var(--ink-soft); cursor: pointer;
  pointer-events: auto;
}
.poi-legend-toggle {
  border: none; background: none; cursor: pointer; color: var(--ink-soft);
  font-size: 11px; padding: 2px 4px; line-height: 1;
  pointer-events: auto;
}
.poi-legend-body { display: flex; flex-direction: column; gap: 5px; margin-top: 5px; }
.poi-legend.collapsed .poi-legend-body { display: none; }
.poi-legend.collapsed .poi-legend-head { margin: 0; }
.poi-legend .row { display: flex; align-items: center; gap: 7px; white-space: nowrap; }
/* Gleicher [hidden]-vs-Autor-Regel-Bug wie bei .opt-row oben: ohne das zeigt
   die Legende IMMER alle Zeilen (Wegpunkt, Laden, Rast, ...), sobald die Box
   selbst sichtbar ist – unabhängig davon, welcher Layer wirklich aktiv ist. */
.poi-legend .row[hidden] { display: none; }
.poi-legend .sw {
  width: 15px; height: 17px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; color: #fff;
  clip-path: polygon(50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%);
}
.poi-legend .sw.round { border-radius: 50%; clip-path: none; width: 16px; height: 16px; }
.poi-legend .row.muted { color: var(--ink-soft); font-size: 11px; white-space: normal; max-width: 210px; }
.poi-kind { color: var(--ink-soft); font-size: 12px; }
.poi-legend .sw.pin {
  clip-path: none; width: 15px; height: 15px;
  border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
}

/* ---------- Responsive ---------- */
/* ===== Navigationsmodus =====
   Richtungsanzeige am oberen Kartenrand: großer Pfeil, herunterzählende Meter,
   Anweisung. Bewusst kontrastreich und groß – das muss im Fahren mit einem
   Blick erfassbar sein. */
.nav-start { background: #0f766e; }
.nav-start:hover { background: #115e56; }
/* Derselbe Knopf beendet die Fahrt wieder – rot, damit er sich vom Starten
   unterscheidet. Das ✕ in der Fahrtanzeige ist dafür entfallen. */
.nav-start.nav-stop-btn { background: var(--danger); }
.nav-start.nav-stop-btn:hover { background: #b8433f; }

/* Fahrtanzeige: freie Einblendung, KEIN Balken.
   Vorher lag hier ein deckender Riegel ueber der ganzen Breite und verdeckte
   genau den Teil der Karte, auf den man beim Fahren schaut. Jetzt schweben
   Pfeil, Entfernung und Anweisung ueber dem Bild; lesbar bleiben sie durch
   Schattenkante statt durch Flaeche. Das Schliesskreuz ist raus - Beenden
   laeuft ueber den Knopf in der Suchansicht, neben der Fahrtanzeige haette
   man es staendig versehentlich getroffen. */
.nav-hud {
  display: none;
  position: absolute;
  /* Links statt mittig: die Bildmitte gehört der Strecke vor einem. */
  top: 8px; left: 12px; right: auto;
  max-width: 62%;
  z-index: 20;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  pointer-events: none;   /* die Karte darunter bleibt bedienbar */
  text-align: left;
  color: #fff;
  text-shadow: 0 2px 6px rgba(0,0,0,.9), 0 0 14px rgba(0,0,0,.7);
}
.nav-hud.an { display: flex; }
/* Ganz oben: wie weit noch. Kleiner als die Abbiege-Entfernung – die ist im
   Fahren die wichtigere Zahl und darf nicht mit ihr konkurrieren. */
.nav-ziel {
  font-size: 15px; font-weight: 700; opacity: .92;
  font-variant-numeric: tabular-nums;
  margin-bottom: 2px;
}
.nav-text[hidden] { display: none; }
/* Gezeichnete Form statt Schriftzeichen – siehe navi.js. Der Schatten liegt
   als drop-shadow am SVG, text-shadow greift bei Vektorformen nicht. */
.nav-pfeil {
  width: 78px; height: 78px;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.95));
}
.nav-pfeil svg { width: 100%; height: 100%; display: block; }
.nav-meter { font-size: 46px; font-weight: 800; line-height: 1; letter-spacing: -.5px; }
.nav-meter.nah { color: #fbbf24; }
/* Umbruch erlaubt: „an der Gabelung rechts halten" passt sonst nicht unter den
   Pfeil und wurde vorher mit Auslassungspunkten abgeschnitten. */
.nav-text {
  font-size: 17px; font-weight: 600; margin-top: 2px;
  line-height: 1.25;
  white-space: normal;
  overflow-wrap: break-word;
}
/* Steigung voraus – nur sichtbar, wenn es wirklich bergauf oder bergab geht. */
.nav-steig {
  font-size: 15px; font-weight: 800; margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
.nav-steig.auf { color: #fbbf24; }
.nav-steig.ab  { color: #5eead4; }

/* Einziger Knopf, der bleibt: stumm schalten. Klein und abseits. */
.nav-ton {
  pointer-events: auto;
  margin-top: 6px;
  width: 42px; height: 42px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.5);
  background: rgba(15,23,42,.55); color: #fff; font-size: 18px; cursor: pointer;
}
.nav-ton.aus { opacity: .5; }

/* Während der Navigation stört die Melde-Leiste nicht – sie bleibt bedienbar,
   rutscht aber unter die Richtungsanzeige. */
.navi-an .qp-bar { z-index: 10; }

/* Eigener Positionsmarker im Navigationsmodus.
   Beim Radfahren schaut man nur kurz auf den Lenker – deshalb ein großer,
   schwebender Pfeil statt eines Punktes. 56 px, kräftiger Schatten, heller
   Ring darum, damit er auf jedem Kartenhintergrund sofort ins Auge springt. */
.nav-ich {
  /* EINE Zahl bestimmt die Größe, alles andere rechnet mit. Vorher 56 px –
     beim nahen Fahrzoom und mit der Tastenleiste darunter ging der Pfeil
     schlicht unter. Zum Nachjustieren nur diesen Wert ändern.
     --ich-scale kommt von map.js watchZoomScale() (0.4x weit rausgezoomt
     bis 1x ab nahem Fahrzoom) - ohne das blieb der Pfeil bei jeder
     Zoomstufe gleich groß und wirkte beim Rauszoomen riesig. */
  --ich: calc(150px * var(--ich-scale, 1));
  width: var(--ich); height: var(--ich);
  display: flex; align-items: center; justify-content: center;
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.5));
}
.nav-ich-pfeil {
  width: 0; height: 0;
  border-left:  calc(var(--ich) * .30) solid transparent;
  border-right: calc(var(--ich) * .30) solid transparent;
  border-bottom: calc(var(--ich) * .75) solid #2563eb;
  position: relative;
}
/* Innerer heller Keil – gibt dem Pfeil Tiefe und eine klare Spitze */
.nav-ich-pfeil::after {
  content: '';
  position: absolute;
  left: calc(var(--ich) * -.16); top: calc(var(--ich) * .25);
  width: 0; height: 0;
  border-left:  calc(var(--ich) * .16) solid transparent;
  border-right: calc(var(--ich) * .16) solid transparent;
  border-bottom: calc(var(--ich) * .39) solid #93c5fd;
}
/* Halo, damit der Pfeil auch auf blauen Flächen (Wasser) sichtbar bleibt */
.nav-ich::before {
  content: '';
  position: absolute;
  width: calc(var(--ich) * .96); height: calc(var(--ich) * .96);
  border-radius: 50%;
  background: rgba(37, 99, 235, .16);
  border: 2px solid rgba(255,255,255,.75);
}

/* ===== Freie Fahrt aufzeichnen (record.js) =====
   Anders als die Navigation folgt dieser Modus keiner Route – nur eine
   pulsierende Aufnahme-Anzeige mit Zeit und Distanz, keine Abbiegehinweise. */
.rec-hud {
  display: none;
  position: absolute;
  top: 10px; left: 12px;
  z-index: 20;
  background: rgba(15, 23, 42, .72);
  color: #fff;
  border-radius: 10px;
  padding: 8px 14px;
  align-items: center;
  gap: 10px;
  pointer-events: none;
  box-shadow: 0 2px 10px rgba(0,0,0,.4);
}
.rec-hud.an { display: flex; }
.rec-dot {
  width: 12px; height: 12px;
  background: #ef4444;
  border-radius: 50%;
  flex-shrink: 0;
  animation: rec-pulse 1.2s ease-in-out infinite;
}
@keyframes rec-pulse {
  0%, 100% { opacity: 1;  transform: scale(1); }
  50%      { opacity: .4; transform: scale(.7); }
}
.rec-info { display: flex; flex-direction: column; line-height: 1.25; }
.rec-zeit { font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; }
.rec-dist { font-size: 12.5px; opacity: .85; }

/* Zusammenfassung nach dem Stoppen, bevor gespeichert/verworfen wird */
.rec-summary { font-size: 13px; color: var(--ink-soft); margin-bottom: 8px; }
/* Zusammenfassung und Spur-Info tragen jetzt dieselben Bausteine wie das
   Routenergebnis (Kopfzeile, Höhenmeter, Profil) – hier nur die Größe angleichen. */
.rec-summary .res-main, .track-info-text .res-main { font-size: 17px; }

/* Info-Leiste + Kürzen-Griffe für eine geladene Aufzeichnung */
.track-info-row {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 12px;
  font-size: 13px;
}
.track-info-text { color: var(--ink-soft); margin-bottom: 8px; font-size: 13px; }
.track-info-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.track-info-actions .btn { padding: 8px 12px; font-size: 13px; }

.trim-handle {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid #7c3aed;
  box-shadow: 0 1px 5px rgba(0,0,0,.45);
  cursor: grab;
}
.trim-handle.trim-end { border-color: #dc2626; }
.trim-handle:active { cursor: grabbing; }

/* ===== Mobil / Android =====
   Drei Ansichten statt einer gequetschten Sidebar über einer 360-px-Karte:
   Suchen (aktuelle Tour), Einstellungen (dauerhafte Vorgaben), Karte in
   voller Höhe. Nur so haben die Melde-Tasten überhaupt Platz, um brauchbar
   groß zu sein. */
.mobile-tabs { display: none; }

/* Gilt für Hochformat (schmal) UND Querformat am Telefon (breit, aber niedrig).
   Nur `max-width: 720px` reichte NICHT: quer liegend ist ein Telefon 812–1024 px
   breit, damit hätte die Lenkerhalterung das Desktop-Layout bekommen.
   Die Höhe allein reicht auch nicht (Geräte liegen zwischen ~300 und ~700 px,
   je nach Pixeldichte). Deshalb Höhe UND Breite begrenzen: quer liegende
   Telefone sind bis ~1180 breit und höchstens ~720 hoch, ein Desktop ist
   entweder breiter oder höher. `pointer: coarse` wäre eleganter, wird aber
   nicht überall zuverlässig gemeldet – Maße sind hier verlässlicher. */
@media (max-width: 720px),
       (orientation: landscape) and (max-height: 720px) and (max-width: 1180px) {
  .mobile-tabs {
    display: flex;
    border-bottom: 1px solid var(--line);
    background: var(--surface);
  }
  .mtab {
    flex: 1; border: none; background: transparent;
    padding: 10px 4px; font-size: 13px; font-weight: 600;
    color: var(--ink-soft); cursor: pointer;
    border-bottom: 3px solid transparent;
    white-space: nowrap;
  }
  .mtab.active { color: var(--brand); border-bottom-color: var(--brand); }

  /* Kopfzeile ganz weg. Sie kostete rund 40 Pixel Kartenhöhe und enthielt
     nichts, was man im Fahren braucht: Titel, Anmeldung und der Wechsel zum
     Autoplaner stehen jetzt in der Suchansicht. */
  .topbar { display: none; }
  .user-name { max-width: 130px; }

  .main { flex-direction: column; }
}

/* Ganz schmale Telefone im Hochformat: der Name muss weichen. Er würde sonst
   auf ein paar Pixel zusammengedrückt und stünde nur als Strich in der Zeile. */
@media (max-width: 560px) {
  .user-name { display: none; }
}

@media (max-width: 720px),
       (orientation: landscape) and (max-height: 720px) and (max-width: 1180px) {
  .sidebar {
    width: 100%; max-height: none; flex: 1;
    border-right: none; border-bottom: none;
  }
  #map { min-height: 0; flex: 1; }

  /* Immer nur eine der drei Ansichten. Auf dem Desktop stehen Suchen und
     Einstellungen einfach untereinander in derselben Seitenleiste – erst hier,
     im mobilen Layout, wird daraus eine Auswahl. */
  .main.view-search   #map            { display: none; }
  .main.view-settings #map            { display: none; }
  .main.view-map      .sidebar        { display: none; }
  .panel-settings                     { display: none; margin-top: 0; padding-top: 0; border-top: none; }
  .main.view-settings .panel-search   { display: none; }
  .main.view-settings .panel-settings { display: block; }

  /* Keine Seitenleiste neben der Karte – die Legende rückt an den Rand und
     verschwindet, solange die Karte gar nicht zu sehen ist. */
  .poi-legend { left: 10px; max-width: 62vw; gap: 3px; padding: 6px 8px; font-size: 11px; }
  .poi-legend .row.muted { font-size: 10px; max-width: 100%; }
  .main.view-search   .poi-legend { display: none; }
  .main.view-settings .poi-legend { display: none; }

  /* Zoomtasten und Kompass raus – auf dem Handy wird mit zwei Fingern
     gezoomt, die Knöpfe kosten nur Platz. Ortung und 3D bleiben. */
  .maplibregl-ctrl-zoom-in,
  .maplibregl-ctrl-zoom-out,
  .maplibregl-ctrl-compass { display: none !important; }

  /* Ortung und 3D auf Fingergröße. MapLibres 29 px sind neben den großen
     Melde-Tasten unauffindbar und unterwegs nicht zu treffen. */
  .maplibregl-ctrl-group          { border-radius: 12px; }
  .maplibregl-ctrl-group button,
  .ctrl-3d,
  .ctrl-theme {
    width: 48px !important; height: 48px !important;
  }
  .maplibregl-ctrl-group button .maplibregl-ctrl-icon {
    background-size: 24px 24px;
  }
  .ctrl-3d { font-size: 15px; font-weight: 700; }
  .ctrl-theme { font-size: 22px; }

  /* Größerer Regler auf dem Handy – dicke Finger brauchen mehr Ziehweg als
     die Maus, sonst wird jeder Grad zum Balanceakt. */
  .ctrl-pitch { width: 48px !important; height: 132px !important; }
  .ctrl-pitch-thumb { width: 24px; height: 24px; }

  /* Melde-Tasten über die volle Höhe der rechten Seite.
     Unten bleiben 44 px für die Attribution frei – die ist Pflicht (ODbL). */
  /* HOCHKANT: Melde-Tasten als Fußleiste nebeneinander.
     Rechts oben in der Karte bleiben nur 3D und Ortung – so überlagert
     sich nichts mehr. */
  .qp-bar {
    top: auto; bottom: 46px;
    left: 10px; right: 10px;
    transform: none;
    /* Eine Zeile: Umschalter links, die vier Melde-Tasten rechts daneben.
       Vorher lag der Umschalter als eigene Zeile DARÜBER und aß zusammen mit
       den Tasten so viel Karte weg, dass der Standortpfeil kaum noch Platz
       hatte. */
    flex-direction: row;
    align-items: flex-end;
    gap: 8px;
  }
  /* Der Kopf bleibt hochkant sichtbar – aber nur wegen des Umschalters.
     Ortung und 3D stehen hochkant in der Karte (.qp-ctrl ist ohnehin aus). */
  .qp-head  { display: flex; flex-direction: row; flex: 0 0 auto; }
  /* Melden oben, Finden darunter – schmal, damit die Tasten Platz behalten. */
  .qp-mode  { flex-direction: column; flex: 0 0 auto; width: 58px; }
  .qp-mode-btn { flex-direction: column; gap: 1px; padding: 7px 2px; font-size: 10px; }
  .qp-mode-txt { display: inline; }
  .qp-mode-ico { font-size: 17px; }
  .qp-grid  { flex-direction: row; justify-content: flex-end; gap: 7px; flex: 1 1 auto; min-width: 0; }
  /* Rund zehn Prozent kleiner als vorher (84 px), damit Umschalter und vier
     Tasten zusammen in eine Zeile passen. */
  .qp-btn   { max-width: 76px; }
  .qp-title { display: none; }

  /* Während der Fahrt hat die Legende nichts im Bild zu suchen – sie lag
     hinter der Fahrtanzeige und störte nur. */
  .navi-an .poi-legend { display: none; }
  /* In Suchen/Einstellungen ist die Karte weg – die Leiste darf dann nicht
     über der Sidebar liegen. */
  .main.view-search   .qp-bar { display: none; }
  .main.view-settings .qp-bar { display: none; }
  /* QUADRATISCH halten – die Grafiken sind quadratisch, ein gestreckter Knopf
     schnitt ihnen die Ränder ab. Breite wächst mit dem Platz, aspect-ratio
     hält die Höhe nach. */
  .qp-btn {
    width: auto; height: auto;
    flex: 1 1 0; aspect-ratio: 1 / 1; max-width: 84px;
    border-radius: 16px;
  }
  .qp-ico { font-size: 32px; }
}

/* ===== Querformat am Telefon (Lenkerhalterung) =====
   Breit, aber niedrig – davon gehen Kopfzeile und Reiter noch ab.
   Deshalb: Chrome schrumpfen und die vier Tasten als 2x2-Block unten rechts
   statt als Stapel. Senkrecht untereinander blieben bei der geringen Höhe
   nur flache Streifen übrig. */
@media (orientation: landscape) and (max-height: 720px) and (max-width: 1180px) {
  .topbar     { padding: 4px 10px; }
  .topbar h1  { font-size: 15px; }
  .mtab       { padding: 6px 8px; font-size: 13px; }

  /* QUER ist die Seitenleiste ~800 px breit. `space-between` schob damit den
     Text an den linken und das Bedienelement an den rechten Displayrand –
     dazwischen eine halbe Handbreite Nichts. Zeilen auf Lesebreite begrenzen. */
  .opt-row, .chk, .address-input, .layers, .waypoints, .counter { max-width: 480px; }
  .opt-row select { min-width: 160px; }

  /* QUER: echte Seitenleiste RECHTS NEBEN der Karte – nicht darüber
     schwebend. Eine schmale schwebende Leiste quetschte die Tasten auf
     Briefmarkengröße an den Rand. Oben 3D + Ortung (per JS hierher verschoben),
     darunter die vier Melde-Tasten als 2x2. */
  .main.view-map { flex-direction: row; }

  .qp-bar {
    position: static;
    transform: none;
    flex: 0 0 200px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 10px;
    background: var(--surface);
    border-left: 1px solid var(--line);
    box-shadow: none;
  }
  /* display MUSS hier zurückgesetzt werden – der gemeinsame Mobilblock oben
     blendet den Kopf fürs Hochformat aus, sonst bliebe hier alles 0x0. */
  .qp-head {
    display: flex;
    flex-direction: row;
    justify-content: center;
    gap: 8px;
    flex: 0 0 auto;
  }
  .qp-title { display: none; }
  /* Hier die eigenen Knöpfe zeigen und MapLibres Originale in der Karte
     ausblenden – sonst hätte man beides doppelt. */
  .qp-ctrl {
    display: flex; align-items: center; justify-content: center;
    width: 52px; height: 52px;
    border: 1px solid var(--line); background: var(--surface);
    border-radius: 12px; cursor: pointer;
    font-size: 17px; font-weight: 700; color: var(--ink);
    box-shadow: var(--shadow);
  }
  .qp-ctrl:active   { transform: scale(.92); }
  .qp-ctrl.active   { background: var(--brand); color: #fff; border-color: var(--brand); }
  .qp-locate        { font-size: 24px; }
  .main.view-map .maplibregl-ctrl-top-right { display: none; }

  /* Zeilenhöhe NICHT strecken (kein 1fr) – sonst werden aus den quadratischen
     Grafiken hochkant gezogene Rechtecke. Die Höhe ergibt sich aus der Breite
     über aspect-ratio, der Block sitzt mittig in der Leiste. */
  .qp-grid {
    flex: 1;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    align-content: center;
  }
  .qp-btn {
    width: 100%; height: auto;
    aspect-ratio: 1 / 1;
    flex: none;
    max-width: none; max-height: none;
    border-radius: 16px;
  }
  .qp-ico { font-size: 30px; }

  .main.view-search .qp-bar { display: none; }
}

/* ===== User-Bereich (steht in der Seitenleiste, nicht mehr im Kopf) ===== */
.user-area {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
/* Leer, solange die Anmeldeprüfung läuft – dann auch keinen Abstand erzeugen. */
.user-area:empty { display: none; }
.sidebar .user-area {
  justify-content: flex-end;
  padding-bottom: 10px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

/* Fuß der Seitenleiste: Wechsel zum Autoplaner. */
.app-switch {
  display: block;
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 12.5px;
  color: var(--ink-soft);
  text-decoration: none;
}
.app-switch:hover { color: var(--brand); }
.user-area + .appnav { margin-left: 0; }

/* Früher standen diese Knöpfe auf der farbigen Kopfzeile und waren deshalb
   weiß auf durchsichtig. In der Seitenleiste sitzen sie auf hellem (bzw.
   nachts dunklem) Grund – die Farben kommen jetzt aus den Tokens. */
.btn-login {
  border: 1.5px solid var(--brand);
  background: transparent;
  color: var(--brand);
  border-radius: 7px;
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s;
  white-space: nowrap;
}
.btn-login:hover { background: var(--brand); color: #fff; }

.user-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.btn-logout {
  border: none;
  background: var(--sunken);
  color: var(--ink);
  border-radius: 7px;
  padding: 6px 12px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s;
  white-space: nowrap;
}
.btn-logout:hover { background: var(--line); }

/* ===== Auth-Modal ===== */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.48);
  z-index: 900;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.modal-overlay.hidden { display: none; }

.modal-box {
  background: var(--panel);
  border-radius: 14px;
  box-shadow: 0 8px 48px rgba(0,0,0,.24);
  padding: 28px 28px 24px;
  width: 100%;
  max-width: 390px;
  position: relative;
}
.modal-close {
  position: absolute;
  top: 12px; right: 14px;
  border: none;
  background: transparent;
  cursor: pointer;
  font-size: 18px;
  color: var(--ink-soft);
  padding: 4px 8px;
  border-radius: 6px;
  line-height: 1;
}
.modal-close:hover { background: var(--bg); }

.modal-tabs {
  display: flex;
  border-bottom: 2px solid var(--line);
  margin-bottom: 22px;
}
.modal-tab {
  flex: 1;
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 10px 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  transition: color .15s, border-color .15s;
}
.modal-tab.active { color: var(--brand); border-bottom-color: var(--brand); }

.modal-pane.hidden { display: none; }

.form-group { margin-bottom: 14px; }
.form-group label {
  display: block;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: .4px;
  margin-bottom: 5px;
}
.form-group input[type="email"],
.form-group input[type="password"],
.form-group input[type="text"] {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 14px;
  outline: none;
  color: var(--ink);
  background: var(--surface);
}
.form-group input:focus { border-color: var(--accent); }
.form-group small { font-size: 11.5px; font-weight: 400; text-transform: none; letter-spacing: 0; }
.form-hint { font-size: 13px; color: var(--ink-soft); margin: 0 0 16px; line-height: 1.5; }
.modal-box h2 { font-size: 17px; margin: 0 0 10px; color: var(--ink); }

.form-error {
  font-size: 12.5px;
  color: var(--danger);
  min-height: 16px;
  margin-bottom: 10px;
}

/* ===== Route speichern ===== */
.save-route-row { margin-bottom: 10px; }

.save-form {
  display: flex;
  gap: 8px;
}
.save-form input[type="text"] {
  flex: 1;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 13.5px;
  outline: none;
}
.save-form input:focus { border-color: var(--accent); }
.save-form .btn { padding: 9px 14px; font-size: 13.5px; }

.save-success {
  font-size: 13px;
  color: var(--brand);
  padding: 8px 10px;
  background: var(--hover);
  border-radius: 7px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.save-success a {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink-soft);
  cursor: pointer;
  text-decoration: underline;
}

/* ===== Meine Routen ===== */
.section-title.clickable {
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  user-select: none;
}
.section-title.clickable:hover { color: var(--ink); }

.chevron {
  font-size: 10px;
  color: var(--ink-soft);
  transition: transform .2s;
  display: inline-block;
}
.chevron.open { transform: rotate(90deg); }

.saved-routes-list {
  list-style: none;
  margin: 6px 0 16px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
.saved-routes-list .empty-msg {
  padding: 12px;
  font-size: 13px;
  color: var(--ink-soft);
  text-align: center;
}

.saved-route-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.saved-route-item:last-child { border-bottom: none; }

.sri-name {
  flex: 1;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sri-date {
  font-size: 11px;
  color: var(--ink-soft);
  white-space: nowrap;
  flex-shrink: 0;
}
.sri-actions { display: flex; gap: 4px; flex-shrink: 0; }

.sri-btn {
  border: none;
  background: var(--sunken);
  border-radius: 6px;
  padding: 4px 9px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  color: var(--ink);
  white-space: nowrap;
}
.sri-btn:hover { background: var(--line); }
.sri-btn.danger { background: #fce8e8; color: var(--danger); }
.sri-btn.danger:hover { background: #f5cfcf; }

/* ===== Betriebsprofile: Karten-Popup ===== */
.biz-popup {
  min-width: 220px;
  max-width: 280px;
  font-size: 13px;
  line-height: 1.45;
}
.biz-popup-cover {
  width: 100%;
  height: 140px;
  object-fit: cover;
  border-radius: 6px;
  margin-bottom: 8px;
  display: block;
}
.biz-popup-name {
  font-weight: 700;
  font-size: 15px;
  margin: 0 0 2px;
  color: var(--ink);
}
.biz-popup-cat {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: .4px;
  margin-bottom: 6px;
}
.biz-popup-row {
  display: flex;
  align-items: flex-start;
  gap: 5px;
  margin-bottom: 3px;
  font-size: 12.5px;
  color: var(--ink);
}
.biz-popup-row a { color: var(--accent); text-decoration: none; word-break: break-all; }
.biz-popup-row a:hover { text-decoration: underline; }
.biz-popup-hours {
  background: var(--bg);
  border-radius: 6px;
  padding: 5px 8px;
  margin: 6px 0;
  font-size: 12px;
}
.biz-popup-hour-row { display: flex; gap: 8px; }
.biz-popup-hour-row span:first-child { font-weight: 600; min-width: 56px; }
.biz-popup-verified {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  color: var(--brand);
  font-weight: 700;
  margin-top: 2px;
}

/* Betriebsmarker auf der Karte.
   MapLibre setzt auf DIESES Element (das an new maplibregl.Marker({element})
   übergebene) selbst ein Inline-transform zur Positionierung - eine eigene
   CSS-transform: rotate(...) hier würde MapLibre einfach überschreiben, die
   Tropfenform kam dadurch nie zustande (nur ein Quadrat mit einer eckigen
   statt spitzen Ecke). Deshalb Rotation + Optik auf .biz-marker-shape
   ausgelagert, .biz-marker bleibt reine Positionierungshülle. */
.biz-marker {
  width: 32px;
  height: 32px;
  cursor: pointer;
}
.biz-marker-shape {
  width: 100%;
  height: 100%;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: #7c3aed;
  border: 2.5px solid #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,.45);
  display: flex;
  align-items: center;
  justify-content: center;
}
.biz-marker-inner {
  transform: rotate(45deg);
  font-size: 14px;
  line-height: 1;
  display: flex;
}
.biz-marker-inner svg {
  width: 16px;
  height: 16px;
  fill: #fff;
}
/* Importierte, vom Betrieb noch nicht beanspruchte Einträge - gedeckter
   und gestrichelt, damit klar ist: ungeprüfte Fremddaten. */
.biz-marker.unclaimed .biz-marker-shape {
  background: #a78bfa;
  border-style: dashed;
  opacity: .85;
}
.biz-popup-unclaimed {
  font-size: 11px;
  color: #92610b;
  background: #fef9ec;
  border: 1px solid #f5dfa0;
  border-radius: 6px;
  padding: 4px 7px;
  margin-top: 4px;
}
.biz-popup-amenities {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: 4px 0;
}
.biz-popup-amenities span {
  font-size: 10.5px;
  font-weight: 600;
  background: #eef6f0;
  color: var(--brand-dk, #166138);
  border-radius: 20px;
  padding: 3px 8px;
}
.biz-popup-more {
  display: block;
  margin-top: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
}
.biz-popup-more:hover { text-decoration: underline; }
.biz-popup-route-btn {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 7px 10px;
  border: none;
  border-radius: 8px;
  background: var(--brand);
  color: #fff;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
}
.biz-popup-route-btn:active { transform: scale(.98); }

/* ===== Betrieb-Editor-Seite (/betrieb/) ===== */
.biz-editor-wrap {
  max-width: 640px;
  margin: 0 auto;
  padding: 24px 16px 60px;
}
.biz-section {
  background: var(--panel);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  margin-bottom: 18px;
}
.biz-section-title {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--ink-soft);
  margin: 0 0 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}
.biz-field { margin-bottom: 14px; }
.biz-field label {
  display: block;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: .4px;
  margin-bottom: 5px;
}
.biz-field input[type="text"],
.biz-field input[type="email"],
.biz-field input[type="tel"],
.biz-field input[type="url"],
.biz-field select,
.biz-field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 14px;
  font-family: inherit;
  color: var(--ink);
  background: var(--surface);
  outline: none;
  resize: vertical;
}
.biz-field input:focus,
.biz-field select:focus,
.biz-field textarea:focus { border-color: var(--accent); }
.biz-field .hint {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 4px;
}

/* Öffnungszeiten */
.hours-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.hour-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.hour-row input { flex: 1; min-width: 0; }
.hour-row button {
  border: none;
  background: #fce8e8;
  color: var(--danger);
  border-radius: 6px;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 14px;
  flex-shrink: 0;
}
.hour-row button:hover { background: #f5cfcf; }
.btn-add-hour {
  border: 1.5px dashed var(--line);
  background: transparent;
  color: var(--ink-soft);
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 13px;
  cursor: pointer;
  width: 100%;
  transition: border-color .15s;
}
.btn-add-hour:hover { border-color: var(--accent); color: var(--accent); }

/* Foto-Upload */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}
.photo-thumb {
  position: relative;
  aspect-ratio: 4/3;
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg);
}
.photo-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.photo-del {
  position: absolute;
  top: 4px; right: 4px;
  width: 22px; height: 22px;
  border: none;
  background: rgba(0,0,0,.55);
  color: #fff;
  border-radius: 50%;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.photo-del:hover { background: rgba(220,38,38,.8); }
.btn-upload-photo {
  border: 2px dashed var(--line);
  background: var(--bg);
  color: var(--ink-soft);
  border-radius: 8px;
  padding: 18px 12px;
  font-size: 13px;
  cursor: pointer;
  width: 100%;
  text-align: center;
  transition: border-color .15s;
}
.btn-upload-photo:hover { border-color: var(--accent); color: var(--accent); }
.photo-uploading { opacity: .5; pointer-events: none; }

/* Geocode-Zeile */
.geocode-row {
  display: flex;
  gap: 8px;
}
.geocode-row input { flex: 1; }
.btn-geo {
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
}
.btn-geo:hover { border-color: var(--accent); color: var(--accent); }
.geocode-suggestions {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: var(--surface);
}
.geocode-suggestions li {
  padding: 9px 12px;
  font-size: 13px;
  cursor: pointer;
  border-bottom: 1px solid var(--line);
}
.geocode-suggestions li:last-child { border-bottom: none; }
.geocode-suggestions li:hover { background: var(--bg); }
.geocode-suggestions.hidden { display: none; }
.coords-display {
  font-size: 11.5px;
  color: var(--brand);
  margin-top: 4px;
}

/* Statuszeile Betrieb */
.biz-status-bar {
  background: var(--hover);
  border: 1px solid #c6e6d3;
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  color: var(--brand);
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.biz-inactive-notice {
  background: #fef9ec;
  border: 1px solid #f5dfa0;
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  color: #92610b;
  margin-bottom: 18px;
}
.biz-auth-prompt {
  text-align: center;
  padding: 40px 20px;
}
.biz-auth-prompt h2 { font-size: 20px; margin: 0 0 8px; }
.biz-auth-prompt p { color: var(--ink-soft); margin-bottom: 20px; }
.biz-loader { text-align: center; padding: 40px; color: var(--ink-soft); font-size: 14px; }
.biz-save-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}
.biz-save-msg { font-size: 13px; color: var(--brand); }

/* Öffentliche Kunden-Tracking-Seite (Schritt 3, verfolgen/) */
.track-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: var(--bg);
}
.track-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  background: var(--accent);
  color: #fff;
  flex: none;
}
.track-head h1 { font-size: 17px; margin: 0; font-weight: 600; }
.track-logo { font-size: 22px; }
.track-map { flex: 1; min-height: 0; }
.track-card {
  flex: none;
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding: 18px 20px calc(18px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -4px 16px rgba(0,0,0,.06);
}
.track-loading { text-align: center; color: var(--ink-soft); font-size: 14px; padding: 10px 0; }
.track-icon { font-size: 32px; text-align: center; margin-bottom: 8px; }
#trackError p { text-align: center; color: var(--ink-soft); margin: 0; }
.track-status { font-size: 17px; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
.track-eta { font-size: 14px; color: var(--brand); margin-bottom: 6px; }
.track-addr { font-size: 13px; color: var(--ink-soft); }
.track-updated { font-size: 11px; color: var(--ink-soft); margin-top: 8px; opacity: .8; }

.track-pin {
  font-size: 26px;
  line-height: 1;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,.35));
}
.track-pin-fahrer { font-size: 24px; }

/* Tracking-Link-Liste unter "Als Tour mit Tracking anlegen" */
.save-success:has(.tour-link-list) {
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
}
.tour-link-list { display: flex; flex-direction: column; gap: 6px; }
.tour-link-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--surface);
  border-radius: 6px;
  padding: 6px 8px;
}
.tour-link-label { font-size: 12.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.btn.small { padding: 5px 10px; font-size: 12px; flex: none; }

/* ===== Premium-Sperre im Betrieb-Editor ===== */
.biz-premium-lock {
  position: relative;
  border-radius: 8px;
  overflow: hidden;
}
.biz-premium-lock::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--sunken);
  opacity: .6;
  z-index: 1;
  pointer-events: none;
}
.biz-premium-lock textarea,
.biz-premium-lock input { pointer-events: none; }
.biz-premium-badge {
  position: absolute;
  top: 8px; right: 8px;
  z-index: 2;
  background: #7c3aed;
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .3px;
  padding: 3px 8px;
  border-radius: 20px;
  pointer-events: none;
}
.biz-upsell-banner {
  background: linear-gradient(135deg, #7c3aed, #a855f7);
  color: #fff;
  border-radius: var(--radius);
  padding: 16px 18px;
  margin-bottom: 18px;
  box-shadow: var(--shadow);
}
.biz-upsell-banner h3 { margin: 0 0 6px; font-size: 15px; }
.biz-upsell-banner p { margin: 0 0 12px; font-size: 13px; opacity: .92; line-height: 1.5; }
.biz-upsell-banner ul { margin: 0 0 12px; padding-left: 20px; font-size: 13px; opacity: .95; }
.biz-upsell-banner a.btn-upsell {
  display: inline-block;
  background: #fff;
  color: #7c3aed;
  font-weight: 700;
  font-size: 13px;
  padding: 8px 16px;
  border-radius: 8px;
  text-decoration: none;
}
.biz-upsell-banner a.btn-upsell:hover { background: #f3ecfe; }
.biz-claimed-banner {
  background: var(--hover);
  border: 1px solid #c6e6d3;
  border-radius: var(--radius);
  padding: 14px 18px;
  margin-bottom: 18px;
  color: var(--brand-dk);
  font-size: 14px;
}
.biz-claimed-banner strong { display: block; margin-bottom: 4px; font-size: 15px; }

/* ===== Öffentliche Betriebsseite (/betrieb/profil.php) ===== */
.bizpage-wrap { max-width: 640px; margin: 0 auto; padding: 24px 16px 60px; }
.bizpage-cover {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
  border-radius: var(--radius);
  margin-bottom: 18px;
  background: var(--sunken);
  display: block;
}
.bizpage-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 8px;
  margin-bottom: 18px;
}
.bizpage-gallery img { width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 8px; }
.bizpage-head { margin-bottom: 18px; }
.bizpage-cat {
  font-size: 12px; font-weight: 700; color: var(--accent);
  text-transform: uppercase; letter-spacing: .4px; margin-bottom: 4px;
}
.bizpage-name { font-size: 24px; font-weight: 800; margin: 0 0 8px; color: var(--ink); }
.bizpage-verified { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; color: var(--brand); font-weight: 700; }
.bizpage-section {
  background: var(--panel);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px;
  margin-bottom: 16px;
}
.bizpage-section h2 {
  font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  color: var(--ink-soft); margin: 0 0 12px; padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
.bizpage-section p { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ink); white-space: pre-line; }
.bizpage-hours-row { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; font-size: 14px; }
.bizpage-hours-row span:first-child { font-weight: 600; color: var(--ink); }
.bizpage-hours-row span:last-child { color: var(--ink-soft); }
.bizpage-contact-row { display: flex; align-items: center; gap: 8px; font-size: 14px; margin-bottom: 8px; color: var(--ink); }
.bizpage-contact-row a { color: var(--accent); text-decoration: none; word-break: break-word; }
.bizpage-contact-row a:hover { text-decoration: underline; }
.bizpage-unclaimed {
  background: #fef9ec;
  border: 1px solid #f5dfa0;
  border-radius: var(--radius);
  padding: 14px 18px;
  margin-bottom: 18px;
  font-size: 13.5px;
  color: #92610b;
}
.bizpage-unclaimed a { color: #92610b; font-weight: 700; }
.bizpage-atm-hint { font-size: 13px; color: var(--ink-soft); margin-top: 8px; }
.bizpage-atm-hint a { color: var(--accent); font-weight: 600; text-decoration: none; }
.bizpage-atm-hint a:hover { text-decoration: underline; }
.biz-popup-atm-hint a { color: var(--accent); font-weight: 600; }
.bizpage-back { display: inline-block; margin-bottom: 16px; font-size: 13px; color: var(--ink-soft); text-decoration: none; }
.bizpage-back:hover { color: var(--accent); }
.bizpage-notfound { text-align: center; padding: 60px 20px; color: var(--ink-soft); }

/* ===== Rechtstexte (/agb/, /widerruf/, /impressum/, /betrieb/kuendigen/) ===== */
.legal-wrap { max-width: 760px; margin: 0 auto; padding: 32px 20px 80px; line-height: 1.65; }
.legal-wrap h1 { font-size: 26px; margin: 0 0 6px; color: var(--ink); }
.legal-lead { color: var(--ink-soft); font-size: 14px; margin: 0 0 32px; }
.legal-wrap h2 { font-size: 17px; margin: 32px 0 10px; color: var(--ink); }
.legal-wrap p, .legal-wrap ul { font-size: 14.5px; color: var(--ink); margin: 0 0 14px; }
.legal-wrap ul { padding-left: 22px; }
.legal-wrap a { color: var(--accent); }
.legal-tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; margin: 0 0 14px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.legal-tbl th { text-align: left; padding: 9px 12px; background: var(--sunken); font-weight: 600; border-bottom: 1px solid var(--line); color: var(--ink); }
.legal-tbl td { padding: 9px 12px; border-bottom: 1px solid var(--line); vertical-align: top; color: var(--ink); }
.legal-tbl tr:last-child td { border-bottom: none; }

/* ===== Claim-Seite (/betrieb/claim.php) ===== */
.claim-wrap { max-width: 460px; margin: 0 auto; padding: 24px 16px 60px; }
.claim-intro {
  text-align: center;
  padding: 24px 16px 8px;
}
.claim-intro .icon { font-size: 42px; margin-bottom: 10px; }
.claim-intro h2 { font-size: 20px; margin: 0 0 6px; }
.claim-intro p { color: var(--ink-soft); font-size: 14px; margin: 0; }
.claim-biz-card {
  background: var(--panel);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 18px;
  margin: 18px 0;
  display: flex;
  align-items: center;
  gap: 12px;
}
.claim-biz-card .icon { font-size: 30px; flex: none; }
.claim-biz-card .name { font-weight: 700; font-size: 15px; color: var(--ink); }
.claim-biz-card .addr { font-size: 12.5px; color: var(--ink-soft); }
.claim-tabs { display: flex; gap: 4px; background: var(--bg); padding: 3px; border-radius: 9px; margin-bottom: 16px; }
.claim-tab {
  flex: 1; text-align: center; padding: 8px 10px; border-radius: 6px;
  font-size: 13px; font-weight: 600; color: var(--ink-soft); cursor: pointer; border: none; background: none;
}
.claim-tab.active { background: var(--brand); color: #fff; }
.claim-error {
  text-align: center; padding: 50px 16px; color: var(--ink-soft);
}
.claim-error .icon { font-size: 40px; margin-bottom: 12px; }
.claim-map {
  width: 100%;
  height: 320px;
  border-radius: var(--radius);
  overflow: hidden;
  margin: 4px 0 18px;
  box-shadow: var(--shadow);
}
