/* ==========================================================================
   geocoder.css -- Suchfeld neben #search-location-btn.
   Gehört zu: frontend/js/geocoder.js

   Layout-Konzept:
   .geocoder-wrap hat Größe 0×0 und nimmt KEINEN Platz in der Flex-Spalte
   von #right-controls ein. Input und Dropdown sind position:absolute relativ
   zum Wrap selbst (der wiederum absolut in #right-controls sitzt).

   --geocoder-top wird per JS (_buildUI) auf den vertikalen Offset des
   #search-location-btn gesetzt und bei window:resize aktualisiert.

   Breiten-Strategie:
   .geocoder-wrap--open trägt die clamp()-Breite. Input und Dropdown
   erben via width:100% -- so sind beide immer pixelgenau gleich breit.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Wrapper
   position:absolute → komplett raus aus dem Flex-Flow von #right-controls,
   kein Verschieben der anderen Buttons beim Aufklappen.
   Containing Block: #right-controls (position:absolute).
   right: 52px = Button-Breite (44px) + Gap (8px) → links der Lupe.
   top via --geocoder-top, per JS auf #right-controls gesetzt.
   overflow:visible damit Input und Dropdown herausragen dürfen.
   pointer-events nur wenn offen.
   -------------------------------------------------------------------------- */
.geocoder-wrap {
  position: absolute;
  top: var(--geocoder-top, 0px);
  right: 52px;
  width: 0;
  height: 0;
  overflow: visible;
  pointer-events: none;
  z-index: 1;
}

/* Im offenen Zustand trägt der Wrapper die Zielbreite --
   Input und Dropdown erben via width:100% exakt dieselbe Breite.
   clamp(280px, calc(100vw - 84px), 720px):
     - 280px            = untere Grenze (sicher auf 375px+ Geräten)
     - 100vw - 84px     = Viewport minus right:16 minus Button+Gap (52px) minus 16px Puffer
     - 720px            = obere Grenze auf Desktop */
.geocoder-wrap--open {
  pointer-events: auto;
  width: clamp(280px, calc(100vw - 84px), 720px);
}

/* --------------------------------------------------------------------------
   Input-Feld
   Absolut relativ zum Wrap.
   right:0 / top:0 -- Wrap sitzt bereits an der richtigen Position.
   Breite animiert von 0 → 100% (= Wrapper-Breite) beim Aufklappen.
   text-overflow:ellipsis für lange gewählte Labels (z.B.
   "Niederdornberg-Deppendorf, Bielefeld, ...").
   -------------------------------------------------------------------------- */
.geocoder-input {
  position: absolute;
  right: 0;
  top: 0;
  z-index: 1;
  width: 0;
  height: 40px;

  padding: 0;
  border-radius: var(--radius-xl);
  border: 1px solid transparent;

  background: var(--glass-bg);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);

  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;

  opacity: 0;
  pointer-events: none;

  transition:
    width        200ms ease,
    opacity      200ms ease,
    padding      200ms ease,
    border-color 150ms ease,
    box-shadow   150ms ease;
}

.geocoder-wrap--open .geocoder-input {
  /* 100% = Wrapper-Breite (clamp(280px, calc(100vw - 84px), 720px)) */
  width: 100%;
  padding: 0 var(--space-3);
  opacity: 1;
  pointer-events: auto;
  border-color: var(--color-border);
  box-shadow: var(--shadow-md);
}

.geocoder-input::placeholder {
  color: var(--color-text-faint);
}

.geocoder-input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--color-accent) 55%, transparent);
  box-shadow:
    var(--shadow-md),
    0 0 0 3px color-mix(in srgb, var(--color-accent) 12%, transparent);
}

/* --------------------------------------------------------------------------
   Höhe der gewählten Stelle, z.B. "(412 m)"
   Liegt rechts ÜBER dem Feld und ist kein Teil seines Texts: sie lässt sich
   weder markieren noch editieren, und Klicks gehen durch sie hindurch ins
   Feld. Sichtbar nur im offenen Zustand und solange das Element nicht
   `hidden` ist. Das Feld bekommt dann rechts so viel Innenabstand, dass ein
   langer Text vor der Höhe endet statt unter ihr durchzulaufen; die Regel
   greift über den Nachbar-Selektor, das Element steht deshalb VOR dem Feld
   im Baum (geocoder.js, _buildUI).
   -------------------------------------------------------------------------- */
