/* Kartenmarker — von der Besucher-App UND vom Admin-Portal benutzt.
 *
 * Eigene Datei, weil beide Oberflächen sie brauchen und keine die andere lädt:
 * css/app.css gehört der Besucher-App, css/admin.css dem Portal. Bis zur
 * Kartenverwaltung stand alles hier in app.css — im Portal waren die Marker
 * deshalb nackte Glyphen ohne die farbige Scheibe, und die Kategoriefarbe fehlte
 * genau dort, wo man Stände auseinanderhalten muss.
 *
 * Doppeln wäre die Alternative gewesen. Eine geteilte Datei ist es nicht, weil
 * es kürzer ist, sondern weil ein Marker in beiden Oberflächen gleich aussehen
 * MUSS: es ist dieselbe Karte und dasselbe Markup aus js/map.js.
 *
 * Zwei Pseudoelemente sind hier belegt: ::before ist die Scheibe, ::after der
 * pulsierende Ring des ausgewählten Markers. Wer etwas hinzufügen will, braucht
 * ein eigenes Element — siehe .marker__tip in css/admin.css.
 */

/* Der Knopf ist die Trefferfläche (48 px, Abschnitt 03), die farbige Scheibe
   darin ist die Grafik (38 px). Beides zu trennen ist nötig, weil ein größerer
   Marker den Plan zudecken würde — und ein 38-px-Marker mit der Fingerspitze
   nicht zuverlässig zu treffen ist. */
/* Position und Verschiebung kommen von MapLibre: es setzt transform auf genau
   diesem Knoten. Eigene Werte hier würden überschrieben und wären toter Code. */