.geocoder-elev {
  position: absolute;
  right: var(--space-3);
  top: 0;
  z-index: 2;
  height: 40px;
  line-height: 40px;

  display: none;
  color: var(--color-text-muted);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-style: italic;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.geocoder-wrap--open .geocoder-elev:not([hidden]) {
  display: block;
}

/* Der Innenabstand rechts ist der Abstand der Höhe zum Rand (`right` oben) plus
   ihre Breite samt einer Lücke zum Feldtext, gerechnet an der breitesten
   vierstelligen Höhe. Feld und Höhe tragen dieselbe Schriftgröße, `em` meint
   deshalb in beiden dasselbe.
   ⚠️ Mehr als vier Stellen liefern die Datensätze der Vorgabe nicht
   (elevation.js, DEFAULT_DATASETS). Ein längerer Wert kann breiter sein als
   dieser Platz; die Höhe ragt dann in den Feldtext. */
.geocoder-wrap--open .geocoder-elev:not([hidden]) + .geocoder-input {
  padding-right: calc(var(--space-3) + 5em);
}

/* --------------------------------------------------------------------------
   Dropdown-Liste
   Absolut relativ zum Wrap.
   right:0 -- bündig mit der linken Input-Kante.
   top:48px -- direkt unterhalb des Inputs (40px Höhe + 8px Gap).
   width:100% = exakt so breit wie der Wrapper (= Input-Breite).
   Vollständig opaker Hintergrund -- kein Karten-Durchscheinen.

   overflow-y:hidden als Vorgabe: passen alle Zeilen sichtbar hinein, gibt es
   keine Scrollbar. Den Scroll-Modus setzt JS am Element (data-scrollable="true",
   s.u.), und zwar bei jedem Zeichnen neu -- entschieden wird an der Zahl der
   Zeilen, die WIRKLICH in der Liste stehen, lokale Vorschläge eingerechnet.
   -------------------------------------------------------------------------- */
.geocoder-dropdown {
  position: absolute;
  right: 0;
  top: 48px;
  z-index: 1;
  width: 100%;

  list-style: none;
  margin: 0;
  /* ⚠️ In em, nicht in rem: die Deckelung unten rechnet in Zeilen, und die
     Polsterung zählt wegen `box-sizing: border-box` (globaler Reset in
     style.css) in sie hinein. Gemischt gerechnet passte die letzte Zeile je
     nach Viewport-Breite hinein oder nicht. */
  padding: 0.25em 0;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  background: var(--color-surface-2);
  box-shadow: var(--shadow-lg);

  /* Kein Scroll per Default -- verhindert Scrollbar auch bei Zoom oder
     Sub-Pixel-Rendering-Abweichungen wenn alle Treffer sichtbar passen. */
  overflow-y: hidden;
}

/* Scroll-Modus: aktiv, sobald mehr Zeilen in der Liste stehen, als ohne Scroll
   sichtbar sind. JS entscheidet das in _paintDropdown(), bei jedem Zeichnen.

   max-height dynamisch: so viele Zeilen zu je 2.5em, wie --geocoder-rows sagt,
   dazu die eigene Polsterung (2 × 0.25em) und die beiden 1px-Kanten --
   `box-sizing: border-box` (globaler Reset) rechnet Polsterung und Kanten in die
   Deckelung mit hinein.
   ⚠️ Die Zahl der Zeilen steht NICHT hier: _buildUI() setzt --geocoder-rows aus
   `dropdown_limit` am Element, und zwar unbedingt. Der Wert in dieser Regel ist
   allein der Rückfall für eine fehlende Eigenschaft -- er greift nur, wenn das
   Element gar nicht durch _buildUI() gegangen ist, und beschreibt deshalb keine
   Konfiguration.
   Die Höhe einer Zeile steht als Regel an `.geocoder-item`; wer beide Regeln
   liest, kommt auf dieselbe Zahl sichtbarer Zeilen wie der Browser.
   em bezieht sich auf font-size dieses Elements (= var(--text-sm)) --
   skaliert automatisch mit der fluiden Schriftgröße, kein fixer px-Wert. Alles,
   was in die Höhe eingeht, steht in DIESER Einheit: eine Länge in rem wäre je
   nach Viewport-Breite ein anderer Bruchteil einer Zeile.

   scrollbar-color / scrollbar-width: W3C-Standard (Scrollbars Styling L1),
   unterstützt in Firefox 64+, Chrome 121+, Edge 121+ -- kein Vendor-Prefix.
   Thumb-Farbe via --color-border: passt zu den Item-Trennlinien und
   wechselt automatisch mit dem Theme (Light/Dark).
   Track transparent: Dropdown-Hintergrund bleibt sichtbar. */
.geocoder-dropdown[data-scrollable="true"] {
  max-height: calc(var(--geocoder-rows, 6) * 2.5em + 2 * 0.25em + 2px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--color-border) transparent;
}

/* --------------------------------------------------------------------------
   Dropdown-Einträge
   -------------------------------------------------------------------------- */
.geocoder-item {
  /* ⚠️ Die Höhe der Zeile ist eine ZUSAGE, keine Folge der Schrift: das
     Dropdown zeigt genau `dropdown_limit` Zeilen ohne Scroll (s. max-height
     unten), und diese Rechnung braucht eine Zeilenhöhe, die in einer Regel
     steht. Ohne sie gälte die Vorgabe der Schrift, und jede Schriftart
     verschöbe die Zahl der sichtbaren Zeilen.
     2.5em = Zeilenbox 1.5em + 2 × 0.5em Polsterung. `box-sizing: border-box`
     nimmt die Trennlinie mit hinein -- sonst käme je Zeile ein Pixel dazu, und
     die letzte wäre angeschnitten. Polsterung in em und nicht in rem, damit die
     Summe aufgeht: --space-2 wäre 0.5rem und damit je nach Viewport ein anderer
     Bruchteil der Zeile. */
  height: 2.5em;
  box-sizing: border-box;
  line-height: 1.5;
  padding: 0.5em var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition:
    background 120ms ease,
    color      120ms ease;
}

/* Hover und Tastatur-Fokus: dezentes Akzent-Highlight. */
.geocoder-item--active,
.geocoder-item:hover {
  background: var(--color-accent-dim);
  color: var(--color-accent);
}

/* Trennlinie zwischen Einträgen. */
.geocoder-item:not(:last-child) {
  border-bottom: 1px solid var(--color-border);
}

/* "Keine Treffer"-Zeile. */
.geocoder-item--empty {
  color: var(--color-text-faint);
  cursor: default;
  font-style: italic;
}

/* --------------------------------------------------------------------------
   Lokale Vorschläge (Standorte, eigene Pins, GPS-Punkt)

   Die Zeile trägt ihr Zeichen vor dem Namen. Das Zeichen ist Markup und kommt
   aus derselben Kette wie im Standort-Menü (poi_entries.js: Emoji,
   SVG-Vorlage, Flagge, oder ein Wappen aus Bild und Flagge); die Regeln dafür stehen dort unter
   `#hover-select` und greifen hier nicht, deshalb stehen sie hier noch einmal --
   auf das Dropdown gescoped.

   ⚠️ Die Höhe ist die ganze Frage. Das Dropdown zeigt ohne Scroll so viele
   Zeilen, wie `dropdown_limit` sagt (Deckelung oben), und wie viele davon die
   lokalen Quellen belegen, sagt `max_extra_suggestions` -- mit einem `null` an
   einer Quelle ist es unbegrenzt. Ein Zeichen, das höher baut als die Textzeile,
   schöbe den ersten Nominatim-Treffer hinaus. Deshalb ist der Kasten des
   Zeichens genau so hoch wie die Zeile (1.5em), und alles darin wird auf diese
   Höhe gerechnet -- im Menü steht dafür ein Ring von 40px zur Verfügung, hier
   eine Textzeile.
   -------------------------------------------------------------------------- */
.geocoder-item--local {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Der Name bekommt den Platz, der neben dem Zeichen bleibt -- und kürzt selbst.
   Ohne min-width:0 wächst ein Flex-Kind über seinen Inhalt hinaus, und die
   Ellipse käme nie zum Zug. */
.geocoder-item__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Eine Trefferzeile mit Höhe: das Label kürzt, die Höhe bleibt ganz und steht
   am rechten Rand der Zeile, in Farbe und Schrift wie die Höhe im Suchfeld
   (.geocoder-elev). Der Innenabstand rechts ist deren Abstand zum Rand, um den
   Rahmen der Liste gekürzt: so stehen beide untereinander an derselben Kante,
   solange die Liste keine Bildlaufleiste trägt. */
.geocoder-item--elev {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-right: calc(var(--space-3) - 1px);
}

.geocoder-item__elev {
  flex: none;
  margin-left: auto;
  color: var(--color-text-muted);
  font-style: italic;
}

/* Der Kasten des Zeichens: feste Breite, damit die Namen untereinander an
   derselben Kante beginnen, und genau die Höhe der Zeilenbox (1.5em, s.
   `.geocoder-item` oben). Höher gesetzt zöge er die Zeile auf, und die letzte
   noch sichtbare wäre angeschnitten. */
.geocoder-item__icon {
  /* ⚠️ Die Höhe eines Bildes steht EINMAL, weil zwei Konfigurationswege dasselbe
     zeigen: `country` wird ein flag-icons-Span (Breite 1.333 em, Höhe eine
     Zeile), `icon_path` und `icon_template` werden eine SVG-Vorlage. Zwei
     getrennte Zahlen liefen auseinander, und dieselbe Flagge hätte je nach
     Konfigurationsweg eine andere Größe.
     Der Aufschlag gilt nur dem Bildkasten: ein Emoji wirkt bei gleicher Höhe
     kleiner als eine Fläche. Die SVG-Vorlage sitzt IN diesem Kasten, ihr `em`
     ist also schon aufgeschlagen -- deshalb teilt ihre Größe durch denselben
     Faktor, mit dem der Kasten multipliziert. */
  --geocoder-icon-height: 1.2em;
  --geocoder-icon-scale: 1.15;

  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Breite: das breiteste Bild ist 4:3, also Höhe × 4 / 3, plus etwas Luft,
     damit die Namen an derselben Kante beginnen. */
  width: calc(var(--geocoder-icon-height) * 4 / 3 + 0.15em);
  height: 1.5em;
  line-height: 1;
}

/* Die Kette aus poi_entries.js, hier gescoped. Im Menü steht dafür ein Ring von
   40 px zur Verfügung, hier eine Textzeile -- die Größen sind deshalb an die
   Zeile gerechnet und nicht an den Ring. */
.geocoder-item__icon .hs-poi {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
}
.geocoder-item__icon .hs-poi__icon { font-size: calc(var(--geocoder-icon-scale) * 1em); }
.geocoder-item__icon .hs-poi .fi   { font-size: var(--geocoder-icon-height); }
.geocoder-item__icon .hs-poi svg   {
  display: block;
  width: calc(var(--geocoder-icon-height) * 4 / 3 / var(--geocoder-icon-scale));
  height: calc(var(--geocoder-icon-height) / var(--geocoder-icon-scale));
}
/* Wappen: die Flagge in voller Zeilengröße gibt dem Kasten Maß und Lage, das Bild
   liegt zentriert davor, 0.72 der Flaggenhöhe wie im Menü (hover_select.css).
   Anders als im Menü steht `.hs-poi` hier im Fluss und braucht deshalb selbst
   `position: relative` als Bezugskasten. Der Aufschlag für Emoji entfällt: das
   Bild soll kleiner sein als die Flagge, nicht so groß wie sie wirken.
   ⚠️ Die Vorlage sitzt IN diesem Bildkasten, ihr `em` ist also schon dessen
   Schriftgröße, 0.72 der Flaggenhöhe. Deshalb misst sie 1em: noch einmal
   `var(--geocoder-icon-height) * 0.72` verkleinerte sie ein zweites Mal. */
.geocoder-item__icon .hs-poi--crest { position: relative; }
.geocoder-item__icon .hs-poi--crest .hs-poi__icon {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  font-size: calc(var(--geocoder-icon-height) * 0.72);
  line-height: 1;
}
.geocoder-item__icon .hs-poi--crest svg {
  width: 1em;
  height: 1em;
}