.marker {
  width: 48px;
  height: 48px;
  background: transparent;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.marker::before {
  content: '';
  position: absolute;
  inset: 5px;
  border-radius: var(--lf-r-full);
  background: var(--lf-marker, #888);
  border: 3px solid var(--lf-beton);
  box-shadow: 0 3px 8px rgba(0, 0, 0, .3);
  transition: transform .12s;
}
/* Der Inhalt der Scheibe — Symbol oder Kennung (setMarkerFace in js/map.js).
   position: relative, damit er über ::before liegt: das Pseudoelement ist
   absolut positioniert und läge sonst über dem Inhalt im Textfluss. */
.marker__face {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.marker .ic { position: relative; width: 20px; height: 20px; }
.marker:hover::before { transform: scale(1.1); }

/* Kennung statt Symbol. Nur das Admin-Portal schaltet das ein.
   Oswald ist schmal — drei Zeichen (s49) passen damit in die 38-px-Scheibe,
   ohne den Rand zu berühren. Weiß auf der Kategoriefarbe wie das Symbol, die
   Scheibe bleibt also unverändert lesbar als Kategoriefarbe. */
.marker--code .marker__face {
  font-family: var(--lf-font-display);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: .01em;
}

/* --- Maßstabsgetreues Rechteck (Ansicht „Standgröße" im Portal) ----------

   Statt der runden Scheibe die echte Grundfläche des Standes. Die Pixelmaße setzt
   js/map.js bei jeder Kamerabewegung (setRectSize), der Winkel steht als
   --lf-rect-rot am Knopf.

   Die Scheibe ::before wird abgeschaltet und nicht umgeformt: sie ist auf 48 px
   festgelegt (inset: 5px), und ein Rechteck von 3 × 12 m hat mit diesen Maßen
   nichts zu tun. Der Knopf behält seine 48 px als TREFFERFLÄCHE — auch wenn das
   Rechteck kleiner ist, bleibt er anklickbar und mit der Tastatur erreichbar. Genau
   deshalb ist diese Ansicht ein Marker und kein GeoJSON-Polygon.

   `overflow: visible` am Knopf ist nötig, weil ein großer Stand (12 m Front bei
   Zoom 21 sind 250 px) über die 48 px hinausragt. */
.marker--rect { overflow: visible; }
.marker--rect::before { display: none; }

.marker--rect .marker__face {
  /* ABSOLUT positioniert und nicht als Flex-Element. Der Knopf ist ein
     `display: flex` mit festen 48 px; ein Flex-Element darin wird auf diese Breite
     GESCHRUMPFT, und ein 124 px breites Rechteck war dadurch 48 px breit — es sah
     nach einem Rechenfehler aus und war einer im Layout. Absolut positioniert
     kennt der Kasten die 48 px nicht mehr.
     Die Verschiebung um die halbe eigene Größe zentriert es über dem Ort; sie
     steht im SELBEN transform wie die Drehung, weil ein zweites transform das
     erste ersetzt. */
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--lf-rect-w, 12px);
  height: var(--lf-rect-h, 12px);
  /* Die Drehung sitzt HIER und nicht am Knopf: MapLibre schreibt transform am
     Markerelement selbst und überschriebe sie bei jeder Kamerabewegung. */
  transform: translate(-50%, -50%) rotate(var(--lf-rect-rot, 0deg));
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--lf-marker, #888) 55%, transparent);
  border: 2px solid var(--lf-marker, #888);
  border-radius: 2px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
  box-sizing: border-box;
}

/* Halbdurchsichtige Füllung, damit man SIEHT, was darunter liegt: auf dem Luftbild
   ist das der Grund, auf dem der Stand stehen soll — Schotter, Rasen, Bordstein.
   Eine deckende Fläche verstecken genau die Auskunft, für die man das Luftbild
   eingeschaltet hat. Der Rand bleibt deckend, sonst verschwimmt die Kante, an der
   man ausrichtet. */

/* Die Kennung bleibt AUFRECHT: das Rechteck dreht sich, die Zahl nicht. Bei 180°
   stünde sie sonst auf dem Kopf, und ein Aufbauplan wird im Gehen gelesen. */
.marker--rect .marker__rectnr {
  display: block;
  transform: rotate(calc(-1 * var(--lf-rect-rot, 0deg)));
  font-family: var(--lf-font-display);
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
  white-space: nowrap;
}

/* Zu klein für eine Zahl. Sie stünde über die Ränder hinaus und machte aus dem
   Rechteck einen Fleck — dann ist die Fläche selbst die Auskunft. */
.marker--rect-tiny .marker__rectnr { display: none; }

/* Die Auswahl am Rechteck. Der pulsierende Ring weiter unten ist ein KREIS von
   38 px — um ein Rechteck von 250 px gelegt sähe er wie ein zweiter, fremder Marker
   aus. Er wird deshalb hier abgeschaltet, und die Auswahl steht am Rechteck selbst:
   weißer Rand plus Signalfarbe außen herum, dieselben drei Mittel wie an der
   Scheibe (Rand, Schatten, Farbe) — nur an der richtigen Form. */
.marker--rect.marker--sel::after { display: none; }
.marker--rect.marker--sel .marker__face {
  border-color: #fff;
  box-shadow:
    0 0 0 2.5px var(--lf-signal),
    0 2px 8px rgba(0, 0, 0, .45);
}

/* Der Drehgriff am ausgewählten Rechteck (rotateHandle in js/map.js).
   Nur im Portal — die Besucher-App ruft rotateHandle nie.

   44 px, weil man ihn mit dem Daumen fassen soll; das gezeichnete Rund ist kleiner
   (26 px), damit er das Rechteck nicht zudeckt. Dieselbe Trennung wie beim Marker:
   Trefferfläche und Grafik sind zwei verschiedene Maße. */
.rotgrip {
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  /* Über den Rechtecken, damit er greifbar bleibt, wenn ein großer Stand darunter
     liegt. Unter Suchfeld (6) und Blatt (5) wie der ausgewählte Marker. */
  z-index: 4;
}
.rotgrip::before {
  content: '';
  position: absolute;
  width: 26px;
  height: 26px;
  border-radius: var(--lf-r-full);
  background: var(--lf-signal);
  border: 2.5px solid #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .4);
}
.rotgrip svg {
  position: relative;
  width: 15px;
  height: 15px;
  fill: #fff;
}
.rotgrip:hover::before { transform: scale(1.12); }
.rotgrip:focus-visible { outline: 3px solid var(--lf-signal); outline-offset: 3px; }
/* Beim Ziehen: der Zeiger bleibt am Griff, auch wenn er über die Karte hinauswandert.
   `cursor: grabbing` am Griff allein genügte nicht — der Zeiger ist während des
   Ziehens über der Karte, nicht über dem Knopf. */
.rotgrip--on { cursor: grabbing; }
.rotgrip--on::before { transform: scale(1.12); background: var(--lf-ink); }

/* --- Ausgewählter Marker -------------------------------------------------
   Ein Ring in Signal-Orange allein reichte nicht: auf einem orangefarbenen
   Essen-Marker verschwand er fast. Deshalb drei Mittel zusammen —
   1. die Scheibe wird größer,
   2. ein weißer Spalt trennt sie von einem kräftigen Signal-Ring,
   3. ein Ring pulsiert nach außen und holt das Auge hin.
   Der Marker liegt außerdem über seinen Nachbarn, damit der Ring nicht
   halb verdeckt wird. */
.marker--sel {
  /* Über den anderen Markern, aber unter Suchfeld (6) und Blatt (5). */
  z-index: 4;
}
.marker--sel::before {
  transform: scale(1.12);
  border-color: #fff;
  box-shadow:
    0 0 0 3px var(--lf-signal),
    0 3px 10px rgba(0, 0, 0, .4);
}
.marker--sel:hover::before { transform: scale(1.18); }

/* Der pulsierende Ring. Zweite Aufgabe dieser Regel: sie ist gleichzeitig der
   ruhende Zustand. Bei „prefers-reduced-motion" bricht die Animation sofort ab
   (siehe tokens.css), und was übrig bleibt, ist genau dieser ruhende Ring —
   sichtbar, nur ohne Bewegung. Deshalb steht hier opacity 1 und kein scale. */
.marker--sel::after {
  content: '';
  position: absolute;
  inset: 5px;
  border-radius: var(--lf-r-full);
  border: 2.5px solid var(--lf-signal);
  opacity: 1;
  pointer-events: none;
  animation: marker-pulse 1.8s ease-out infinite;
}
.marker--infra.marker--sel::after { inset: 7px; border-radius: 10px; }

@keyframes marker-pulse {
  0% { transform: scale(1); opacity: .85; }
  /* Früh ausgeblendet, damit die letzte Drittel-Sekunde ruhig bleibt und der
     Puls nicht als Flackern gelesen wird. */
  70% { transform: scale(2.1); opacity: 0; }
  100% { transform: scale(2.1); opacity: 0; }
}

/* Infrastruktur ist ein anderer Objekttyp, nicht eine andere Farbe:
   eckig statt rund, damit die Form die Typen trennt. */
.marker--infra { color: var(--lf-blau); transition: opacity .15s; }
.marker--infra::before {
  inset: 7px;
  border-radius: 10px;
  background: #fff;
  border: 2.5px solid var(--lf-blau);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .22);
}
.marker--infra .ic { width: 19px; height: 19px; }
