/* Livemap – Gestaltung.

   Arbeitet ausschliesslich mit den Gestaltungswerten aus styles.css
   (--surface-*, --border*, --text-*, --good/--warning/--serious/--critical
   samt deren -ink-Ableitungen, --fs-*, --radius, --dur-*, --easing). Neue
   Farbwerte kommen nur dort dazu, wo eine Flaeche im hellen und im dunklen
   Erscheinungsbild verschieden sein MUSS – und dann mit dem nachgerechneten
   Grund daneben.

   Die Lage, fuer die das gestaltet ist: Jemand uebernimmt nachts einen Dienst
   auf einem Gebiet, das er nicht kennt. Handy in der einen Hand, Lampe in der
   anderen, Handschuhe an, Regen. Er muss ohne Einweisung sehen, wo die
   Kontrollpunkte sind, welche noch offen sind, wie er hinkommt, und er muss am
   Punkt eine Aussage machen koennen.

   ---------------------------------------------------------------------------
   VIER ENTSCHEIDE, DIE ALLES ANDERE NACH SICH ZIEHEN

   1. AMTLICHE LANDESKARTE IM HINTERGRUND, GITTER DARUEBER.
      GEAENDERT am 5. August 2026. Hier stand vorher "keine Landkarte im
      Hintergrund", mit dem Umriss aus ch-umriss.js als Begruendung: Der
      stimmt auf wenige Kilometer (ch-umriss.js:3) und haette auf einer
      Flaeche, auf der 80 Meter zwischen zwei Punkten liegen, eine
      Genauigkeit vorgetaeuscht, die es nie gab.

      Die Begruendung war richtig, der Schluss war falsch. Sven hat die
      Livemap geoeffnet und keine Karte gesehen - und ein Gitter ohne
      Untergrund beantwortet die Frage "wo ist das" eben NICHT. Der Fehler
      lag nicht darin, eine ungenaue Karte wegzulassen, sondern darin, keine
      genaue zu suchen.

      Es gibt eine: die amtliche Landeskarte von swisstopo, in
      Landeskoordinaten (LV95) - demselben Bezugssystem, in dem diese Flaeche
      ohnehin rechnet. Nichts wird umgerechnet, nichts verzogen. Das Gitter
      bleibt DARUEBER liegen und bleibt der Massstab; fehlt eine Kachel oder
      ist das Kartenbild abgeschaltet, sieht die Flaeche aus wie vorher und
      beantwortet weiterhin die eine Frage, die sie ohne Bild ehrlich
      beantworten kann: wie weit zwei Punkte auseinander liegen.

      Warum nicht Google, obwohl Sven "google maps oder so" gesagt hat: Die
      Begruendung steht bei KACHEL_DIENST in livemap.js, samt dem, was der
      Kartendienst dabei erfaehrt.

   2. MARKEN UND SCHILDER LIEGEN IN EINER UNGESKALIERTEN EBENE.
      karte.js teilt jeden Radius durch die Vergroesserung (karte.js:451) und
      erreicht am Anschlag Marken von 260 Meter Breite – fuenfzig Punkte in
      Baar waeren ein Fleck. objektplan.js macht es richtig und bemisst Marken
      in Bildschirmpunkten (objektplan.js:67-75). Die Livemap folgt
      objektplan.js: livemap.js haelt die Marken- und Schilderebene
      ungeskaliert und verschiebt jedes Zeichen nur mit einem
      transform-Attribut. Genau darum – und nur darum – darf diese Datei
      Schriftgroessen in echten Pixeln setzen. Wuerde die Ebene mitskalieren,
      waere jede Groesse hier gelogen.

   3. FARBE IST NIE DER EINZIGE TRAEGER.
      Hausregel, wortwoertlich aus objektplan.js:95: "Rot und Gruen sind fuer
      rund jeden zwoelften Mann nicht zu unterscheiden, ein Dreieck und ein
      Quadrat fuer jeden." Jeder Zustand hat darum FORM, FARBE, ZEICHEN und
      WORT:

        offen (nicht eingelesen)  Ring, offen/gestrichelt, rot,     "offen"
        eingelesen                Scheibe, gefuellt,      gruen,    "eingelesen"
        Abweichung gemeldet       Dreieck, gefuellt,      orange,   "Abweichung"
        nicht pruefbar            Quadrat, gefuellt,      gelb,     "nicht pruefbar"

      ZUM ROT, und das ist der eine Punkt, an dem diese Datei von rundgang.css
      abweicht: Dort ist Rot die Abweichung (rundgang.css:97) und "nicht
      erfasst" ein gestrichelter Rand ohne Farbe (rundgang.css:367). Svens
      Auftrag sagt fuer die Livemap ausdruecklich "nicht eingelesen ist rot"
      (AUSTAUSCH/livemap-auftrag.md:20-21, begruendet nochmals in Zeile 46-50).
      Beides gleichzeitig geht nicht, ohne dass Rot auf demselben Geraet
      zweierlei heisst. Der Entscheid hier: Auf der Livemap ist die
      Leitfrage "was ist noch offen", also traegt Rot das Offene; die
      Abweichung rueckt auf --serious und bekommt als einzige ein Dreieck. Wer
      es anders will, aendert die vier Werte unter "Zustandsfarben" – eine
      Zeile je Zustand, sonst nichts. Diese Abweichung gehoert Sven vorgelegt.

   4. LANGER DRUCK BEKOMMT IMMER EINEN ZWEITEN WEG.
      Gedrueckt-halten ist mit nassen Handschuhen die unzuverlaessigste Geste,
      die es gibt (dieselbe Begruendung wie rundgang.css:9-19). Der lange
      Druck ist darum die Abkuerzung, nicht der Weg: In der Tafel steht
      derselbe Befehl noch einmal als sichtbarer Knopf. Ein Bildschirm, auf
      dem eine Handlung nur ueber eine Geste erreichbar ist, hat sie fuer die
      Haelfte der Naechte gar nicht.

   ---------------------------------------------------------------------------
   WAS DIESE DATEI BEWUSST NICHT ENTHAELT

   Keine Klasse fuer eine Personenmarke, keine Spur, keine Linie zwischen zwei
   Punkten, kein Verlauf. Svens Entscheid vom 4. August 2026 lautet "nur die
   Punkte, nie die Person" (AUSTAUSCH/livemap-auftrag.md:75). Eine Gestaltung,
   die eine Bewegung zeichnen koennte, ist die Einladung dazu – sie fehlt hier
   deshalb ersatzlos.

   Die einzige Ausnahme ist .lm-hier: der EIGENE Standort auf dem EIGENEN
   Geraet. Er wird gezeichnet und nie gesendet; livemap.js rechnet daraus
   hoechstens einen gerundeten Abstand. Wer diese Klasse je fuer einen fremden
   Standort verwendet, bricht den Entscheid. */

/* ---------------------------------------------------------------------------
   Werte
   --------------------------------------------------------------------------- */

:root {
  /* Zustandsfarben. Absichtlich die -ink-Ableitungen aus styles.css und nicht
     die Flaechenwerte: Die -ink-Werte sind dort genau dafuer gemacht, auf dem
     Grund der Seite zu tragen, und sie kippen mit dem Erscheinungsbild von
     selbst (styles.css:31-35 und 84-86). --good auf hellem Grund kommt roh nur
     auf 2,9:1 und faellt damit unter die geforderten 3:1; --good-ink ist
     dieselbe Farbe, nur dunkel genug. Damit braucht diese Datei fuer die
     Zustaende keinen einzigen eigenen Farbwert und keinen Dunkelmodus-Block. */
  --lm-offen: var(--critical-ink);
  --lm-eingelesen: var(--good-ink);
  --lm-abweichung: var(--serious-ink);
  --lm-unpruefbar: var(--warning-ink);

  /* Der Grund, auf dem die Punkte liegen. Die abgesenkte Flaeche des Hauses:
     ruhig, in beiden Erscheinungsbildern vorhanden, kein neuer Ton. */
  --lm-grund: var(--surface-sunken);

  /* Das Raster ist Massstab, keine Zeichnung. Es sagt "so weit ist so weit"
     und sonst nichts – darum die Linienfarbe des Hauses und nicht mehr. */
  --lm-raster: var(--border);

  /* Die Fassung traegt jede Marke ueber jede Flaeche und ueber jede andere
     Marke, die darunter durchschaut. Sie ist ein Ausschnitt im Grundton, kein
     eigener Farbwert – im Hellen hell, im Dunkeln dunkel. Eine weisse Fassung
     im Dunkeln waere der hellste Punkt der ganzen Flaeche, und das Auge ginge
     zum Ring statt zur Marke (dieselbe Ueberlegung wie karte.css:82-85). */
  --lm-fassung: #ffffff;

  /* Derselbe Fokusring wie auf Karte und Plan, absichtlich: Ein Fokus, der auf
     drei Ansichten unterschiedlich aussieht, wird dreimal gelernt. */
  --lm-fokus: #0b6bcb;

  /* Die Dauer des langen Drucks steht HIER, nicht in livemap.js. Der Ring am
     Punkt fuellt sich genau so lange, wie das Halten dauern muss; zwei Zahlen
     dafuer waeren zwei Wahrheiten. livemap.js liest den Wert mit
     getComputedStyle vom Wurzelelement. */
  --lm-druck-dauer: 500ms;
}

:root[data-theme="dark"] {
  --lm-fassung: #14121c;
  --lm-fokus: #6cb2f5;
}

/* ---------------------------------------------------------------------------
   Rahmen
   --------------------------------------------------------------------------- */

.lm {
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* Breiter als der Rundgang (640px), weil hier eine Flaeche gelesen wird und
     nicht ein Satz. Aber nicht die volle Fensterbreite: Das Ziel bleibt das
     Telefon, und eine Karte, die auf dem Bueroschirm 1700px breit wird, wird
     genau einmal am Bueroschirm entworfen und nie wieder nachts geprueft. */
  max-width: 860px;
  margin: 0 auto;
  /* Der lange Druck ist eine tragende Geste dieser Ansicht. Ohne diese beiden
     Zeilen oeffnet iOS beim Halten das Lupen- und Teilen-Menue und Android
     markiert Text – in beiden Faellen ist der Druck weg, bevor er zaehlt. */
  -webkit-touch-callout: none;
  user-select: none;
}

/* Die Ueberschrift bekommt nach jedem Zeichnen den Fokus, damit eine
   Sprachausgabe zuerst sagt, wo man steht. Sichtbar wird das nur, wenn der
   Fokus auch wirklich gezeigt werden soll. */
.lm-titel { font-size: var(--fs-2xl); line-height: 1.2; }
.lm-titel:focus-visible { outline: 2px solid var(--accent-fg); outline-offset: 4px; }

/* ---------------------------------------------------------------------------
   Der Satz, der ueber allem steht
   --------------------------------------------------------------------------- */

/* "Der Satz gehoert auch sichtbar in die Oberflaeche, nicht nur in diese
   Datei" – AUSTAUSCH/livemap-auftrag.md:109-111. Er steht darum fest im
   Bildschirm und nicht in einem Aufklapper. Ruhig gesetzt, aber nicht klein:
   Er ist der Unterschied zwischen diesem Produkt und der Werbung der
   Konkurrenz. Gleiche Form wie .rg-wahrheit in rundgang.css:338-345, damit man
   ihn ueber die Ansichten hinweg wiedererkennt. */
.lm-wahrheit {
  margin: 0;
  font-size: var(--fs-md);
  line-height: 1.6;
  color: var(--text-secondary);
  /* Haarlinie statt Farbbalken: Ein 3px-Akzentstreifen zieht den Blick
     staerker an als der Text, den er begleiten soll - und wo mehrere solche
     Markierungen auf einer Seite stehen, streiten sie miteinander. Eine
     Linie in der Randfarbe ordnet genauso, ohne zu rufen
     (AUSTAUSCH/design-referenz-claude-app.md). */
  border-left: 1px solid var(--border);
  padding-left: 14px;
}
.lm-wahrheit b { color: var(--text-primary); font-weight: 600; }

/* Die drei Grenzen. Aufklappbar, aber der Kopf sagt schon das Wesentliche –
   wer nichts aufklappt, ist trotzdem nicht getaeuscht worden. */
.lm-grenzen {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 4px 13px;
  background: var(--surface-1);
  font-size: var(--fs-md);
  line-height: 1.55;
  color: var(--text-secondary);
}
.lm-grenzen > summary {
  cursor: pointer;
  /* Ein Aufklapper ist ein Bedienelement und braucht die Trefferflaeche eines
     Knopfes, nicht die einer Textzeile. Erreicht ueber Innenabstand und nicht
     ueber min-height mit display:flex: Ein summary mit eigenem display verliert
     in WebKit sein Dreieck, und dann sieht man dem Ding nicht mehr an, dass es
     sich oeffnen laesst. */
  padding: 11px 0;
  font-weight: 600;
  color: var(--text-secondary);
}
.lm-grenzen ol { margin: 0 0 12px; padding-left: 20px; }
.lm-grenzen li { margin-bottom: 8px; }
.lm-grenzen li:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------------------
   Dienstwahl
   --------------------------------------------------------------------------- */

/* Waagerecht rollbar statt umbrechend: Eine Schalterreihe, die bei acht
   Diensten drei Zeilen hoch wird, schiebt die Flaeche aus dem Bild – dieselbe
   Loesung wie bei den Planebenen (objektplan.css:604-612). */
.lm-dienste {
  display: flex;
  gap: 6px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: 4px;
}

.lm-dienst {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
  text-align: left;
  min-height: 44px;
  padding: 6px 13px;
  font: inherit;
  font-size: max(14px, var(--fs-md));
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 9px;
  cursor: pointer;
}
.lm-dienst:hover { background: var(--surface-sunken); color: var(--text-primary); }
.lm-dienst.ist-aktiv {
  color: var(--accent-fg);
  background: var(--accent-soft);
  border-color: var(--accent);
}
.lm-dienst-zahl {
  font-size: max(12px, var(--fs-xs));
  font-weight: 400;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.lm-dienst.ist-aktiv .lm-dienst-zahl { color: var(--accent-fg); }

/* ---------------------------------------------------------------------------
   Die Flaeche
   --------------------------------------------------------------------------- */

/* Bezug fuer alles, was ueber der Zeichnung liegt: Steuerung, Massstab,
   Nordpfeil, Meldung. */
.lm-buehne {
  position: relative;
}

.lm-flaeche {
  display: block;
  width: 100%;
  /* Nach der HOEHE des Fensters gedeckelt, nicht nach der Breite: Die knappe
     Richtung ist die Hoehe, und eine Flaeche, die die Liste unter die Falz
     draengt, kostet genau die Uebersicht, wegen der sie da ist. */
  height: clamp(300px, 52vh, 520px);
  background: var(--lm-grund);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* Ohne das rollt beim Wischen ueber die Flaeche die Seite mit und die Karte
     bleibt stehen – auf dem Telefon der haeufigste Grund fuer "die Karte
     klemmt". Zugleich die Bedingung dafuer, dass Ziehen, Kneifen und langer
     Druck ueberhaupt sauber auseinanderzuhalten sind. */
  touch-action: none;
}

.lm-flaeche.wird-gezogen { cursor: grabbing; }

/* Das Raster. Es ist Massstab und nicht Zeichnung: eine Haarlinie, unabhaengig
   von der Vergroesserung, und nur so kraeftig, dass man sie sieht, wenn man
   sie sucht. Wer es fuer Strassen haelt, hat sich verguckt – darum steht der
   Massstabsbalken zusaetzlich mit einer Zahl daneben. */
.lm-raster {
  stroke: var(--lm-raster);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  fill: none;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
   Zeichen: eine Form je Zustand, dreimal verwendet
   --------------------------------------------------------------------------- */

/* Dieselben vier Formen erscheinen an drei Stellen: als Marke auf der Flaeche
   (SVG), als Zeichen in der Punktliste und in der Tafel (HTML), und in der
   Zeichenerklaerung (HTML). Ein Zeichen, das in der Erklaerung anders aussieht
   als in der Zeichnung, erklaert nichts (objektplan.css:571-573). */

/* --- Die Marke auf der Flaeche --- */

.lm-marke { cursor: pointer; }

/* Die unsichtbare Trefferflaeche. Sichtbar bleibt die Marke bei ihren rund
   26 Bildschirmpunkten, getroffen wird ein Feld von 44 – dieselbe Loesung wie
   am Spurpunkt des Rundgangs (rundgang.css:77-90) und am Loeschkreuz der
   Bilder. Mit Handschuhen ist das der Unterschied zwischen "geht" und "geht
   nicht". Den Radius setzt livemap.js als Attribut, hier steht nur, dass die
   Flaeche unsichtbar ist und trotzdem trifft. */
.lm-marke-griff {
  fill: transparent;
  stroke: none;
}

/* Groesse und Lage setzt livemap.js als Attribut – beides haengt an der
   Projektion. Hier stehen nur Farbe und Strich, sonst streiten sich zwei
   Stellen um denselben Wert (gleiche Aufteilung wie karte.css:173-175). */
.lm-marke-form {
  stroke: var(--lm-fassung);
  stroke-width: 2;
  /* Die Fassung soll zwei Bildschirmpunkte breit bleiben, egal wie stark
     vergroessert ist – sonst verschwindet sie beim Hineinzoomen. */
  vector-effect: non-scaling-stroke;
  stroke-linejoin: round;
}

/* Offen: ein Ring, gestrichelt, mit einer sehr leichten Fuellung. Die Fuellung
   macht ihn nachts sichtbar, das Gestrichelte sagt "hier steht noch nichts".
   Damit spricht der offene Punkt dieselbe Sprache wie die leere Zeile im
   Rundgangabschluss (rundgang.css:367) – nur eben in Rot, weil er auf dieser
   Ansicht die Leitfrage traegt. */
.lm-marke.ist-offen .lm-marke-form {
  fill: color-mix(in srgb, var(--lm-offen) 18%, transparent);
  stroke: var(--lm-offen);
  stroke-width: 2.5;
  stroke-dasharray: 4 3;
}

/* Eingelesen: voll gefuellt. Die einzige Marke, die Flaeche bekommt – genau
   wie die gepruefte Marke die einzige Stufe ist, die Flaeche bekommt
   (rundgang.css:237-245). Voll heisst hier: es liegt eine Aussage vor. */
.lm-marke.ist-eingelesen .lm-marke-form { fill: var(--lm-eingelesen); }
.lm-marke.ist-abweichung .lm-marke-form { fill: var(--lm-abweichung); }
.lm-marke.ist-unpruefbar .lm-marke-form { fill: var(--lm-unpruefbar); }

/* Das Zeichen in der Marke. Die Schriftgroesse darf hier in Pixeln stehen,
   WEIL die Markenebene ungeskaliert ist (siehe Entscheid 2 im Kopf). Wer diese
   Bedingung in livemap.js aufhebt, macht diese Zeile zur Luege. */
.lm-marke-zeichen {
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  fill: var(--lm-fassung);
  text-anchor: middle;
  /* Das Zeichen wird gelesen, nie markiert – beim Ziehen sonst blau umrandet. */
  user-select: none;
  pointer-events: none;
}
/* Auf der offenen Marke gibt es keine Fuellung, die das Zeichen tragen
   koennte – dort traegt es sich selbst. */
.lm-marke.ist-offen .lm-marke-zeichen { fill: var(--lm-offen); }

/* Die Nummer steht NEBEN der Marke, nicht darin: In der Marke haette sie mit
   dem Zustandszeichen um denselben Platz gestritten, und das Zeichen ist
   wichtiger. Der Hof aus paint-order traegt sie ueber jede Flaeche
   (dasselbe Rezept wie objektplan.css:237-246). */
.lm-marke-nr {
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  fill: var(--text-primary);
  stroke: var(--lm-grund);
  stroke-width: 3.5px;
  paint-order: stroke fill;
  vector-effect: non-scaling-stroke;
  user-select: none;
  pointer-events: none;
}

/* Der Fokusring ist ein eigenes Element im Markup: Ein CSS-Umriss um eine
   SVG-Gruppe zeichnen Browser unterschiedlich, teils rechteckig, teils gar
   nicht. Ein Kreis sitzt ueberall gleich (karte.css:206-208). */
.lm-fokus {
  fill: none;
  stroke: none;
  stroke-width: 2;
}
.lm-marke:focus { outline: none; }
.lm-marke:focus-visible .lm-fokus { stroke: var(--lm-fokus); }

/* Ausgewaehlt bleibt sichtbar, auch wenn der Fokus weitergewandert ist – sonst
   weiss niemand mehr, worauf sich die Tafel darunter bezieht. Dickere Linie
   als beim Fokus: "ausgewaehlt" und "gerade unter dem Finger" sind zwei
   verschiedene Aussagen und duerfen nicht gleich aussehen. Die Unterscheidung
   haengt an der Strichbreite, nicht an der Farbe (karte.css:223-231). */
.lm-marke.ist-gewaehlt .lm-fokus {
  stroke: var(--lm-fokus);
  stroke-width: 3.5;
}

/* Der einzige Uebergang an der Marke: die Fassung waechst unter dem Zeiger.
   Bewusst KEIN Farbwechsel – jede Farbe dieser Ansicht bedeutet etwas, und
   eine Marke, die unter dem Zeiger kurz aussieht wie ein anderer Zustand, sagt
   fuer einen Moment etwas Falsches (dieselbe Ueberlegung wie karte.css:273-283).
   Die Dicke der Fassung bedeutet nichts, darum darf sie sich bewegen. */
.lm-marke:hover .lm-marke-form { stroke-width: 3; }

/* Die Marke zu der Zeile, ueber der jemand gerade steht. Dieselbe Bewegung wie
   beim Ueberfahren der Marke selbst — eine zweite Sprache fuer dieselbe
   Aussage waere eine zweite Aussage. Kein Farbwechsel, aus demselben Grund wie
   oben. Der Ring ist schwaecher als beim Fokus und deutlich schwaecher als bei
   der Auswahl: "die Maus ist auf der Zeile" ist die leiseste der drei
   Aussagen und muss auch so aussehen. */
.lm-marke.ist-hervor .lm-marke-form { stroke-width: 3; }
.lm-marke.ist-hervor .lm-fokus {
  stroke: var(--lm-fokus);
  stroke-opacity: .45;
}

@media (prefers-reduced-motion: no-preference) {
  .lm-marke-form { transition: stroke-width var(--dur-schnell) var(--easing); }
}

/* --- Der lange Druck --- */

/* Der Ring fuellt sich, solange gehalten wird. Er ist der einzige Hinweis
   darauf, dass ueberhaupt etwas laeuft; ohne ihn haelt man drei Sekunden und
   glaubt, das Geraet sei eingefroren.

   stroke-dasharray 132 ist der Umfang des Rings bei Radius 21 (2*pi*21 =
   131,9). livemap.js setzt denselben Radius als Attribut – wer ihn aendert,
   aendert auch diese Zahl, sonst laeuft der Ring zu kurz oder zu weit. */
.lm-druckring {
  fill: none;
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 132;
  stroke-dashoffset: 132;
  /* Ohne Drehung begaenne der Ring rechts. Oben ist die Stelle, an der man
     eine Uhr ablaufen sieht. */
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(-90deg);
  opacity: 0;
  pointer-events: none;
}

.lm-marke.wird-gedrueckt .lm-druckring {
  opacity: 1;
  animation: lm-druck var(--lm-druck-dauer) linear forwards;
}

@keyframes lm-druck {
  from { stroke-dashoffset: 132; }
  to { stroke-dashoffset: 0; }
}

/* --- Dasselbe Zeichen in HTML: Liste, Tafel, Zeichenerklaerung --- */

.lm-zeichen {
  display: inline-block;
  width: 16px;
  height: 16px;
  flex: none;
  border: 2px solid transparent;
  border-radius: 50%;
}
.lm-zeichen.ist-offen {
  background: color-mix(in srgb, var(--lm-offen) 18%, transparent);
  border-color: var(--lm-offen);
  border-style: dashed;
}
.lm-zeichen.ist-eingelesen { background: var(--lm-eingelesen); border-color: var(--lm-eingelesen); }
/* Quadrat, nicht Kreis – dieselbe Form wie die Marke auf der Flaeche. */
.lm-zeichen.ist-unpruefbar {
  background: var(--lm-unpruefbar);
  border-color: var(--lm-unpruefbar);
  border-radius: 3px;
}
/* Dreieck aus einem Rahmen, kein zusaetzliches Bild noetig
   (objektplan.css:576-585). */
.lm-zeichen.ist-abweichung {
  width: 0;
  height: 0;
  border: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-bottom: 15px solid var(--lm-abweichung);
  background: none;
  border-radius: 0;
}

/* ---------------------------------------------------------------------------
   Der Balken ueber der Haeufung
   --------------------------------------------------------------------------- */

/* Das Herzstueck des Auftrags: "man sieht bei der Livemap ueber der Stadt Zug
   einen Balken wo genau steht OD1 Patrouille Kanton Zug"
   (AUSTAUSCH/livemap-auftrag.md:17-19).

   Er liegt im SVG und nicht als HTML darueber, aus einem Grund: Dieses Projekt
   fuehrt keine style-Attribute im Markup (begruendet in karte.css:251-254).
   Ein HTML-Balken muesste bei jedem Ziehschritt seine Lage als style bekommen.
   Im SVG genuegt ein transform-Attribut an der Gruppe, und weil die
   Schilderebene ungeskaliert ist, bleiben Schrift und Hoehe konstant. */

.lm-balken { cursor: pointer; }

.lm-balken-feld {
  fill: var(--surface-2);
  stroke: var(--border-strong);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

/* Die Spitze zeigt auf die Haeufung, ueber der der Balken steht. Ohne sie
   schwebt eine Beschriftung im Raum und niemand weiss, wozu sie gehoert. */
.lm-balken-spitze {
  fill: var(--surface-2);
  stroke: var(--border-strong);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.lm-balken-name {
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  fill: var(--text-primary);
  user-select: none;
  pointer-events: none;
}

/* Die Zahl offener Punkte. Sie ist die eigentliche Nachricht des Balkens: Wer
   ihn im Vorbeigehen ansieht, will wissen, ob noch etwas aussteht, nicht wie
   der Dienst heisst. Tabellenziffern, damit sie beim Nachladen nicht springt. */
.lm-balken-zahl {
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  fill: var(--text-muted);
  text-anchor: end;
  user-select: none;
  pointer-events: none;
}
.lm-balken.hat-offene .lm-balken-zahl { fill: var(--lm-offen); }
.lm-balken.ist-fertig .lm-balken-zahl { fill: var(--lm-eingelesen); }

/* Aufgeklappt heisst: Die Punkte dieses Dienstes liegen jetzt auf der Flaeche.
   Der Balken bleibt stehen und zeigt es an – sonst weiss niemand, welcher der
   beiden Balken ueber Zug gerade offen ist. */
.lm-balken[aria-expanded="true"] .lm-balken-feld,
.lm-balken[aria-expanded="true"] .lm-balken-spitze {
  fill: var(--accent-soft);
  stroke: var(--accent);
}
.lm-balken[aria-expanded="true"] .lm-balken-name { fill: var(--accent-fg); }

.lm-balken:focus { outline: none; }
.lm-balken:focus-visible .lm-fokus { stroke: var(--lm-fokus); }

/* ---------------------------------------------------------------------------
   Massstab und Nordpfeil
   --------------------------------------------------------------------------- */

/* Ohne Landkarte im Hintergrund ist der Massstab keine Zierde, sondern die
   einzige Angabe, mit der sich "weit" von "gleich um die Ecke" trennen laesst.
   Er liegt IM Bild, weil die Frage dort entsteht. */
.lm-massstab {
  position: absolute;
  left: 10px;
  bottom: 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 7px;
  background: color-mix(in srgb, var(--surface-1) 88%, transparent);
  border: 1px solid var(--border);
  border-radius: 6px;
  pointer-events: none;
}
/* Der Balken hat eine FESTE Breite, die Zahl daneben wechselt. Ueblicher waere
   das Umgekehrte – ein Balken, der auf eine runde Zahl waechst. Das ginge hier
   nur mit einer Breite als style-Attribut, und die fuehrt dieses Projekt nicht
   (begruendet in karte.css:251-254). Feste Breite plus genaue Zahl sagt
   dasselbe: "diese Strecke sind gerade so viele Meter". */
.lm-massstab-balken {
  width: 64px;
  height: 4px;
  border: 1px solid var(--text-secondary);
  border-top: 0;
}
.lm-massstab-text {
  font-size: max(12px, var(--fs-xs));
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* Klein in der Ecke, wie beim Objektplan: Der Weltbezug ist Nebenangabe, nicht
   Inhalt – aber ganz ohne ihn dreht sich die Flaeche im Kopf. */
.lm-nord {
  position: absolute;
  right: 10px;
  bottom: 10px;
  width: 34px;
  height: 34px;
  padding: 2px;
  background: color-mix(in srgb, var(--surface-1) 88%, transparent);
  border: 1px solid var(--border);
  border-radius: 50%;
  pointer-events: none;
}
.lm-nord-bild { display: block; width: 100%; height: 100%; }
.lm-nord-pfeil { fill: var(--text-secondary); }
.lm-nord-text {
  fill: var(--text-secondary);
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Sie sind hier
   --------------------------------------------------------------------------- */

/* Der eigene Standort, gezeichnet auf dem eigenen Geraet. Er wird NIE
   gesendet: livemap.js rechnet daraus hoechstens einen gerundeten Abstand zum
   Punkt (Svens Entscheid, livemap-auftrag.md:89-93). Der Hof zeigt die
   gemeldete Genauigkeit als Flaeche – im Gebaeude sind fuenfzig Meter normal,
   und ein spitzer Punkt wuerde eine Genauigkeit behaupten, die es nicht gibt.
   Das ist Grenze 3 des Auftrags, als Form statt als Satz. */
.lm-hier { pointer-events: none; }

.lm-hier-hof {
  fill: color-mix(in srgb, var(--accent) 18%, transparent);
  stroke: var(--accent);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

.lm-hier-kern {
  fill: var(--accent);
  stroke: var(--lm-fassung);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

/* Ein einziger, langsamer Puls. Er zieht das Auge auf die eine Stelle, die man
   sofort finden muss, und ist so traege, dass er beim Lesen nicht stoert. */
.lm-hier-hof {
  transform-box: fill-box;
  transform-origin: center;
  animation: lm-puls 2.4s ease-in-out infinite;
}

@keyframes lm-puls {
  0%, 100% { opacity: .55; transform: scale(.86); }
  50% { opacity: 1; transform: scale(1); }
}

/* ---------------------------------------------------------------------------
   Bedienung auf der Flaeche
   --------------------------------------------------------------------------- */

/* Die Knoepfe liegen auf der Flaeche, nicht darunter: Wer den Ausschnitt
   sucht, schaut auf die Karte und nicht ans Seitenende. */
.lm-steuerung {
  position: absolute;
  top: 10px;
  right: 10px;
  display: grid;
  grid-template-columns: repeat(2, 44px);
  gap: 4px;
  padding: 5px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* 44px, nicht 32 wie auf Karte und Plan. Dort sitzt man am Tisch, hier steht
   man im Regen. */
.lm-knopf {
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font: inherit;
  font-size: max(15px, var(--fs-lg));
  line-height: 1;
  color: var(--text-primary);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
.lm-knopf.ist-breit { grid-column: 1 / -1; height: 38px; font-size: max(13px, var(--fs-sm)); }
.lm-knopf:hover:not(:disabled) { background: var(--surface-0); }
.lm-knopf:focus-visible { outline: 2px solid var(--lm-fokus); outline-offset: 1px; }
.lm-knopf:disabled {
  /* Nicht ausblenden, nur abschwaechen: Ein Knopf, der verschwindet, laesst die
     uebrigen springen und man drueckt daneben. */
  opacity: .4;
  cursor: default;
}

/* Sie liegt IM Bild und nicht am Seitenende, weil die Frage "warum sehe ich
   nichts" genau dort entsteht, wo nichts zu sehen ist. */
.lm-meldung {
  position: absolute;
  inset: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 18px;
  font-size: max(14px, var(--fs-md));
  line-height: 1.5;
  color: var(--text-secondary);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* ---------------------------------------------------------------------------
   Hineinzoomen: der Ring am Ziel und der Weg zurueck
   --------------------------------------------------------------------------- */

/* DER RING AM ZIEL. Er laeuft einmal vom Punkt weg, sobald die Zoomfahrt
   angekommen ist, und verblasst dabei - die Antwort auf "wo bin ich
   gelandet", bevor jemand sie stellt.

   Radius und Deckung setzt livemap.js als Attribut, und das ist hier kein
   Versehen: Die Zielebene entsteht bei JEDEM Bild neu, ein Ablauf in dieser
   Datei finge damit bei jedem Bild wieder von vorn an. Den Fortschritt fuehrt
   deshalb die Fahrt selbst. Hier steht nur, wie der Ring aussieht.

   Er sagt "hier", nicht "Achtung": ein Lauf, kein Blinken, und in der
   Akzentfarbe statt in einer Zustandsfarbe. Jede Zustandsfarbe dieser Ansicht
   bedeutet etwas ueber den Punkt - ein roter Ring um einen gruenen Punkt
   saehe fuer einen Moment aus wie ein Widerspruch. */
.lm-ziel { pointer-events: none; }

.lm-ziel-ring {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  /* Zwei Bildschirmpunkte breit, egal wie stark vergroessert ist - dieselbe
     Regel wie an der Marke. */
  vector-effect: non-scaling-stroke;
}

/* DER WEG ZURUECK, und warum er als eigener Knopf im Bild steht.

   Nach einer Zoomfahrt sieht man 172 Meter Umgebung. Wo die uebrigen Punkte
   liegen, weiss in diesem Moment niemand mehr - und wer den Rueckweg suchen
   muss, hat ihn schon verloren. Der Knopf in der Steuerung ("Ganze
   Uebersicht") kann das allein nicht tragen: Er steht auf dem Handy unten
   rechts zwischen sechs gleich aussehenden Knoepfen.

   OBEN IN DER MITTE, weil die vier Ecken belegt sind - Herkunft, Steuerung,
   Massstab, Nordpfeil - und weil das die Stelle ist, an der man ein "zurueck"
   sucht. Er erscheint nur, solange wirklich nah herangefahren ist; ein Knopf,
   der dorthin fuehrt, wo man schon steht, ist ein Knopf, der luegt.

   Wortlaut GENAU wie der Knopf in der Steuerung. Zwei Woerter fuer dieselbe
   Sache waeren zwei Sachen. */
.lm-zurueck {
  position: absolute;
  top: 10px;
  left: 50%;
  /* Kein transform am Element selbst waere sauberer, aber die Mitte einer
     Flaeche unbekannter Breite gibt es anders nicht - und dieses Projekt
     fuehrt keine style-Attribute im Markup, mit denen livemap.js sie
     ausrechnen koennte. */
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 7px;
  /* 44px wie die uebrigen Knoepfe dieser Ansicht: Am Tisch reichten 32, hier
     steht man im Regen und traegt Handschuhe. */
  min-height: 44px;
  max-width: calc(100% - 20px);
  padding: 0 15px;
  font: inherit;
  font-size: max(14px, var(--fs-md));
  /* Gewicht 500 wie .btn in styles.css: Der Knopf ist ein Ausweg und keine
     Ansage. Fettschrift traegt in diesem Haus nur die eine Handlung, die
     gemeint ist - und gemeint ist auf dieser Ansicht das Einlesen. */
  font-weight: 500;
  white-space: nowrap;
  color: var(--text-primary);
  /* Leicht durchscheinend wie Massstab und Nordpfeil: Er liegt auf der Karte
     und soll nicht so tun, als gehoere die Stelle darunter ihm. */
  background: color-mix(in srgb, var(--surface-1) 92%, transparent);
  /* Haarlinie und Radius 8 nach der Hausskala
     (AUSTAUSCH/design-referenz-claude-app.md). */
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  cursor: pointer;
}
.lm-zurueck:hover { background: var(--surface-1); border-color: var(--border-strong); }
.lm-zurueck:focus-visible { outline: 2px solid var(--lm-fokus); outline-offset: 2px; }

/* Der Pfeil kehrt um und geht nach links oben - dorthin, wo die Uebersicht
   war. Ein reiner Linkspfeil hiesse "eine Seite zurueck", und das ist es
   nicht: Es geht eine Stufe HERAUS. */
.lm-zurueck-pfeil {
  font-size: max(15px, var(--fs-lg));
  line-height: 1;
  color: var(--accent-fg);
}

/* Er erscheint am Ende der Fahrt und soll dabei nicht aufpoppen. Kurz,
   ease-out, nichts federt - dieselbe Bewegungssprache wie im ganzen Haus. */
@media (prefers-reduced-motion: no-preference) {
  .lm-zurueck { animation: lm-zurueck-ein var(--dur-normal) var(--easing); }
}

@keyframes lm-zurueck-ein {
  from { opacity: 0; transform: translate(-50%, -6px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* Auf schmalen Flaechen stossen der mittige Knopf und die Herkunft oben links
   zusammen: "Karte (c) swisstopo" reicht bei 344 Punkten Breite bis weit in
   die Mitte. Die Herkunft weicht nach unten aus und nicht der Knopf - sie ist
   eine Angabe, er ist ein Ausweg. Weglassen darf man sie nicht, swisstopo
   verlangt sie. Darum setzt livemap.js hat-zurueck an die Buehne: Die Regel
   gilt genau dann, wenn der Knopf wirklich steht. */
@media screen and (max-width: 560px) {
  .lm-buehne.hat-zurueck .lm-herkunft { top: 58px; }
}

/* ---------------------------------------------------------------------------
   Die Tafel zum gewaehlten Punkt
   --------------------------------------------------------------------------- */

.lm-tafel {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-left: 4px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 14px 16px;
  box-shadow: var(--shadow);
}
.lm-tafel.ist-offen { border-left-color: var(--lm-offen); }
.lm-tafel.ist-eingelesen { border-left-color: var(--lm-eingelesen); }
.lm-tafel.ist-abweichung { border-left-color: var(--lm-abweichung); }
.lm-tafel.ist-unpruefbar { border-left-color: var(--lm-unpruefbar); }

.lm-tafel-kopf {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 4px;
}

/* Der Name ist die eine Angabe, die im Vorbeigehen lesbar sein muss – und
   zugleich der Text, der spaeter im Rapport im Feld "Ort" steht. */
.lm-tafel-name { flex: 1; font-size: max(19px, var(--fs-xl)); line-height: 1.25; }

.lm-tafel-ort {
  margin: 0 0 8px;
  font-size: max(15px, var(--fs-lg));
  color: var(--text-secondary);
}

/* Was der Zustand heisst, steht als WORT da und nicht nur als Farbe. */
.lm-tafel-zustand {
  margin: 0 0 8px;
  font-size: max(14px, var(--fs-md));
  font-weight: 600;
  color: var(--text-secondary);
}

/* Der Abstand. Gerundete Meter und die gemeldete Genauigkeit, sonst nichts –
   das ist die einzige Form, in der ein Geraetestandort dieses Programm
   verlaesst (livemap-auftrag.md:89-93). Es gibt hier bewusst keine Klasse fuer
   eine Koordinatenanzeige: Was man nicht anzeigen kann, kopiert auch niemand
   in ein Formular. */
.lm-abstand {
  margin: 0 0 4px;
  font-size: max(14px, var(--fs-md));
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

/* Und direkt darunter, kleiner, was der Abstand NICHT belegt. Dieselbe
   Haltung wie bei den Erfassungsarten: Jede Stufe sagt selbst, was sie nicht
   beweist (rundgang.js:139-157). */
.lm-genauigkeit {
  margin: 0 0 12px;
  font-size: max(13px, var(--fs-sm));
  line-height: 1.5;
  color: var(--text-muted);
  border-left: 2px solid var(--border-strong);
  padding-left: 10px;
}

/* Die Erfassungsart-Marken kommen unveraendert aus rundgang.css
   (.rg-art.stufe-geprueft / .stufe-gelesen / .stufe-angegeben). Eine zweite
   Fassung derselben Aussage waere die sicherste Art, sie auseinanderlaufen zu
   lassen – und der Beweiswert einer Erfassung ist genau das, was nirgends
   zweierlei heissen darf. Hier steht nur der Abstand drumherum. */
.lm-art-zeile {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 12px;
}

.lm-tafel-reihe { display: flex; gap: 8px; flex-wrap: wrap; }
/* Hoch und breit: Diese drei Knoepfe werden mit Handschuhen getroffen. */
.lm-tafel-reihe .btn { flex: 1; min-width: 150px; min-height: 48px; justify-content: center; }

/* Navi heisst: die Anwendung verlassen. Das ist keine Kleinigkeit, wenn noch
   etwas in der Warteschlange liegt – der Hinweis dazu steht als Text daneben
   und wird nicht durch eine Farbe ersetzt. */
.lm-tafel-fussnote {
  margin: 8px 0 0;
  font-size: max(13px, var(--fs-sm));
  line-height: 1.5;
  color: var(--text-muted);
}

/* Referenzbild: "So sieht es aus, wenn alles stimmt." Vergleichen faellt
   leichter als Lesen, und station_bilder haengt mit echtem Fremdschluessel an
   den Kontrollpunkten (src/db.js:329-343) – es kostet keine einzige neue
   Spalte. */
.lm-referenz { margin-top: 10px; }
.lm-referenz-knopf {
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-sunken);
  overflow: hidden;
  cursor: zoom-in;
}
.lm-referenz-knopf:focus-visible { outline: 2px solid var(--lm-fokus); outline-offset: 2px; }
.lm-referenz-bild {
  display: block;
  width: 100%;
  max-height: 220px;
  object-fit: cover;
}
.lm-referenz.ist-gross .lm-referenz-knopf { cursor: zoom-out; }
.lm-referenz.ist-gross .lm-referenz-bild { max-height: none; object-fit: contain; }
.lm-referenz-text { margin: 6px 0 0; font-size: max(13px, var(--fs-sm)); color: var(--text-muted); }

/* Fehler des Servers stehen inline und lassen den Nutzer stehen – sie werden
   nicht als Toast weggeblendet. Die Farbe kommt aus .err-msg in styles.css. */
.lm-fehler { margin: 10px 0 0; }

/* ---------------------------------------------------------------------------
   Punktliste unter dem Balken
   --------------------------------------------------------------------------- */

.lm-unter {
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-muted);
  margin: 4px 0 8px;
}

/* Der Zaehler zaehlt PUNKTE, nicht Leistungen. "12 von 50 eingelesen" ist eine
   Aussage ueber den Dienst; "12 von Konto 7" waere eine Verhaltenskontrolle
   nach Art. 26 ArGV 3 (livemap-auftrag.md:102-107). Es gibt in dieser Datei
   deshalb keine Klasse fuer eine Quote je Person, und es darf auch keine
   dazukommen. */
.lm-zaehler {
  margin: 0 0 10px;
  font-size: max(14px, var(--fs-md));
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.lm-liste { list-style: none; margin: 0; padding: 0; }

/* Die Zeile traegt ihren Zustand NICHT mehr als vier Bildpunkte breiten
   Farbbalken. Vier Farben untereinander sind bei fuenfzig Punkten eine
   Farbtabelle und kein Anker — und sie erzwingen genau die Buntheit, die der
   Besitzer gemeldet hat.

   Den Zustand traegt jetzt, was ihn ohnehin am verlaesslichsten traegt: das
   Zeichen mit seiner eigenen FORM je Zustand (darum auch fuer rund jeden
   zwoelften Mann lesbar) und das Wort rechts daneben.

   Was die Zeilen stattdessen ordnet, ist die Flaeche: Ein erledigter Punkt
   tritt eine Stufe zurueck, ein offener steht vorn. Tiefe aus
   Flaechenabstufung statt aus Farbe — Hebel 1 und 4 der Design-Referenz,
   und Haarlinie statt Rahmen. */
.lm-zeile {
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 6px;
  background: var(--surface-1);
}

/* Erledigt heisst zurueckgetreten, nicht abgeschaltet: Die Flaeche sinkt, der
   Text bleibt voll lesbar. Wer die Liste ueberfliegt, sucht das Offene — und
   findet es, weil es das Einzige ist, das vorne steht. */
.lm-zeile.ist-eingelesen { background: var(--surface-2); }
.lm-zeile.ist-eingelesen .lm-zeile-name {
  font-weight: 500;
  color: var(--text-secondary);
}

/* Die einzige Zeile mit Farbe am Rahmen — als Haarlinie, nicht als Balken.
   Eine Abweichung ist die groesste Nachricht dieser Liste; sie darf nicht
   dasselbe Grau tragen wie alles andere. */
.lm-zeile.ist-abweichung { border-color: var(--lm-abweichung); }

.lm-zeile.ist-gewaehlt {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

/* Die ganze Zeile ist der Knopf, nicht ein Teil davon. Wer nachts mit
   Handschuhen eine Zeile trifft, trifft nicht deren rechtes Drittel.

   Raster statt Reihe, und zwar wegen der Nummer: In einer Reihe waere sie so
   breit wie ihre Ziffern, und bei "7" und "48" begaennen die Namen an zwei
   verschiedenen Kanten. Vier Spalten: Nummer, Zeichen, Text, Zustand. */
.lm-zeile-knopf {
  display: grid;
  grid-template-columns: 2.4ch auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  padding: 8px 12px;
  border-radius: 8px;
}

/* Beides fehlte: Eine Zeile, die sich unter dem Zeiger nicht ruehrt, sieht aus
   wie Text; ein Knopf ohne sichtbaren Fokus ist mit der Tastatur unbedienbar.
   Die Farbe bleibt aussen vor — jede Farbe dieser Ansicht bedeutet etwas. */
.lm-zeile-knopf:hover { background: var(--surface-sunken); }
.lm-zeile-knopf:focus-visible { outline: 2px solid var(--lm-fokus); outline-offset: -2px; }

/* Die Nummer steht in einer eigenen Spalte und ist dieselbe, die neben der
   Marke auf der Flaeche steht. Frueher klebte sie im Namen ("14. Schulhaus")
   und wurde mit ihm abgeschnitten. Ziffern in gleicher Laufweite, sonst tanzt
   die Spalte bei jedem Zehnersprung. */
.lm-zeile-nr {
  justify-self: end;
  font-size: max(12px, var(--fs-xs));
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

.lm-zeile-text { min-width: 0; }
.lm-zeile-name {
  display: block;
  /* 580 statt 700: Ueberschriften sind halbfett in Textfarbe, keine
     Fettschlacht (Design-Referenz, Typografie). */
  font-weight: 580;
  font-size: max(15px, var(--fs-lg));
  /* Ein Punktname, der umbricht, macht aus fuenfzig Zeilen achtzig. Abschneiden
     ist hier ehrlicher: der volle Name steht in der Tafel. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lm-zeile-ort {
  display: block;
  font-size: max(13px, var(--fs-sm));
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Die Faehnchen. Form und Ton wie .rg-art.stufe-angegeben in rundgang.css:
   gestrichelt, eckig, ruhig — eine Nebenangabe sieht aus wie eine
   Nebenangabe. Die Beweisstufe daneben bringt ihre eigene Form mit; sie ist
   die einzige Angabe der Zeile, die Fassung verdient. */
.lm-zeile-fahnen {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 3px;
}
.lm-zeile-fahne {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  padding: 2px 8px;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  white-space: nowrap;
}

/* Zustand und Zeit stehen uebereinander am rechten Rand, rechtsbuendig. Die
   Zahlen fluchten damit ueber alle Zeilen — man liest die Spalte hinunter
   statt jede Zeile einzeln. */
.lm-zeile-rechts {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  text-align: right;
}
.lm-zeile-zustand {
  font-size: max(13px, var(--fs-sm));
  color: var(--text-secondary);
}

/* Der Zeitbezug, den der Besitzer vermisst hat. "vor 12 Min." beantwortet die
   Frage, die man nachts wirklich hat — frisch oder von vorhin —, ohne dass
   jemand einen Zeitstempel im Kopf umrechnet. */
.lm-zeile-zeit {
  font-size: max(12px, var(--fs-xs));
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Punkte ohne Standort
   --------------------------------------------------------------------------- */

/* Sie verschwinden nicht, sie stehen daneben. Ein Kontrollpunkt, der aus der
   Ansicht faellt, weil niemand seine Lage erfasst hat, wird sonst vergessen –
   und genau der ist es, bei dem spaeter etwas passiert. Die Vorgabe steht so
   schon am Objektstandort in src/db.js:505-522 ("erscheint auf der Karte in
   einer eigenen Liste Standort fehlt") und gilt hier unveraendert. */
.lm-fehlend {
  padding: 11px 13px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.lm-fehlend h3 {
  margin: 0 0 8px;
  font-size: max(13px, var(--fs-sm));
  font-weight: 600;
  color: var(--text-muted);
}
.lm-fehlend ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.lm-fehlend-knopf {
  display: flex;
  flex-direction: column;
  gap: 1px;
  text-align: left;
  min-height: 44px;
  justify-content: center;
  padding: 6px 11px;
  font: inherit;
  font-size: max(14px, var(--fs-md));
  color: var(--text-primary);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
}
.lm-fehlend-knopf:focus-visible { outline: 2px solid var(--lm-fokus); outline-offset: 1px; }
.lm-fehlend-grund { font-size: max(12px, var(--fs-xs)); color: var(--text-muted); }

/* ---------------------------------------------------------------------------
   Einlesen
   --------------------------------------------------------------------------- */

/* Klebt unten: Einlesen muss erreichbar sein, ohne dass jemand mit einer Hand
   scrollt, waehrend die andere die Lampe haelt (rundgang.css:276-289). */
.lm-fuss {
  position: sticky;
  bottom: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--surface-1);
  border-top: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
}
.lm-fuss-reihe { display: flex; gap: 8px; }
.lm-fuss .btn { min-height: 52px; flex: 1; font-size: max(16px, var(--fs-xl)); }

/* Der Knopf wird GESPERRT, nicht versteckt – auch und gerade auf dem iPhone,
   wo Web NFC nicht existiert. Ein Knopf, der fehlt, laesst jemanden suchen; ein
   gesperrter Knopf mit Begruendung daneben beantwortet die Frage sofort. Das
   ist Grenze 2 des Auftrags, in Gestaltung uebersetzt: Der Rueckfallweg ist
   kein Nachtrag, er ist fuer die Haelfte der Geraete der Hauptweg – also steht
   er gleichberechtigt daneben und nicht darunter. */
.lm-nfc[disabled] { opacity: .55; cursor: not-allowed; }

.lm-warum {
  margin: 0;
  font-size: max(13px, var(--fs-sm));
  line-height: 1.5;
  color: var(--text-muted);
  text-align: center;
}

/* Waehrend das Geraet auf eine Marke wartet. Ein ruhiges Atmen, kein Blinken:
   Blinken zieht das Auge vom Tag weg, an den man das Telefon gerade haelt. */
.lm-nfc.ist-bereit {
  border-color: var(--accent);
  animation: lm-atmen 1.8s ease-in-out infinite;
}

@keyframes lm-atmen {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-soft); }
  50% { box-shadow: 0 0 0 6px var(--accent-soft); }
}

/* Kein Alarmton: Das ist ein Zustand, kein Fehler. Wer in der Tiefgarage
   steht, kann daran ohnehin nichts aendern – er soll es nur wissen. */
.lm-warten {
  margin: 0;
  text-align: center;
  font-size: max(13px, var(--fs-sm));
  color: var(--text-muted);
}

/* ---------------------------------------------------------------------------
   Zeichenerklaerung
   --------------------------------------------------------------------------- */

/* Zugeklappt und ganz unten, und das ist der Punkt: Beschriftet wird an der
   Marke und in der Zeile. Die Erklaerung ist eine Ergaenzung fuer den
   Buerotisch, kein Werkzeug fuer den Weg – wer sie nachts aufklappen muss, hat
   schon verloren. */
.lm-legende {
  font-size: max(13px, var(--fs-sm));
  color: var(--text-secondary);
}
.lm-legende > summary {
  cursor: pointer;
  color: var(--text-muted);
  padding: 11px 0;
}
.lm-legende ul {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
}
.lm-legende li { display: flex; align-items: center; gap: 7px; }

/* ---------------------------------------------------------------------------
   Leerer Zustand
   --------------------------------------------------------------------------- */

.lm-leer {
  text-align: center;
  padding: 32px 20px;
  color: var(--text-muted);
  font-size: max(14px, var(--fs-md));
  line-height: 1.55;
}

/* ---------------------------------------------------------------------------
   Handy
   --------------------------------------------------------------------------- */

@media screen and (max-width: 860px) {
  .lm { gap: 14px; }
  .lm-tafel { padding: 13px 14px; }

  .lm-flaeche {
    /* KORRIGIERT nach einer Aufnahme auf 430x900.
       58vh war zu viel: Die Flaeche reichte bis unter die klebende
       Fussleiste, und die Bedienknoepfe an ihrem unteren Rand lagen dann
       hinter "Einlesen" – der eine Knopf, der im Dienst zaehlt, verdeckte
       genau die Knoepfe, mit denen man den Ausschnitt sucht. 44vh laesst die
       Flaeche ueber der Fussleiste enden, und die Punktliste ist auf dem
       ersten Bildschirm schon angeschnitten sichtbar statt einen ganzen Wisch
       entfernt. */
    height: clamp(260px, 44vh, 400px);
  }

  /* Damit die letzte Zeile der Punktliste nicht unter der klebenden
     Fussleiste endet. Ohne das scrollt man ans Ende und der unterste Punkt
     ist der einzige, den man nicht antippen kann. */
  .lm { padding-bottom: 76px; }

  /* Die Navigationsleiste steht unten fest (styles.css:396). Ohne diesen
     Versatz laege die Fussleiste darunter und Einlesen waere genau der Knopf,
     den man nicht trifft. */
  .lm-fuss {
    bottom: calc(62px + env(safe-area-inset-bottom));
    border-radius: var(--radius);
  }

  /* Die Knoepfe wandern nach unten rechts: Dort erreicht sie der Daumen einer
     Hand, die gleichzeitig eine Lampe haelt – und dort verdecken sie den
     unteren Bildrand statt der Mitte, auf die man schaut. Massstab und
     Nordpfeil weichen dafuer nach oben aus, sonst liegen drei Dinge
     uebereinander. */
  /* KORRIGIERT: Der Massstab stand oben links und lag damit genau auf den
     Marken im oberen Bildteil – auf der Probeaufnahme verdeckte er den Punkt
     "Roessliwiese" halb. Er geht zurueck nach unten links, wo unter ihm nur
     Flaeche liegt; der Nordpfeil nimmt dafuer oben rechts Platz, die
     Bedienknoepfe bleiben unten rechts in Daumenreichweite. Drei Ecken, drei
     Dinge, keine Ueberlagerung. */
  .lm-steuerung { top: auto; bottom: 10px; right: 10px; }
  .lm-massstab { top: auto; bottom: 10px; left: 10px; }
  .lm-nord { bottom: auto; top: 10px; right: 10px; }

  .lm-tafel-reihe .btn { min-width: 120px; }

  /* Der Hilfeknopf steht auf dem Handy unten links (hilfe.css:392-396) und
     lag damit auf "Einlesen" – auf der Probeaufnahme verdeckte er dessen
     linke Haelfte. Beide sind richtig platziert, sie treffen sich nur auf
     dieser einen Ansicht.
     Darum weicht der Hilfeknopf hier aus und nicht die Fussleiste: Einlesen
     ist der Knopf, um den es im Dienst geht; die Hilfe braucht man, wenn man
     stehen bleibt. :has() statt einer Klasse am body, damit livemap.js dafuer
     nichts anfassen muss – die Regel gilt genau dann, wenn diese Ansicht
     offen ist, und sonst nie. */
  /* HIER STAND EINE EIGENE ZAHL, UND SIE IST WEG.
     150px war richtig, solange es die Leiste mit Licht und Notruf nicht gab.
     Danach war sie falsch - und weil in :has(#view-livemap) eine Kennung
     steckt, schlug sie jede spaetere Korrektur aus navigation.css. Wie hoch
     der Knopf sitzt, steht dort und nur dort. */
}

/* ---------------------------------------------------------------------------
   Weniger Bewegung
   --------------------------------------------------------------------------- */

/* styles.css:1579-1598 stellt bereits alle Uebergaenge und Laeufe ab. Zwei
   Dinge muessen hier trotzdem geregelt werden, weil sie sonst als tote Reste
   stehen bleiben. */
@media (prefers-reduced-motion: reduce) {
  /* Der Puls am eigenen Standort verschwindet, die Marke bleibt: Sie ist die
     Aussage, die Bewegung war nur der Hinweis darauf. */
  .lm-hier-hof { animation: none; opacity: .8; transform: none; }

  /* Der Druckring kann seinen Fortschritt nicht mehr zeigen – ein Ring, der
     in einer Millisekunde durchlaeuft, ist eine Luege ueber die verbleibende
     Zeit. Er wird darum sofort und vollstaendig gezeigt: "wird gehalten", ohne
     Aussage darueber, wie lange noch. Dass die Handlung trotzdem erreichbar
     bleibt, liegt nicht an dieser Regel, sondern am zweiten Knopf in der
     Tafel – siehe Entscheid 4 im Kopf dieser Datei. */
  .lm-marke.wird-gedrueckt .lm-druckring {
    animation: none;
    stroke-dashoffset: 0;
    opacity: 1;
  }

  .lm-nfc.ist-bereit { animation: none; box-shadow: 0 0 0 4px var(--accent-soft); }
}

/* ---------------------------------------------------------------------------
   Druck
   --------------------------------------------------------------------------- */

/* Auf Papier zaehlt die Uebersicht, nicht die Bedienung. Ein Ausdruck der
   Livemap ist der Zettel, den jemand ins Auto legt – er muss die Punkte und
   ihre Namen tragen, sonst nichts. */
@media print {
  .lm-dienste,
  .lm-steuerung,
  /* Der Weg zurueck ist ein Ausweg aus einer Bewegung. Auf Papier gibt es
     keine Bewegung und damit auch keinen Ausweg - und der Ring am Ziel
     zeigte auf einen Punkt, den der Ausdruck ohnehin schon zeigt. */
  .lm-zurueck,
  .lm-ziel,
  .lm-fuss,
  .lm-tafel-reihe,
  .lm-warten { display: none !important; }

  /* Helle Fassung erzwingen: Ein dunkler Ausdruck frisst Toner, und die
     Zustandsfarben – wegen derer die Ansicht da ist – verschwinden im Schwarz.
     Die Werte stehen hier nochmals, damit auch ein Ausdruck aus dem dunklen
     Erscheinungsbild hell wird. Es sind keine neuen Farben: Es sind die
     ausgerechneten Ergebnisse der -ink-Mischungen aus styles.css im hellen
     Erscheinungsbild (--good 62% auf Schwarz, --serious 56% auf Schwarz),
     hier fest hingeschrieben, weil color-mix in einem erzwungenen Druckblock
     sonst wieder am Erscheinungsbild haengt. */
  .lm {
    --lm-offen: #d03b3b;
    --lm-eingelesen: #076507;
    --lm-abweichung: #844932;
    --lm-unpruefbar: #8a6100;
    --lm-grund: #ffffff;
    --lm-raster: #d5d3cd;
    --lm-fassung: #ffffff;
  }

  .lm-flaeche {
    background: #ffffff;
    border-color: #7d8b9c;
    /* Ohne das lassen Browser beim Drucken die Flaechen weg – dann sind die
       Zustaende, wegen derer die Karte da ist, nicht mehr zu sehen. */
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* Auf Papier gibt es keinen Ablauf: Jeder Punkt steht sofort, und nichts
     reagiert auf einen Zeiger, den es dort nicht gibt. */
  .lm-hier-hof,
  .lm-druckring,
  .lm-nfc { animation: none !important; transition: none !important; }
  .lm-druckring { display: none; }

  /* Die beiden Randlisten bleiben: Ein Punkt ohne Standort und die Erklaerung
     der Zeichen gehoeren zur Aussage des Ausdrucks – und offen, nicht
     zugeklappt. */
  .lm-fehlend { background: #ffffff; border-color: #7d8b9c; }
  .lm-legende ul { display: flex; }

  .lm-tafel, .lm-zeile, .lm-fehlend { box-shadow: none; break-inside: avoid; }
}

/* ---------------------------------------------------------------------------
   Kartenbild
   --------------------------------------------------------------------------- */

/* Die Kacheln liegen ganz unten, unter Gitter, Punkten und Balken. Kein
   Uebergang und kein Aufblenden: Beim Ziehen wuerde jede Kachel einzeln
   einblenden, und die Karte flackerte unter der Hand. */
.lm-kachel {
  image-rendering: auto;
  pointer-events: none;
}

/* Im Dunkelmodus die amtliche Landeskarte daempfen. Sie ist fuer Papier
   gerechnet und leuchtet nachts wie ein Blatt Papier - genau dann, wenn
   jemand mit angepassten Augen im Dunkeln steht. Gedaempft und leicht
   entsaettigt bleibt sie lesbar, ohne zu blenden. Die Punkte darueber sind
   davon nicht betroffen, sie bleiben in voller Farbe. */
:root[data-theme="dark"] .lm-kachel {
  filter: brightness(.62) saturate(.72) contrast(1.06);
}

/* Herkunft der Karte. Pflicht bei swisstopo und ausserdem richtig: Wer eine
   Karte zeigt, sagt, woher sie kommt. */
/* Oben links, weil unten links der Massstab steht, unten rechts der
   Nordpfeil und oben rechts die Bedienknoepfe. Vier Ecken, vier Dinge - die
   Herkunft lag im ersten Anlauf auf dem Massstab. */
.lm-herkunft {
  position: absolute;
  left: 10px;
  top: 10px;
  z-index: 2;
  padding: 2px 7px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--surface-1) 82%, transparent);
  border: 1px solid var(--border);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  pointer-events: none;
}

/* Auf dem Handy steht oben rechts der Nordpfeil und unten links der
   Massstab. Oben links bleibt frei - die Herkunft kann bleiben, wo sie ist. */

/* ---------------------------------------------------------------------------
   Einrichten
   --------------------------------------------------------------------------- */

/* Die Meldung "Dienste und Kontrollpunkte legt die Leitung an" war eine
   Sackgasse: Wer sie liest, IST oft die Leitung und hatte trotzdem keinen
   Knopf. Der Weg steht darum hier, in derselben Ansicht - zugeklappt, sobald
   etwas da ist, und offen, solange nichts da ist. */
.lm-einrichten-block {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-1);
}
.lm-einrichten-kopf {
  padding: 11px 14px;
  min-height: 44px;
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--text-secondary);
  list-style: none;
}
.lm-einrichten-kopf::-webkit-details-marker { display: none; }
.lm-einrichten-kopf::before {
  content: '+';
  margin-right: 8px;
  font-weight: 700;
  color: var(--accent-fg);
}
.lm-einrichten-block[open] .lm-einrichten-kopf::before { content: '\2212'; }
.lm-einrichten-kopf:focus-visible { outline: 2px solid var(--accent-fg); outline-offset: -2px; }

.lm-einrichten-inhalt {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 14px 14px;
}
.lm-einrichten-hinweis {
  margin: 0;
  font-size: var(--fs-md);
  color: var(--text-secondary);
  line-height: 1.5;
}
.lm-einrichten-reihe {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
/* Das Feld nimmt den Platz, der Knopf nur seinen eigenen - und beide sind
   44px hoch, weil sie mit Handschuhen getroffen werden. */
.lm-einrichten-feld {
  flex: 1;
  min-width: 190px;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--surface-2);
  color: var(--text-primary);
  font-size: max(16px, var(--fs-lg));
}
.lm-einrichten-feld:focus-visible { outline: 2px solid var(--accent-fg); outline-offset: 1px; }
.lm-einrichten-reihe .btn { min-height: 44px; }

/* Der Stand sagt, was gerade passiert. Ohne ihn drueckt jemand zweimal, weil
   nichts zu sehen ist - und legt die Runde zweimal an. */
.lm-einrichten-stand {
  margin: 2px 0 0;
  min-height: 1.2em;
  font-size: var(--fs-md);
  color: var(--text-secondary);
}
.lm-einrichten-stand.ist-fehler { color: var(--critical-ink); font-weight: 600; }

/* ---------------------------------------------------------------------------
   Runden links neben der Flaeche
   --------------------------------------------------------------------------- */

/* Sven: "links neben der livemap die verschiedneen rundgaenge anzeigen."

   Auf dem Rechner eine Spalte, damit man Liste UND Karte gleichzeitig sieht,
   statt zwischen beiden zu wechseln. Auf dem Handy waagrecht ueber der
   Flaeche - dort ist fuer nebeneinander kein Platz, und eine 260px-Spalte auf
   430px Bildschirm laesst fuer die Karte nichts uebrig.

   Dieselbe Liste, dasselbe Markup. Nur dieses Stylesheet entscheidet. */
.lm-arbeitsflaeche {
  display: grid;
  gap: 14px;
  /* Vorgabe ist einspaltig: Was auf dem Handy laeuft, ist der Normalfall. */
  grid-template-columns: 1fr;
}

.lm-spalte { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

/* Die Ueberschrift steht nur auf dem Rechner. In der waagrechten Leiste waere
   sie ein Wort, das Platz kostet und nichts sagt. */
.lm-spalte-kopf { display: none; }

.lm-spalte-fuss {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  line-height: 1.5;
}

@media screen and (min-width: 861px) {
  .lm-arbeitsflaeche {
    /* 264px: breit genug fuer "OD1 Patrouille Kanton Zug" auf zwei Zeilen,
       schmal genug, dass die Karte die Hauptsache bleibt. */
    grid-template-columns: 264px minmax(0, 1fr);
    align-items: start;
  }

  .lm-spalte-kopf {
    display: block;
    margin: 0;
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--text-muted);
  }

  /* Aus der waagrechten Leiste wird eine senkrechte Liste. Sie scrollt fuer
     sich, wenn eine Firma zwanzig Runden hat - die Karte daneben bleibt
     stehen, wo sie ist. */
  .lm-dienste {
    flex-direction: column;
    flex-wrap: nowrap;
    overflow-x: visible;
    overflow-y: auto;
    max-height: 520px;
    padding-bottom: 0;
    padding-right: 4px;
  }
  .lm-dienst {
    width: 100%;
    flex: none;
  }
}

/* ---------------------------------------------------------------------------
   Lage nachtragen
   --------------------------------------------------------------------------- */

/* Sitzt in der Punkttafel und nicht im Objektblatt, weil hier die Luecke
   sichtbar wird: Wer einen Punkt antippt und keine Adresse sieht, will sie in
   diesem Moment nachtragen - nicht in einer anderen Ansicht, die er erst
   suchen muss.

   Fehlt die Lage, ist der Block OFFEN. Ist sie da, ist er zu: Dann ist es
   eine Aenderung und keine Aufgabe. */
.lm-lage {
  margin-top: 4px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-1);
}
.lm-lage-kopf {
  padding: 9px 12px;
  min-height: 44px;
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--text-secondary);
  list-style: none;
}
.lm-lage-kopf::-webkit-details-marker { display: none; }
.lm-lage-kopf::before { content: '\25B8'; margin-right: 7px; color: var(--accent-fg); }
.lm-lage[open] .lm-lage-kopf::before { content: '\25BE'; }
.lm-lage-kopf:focus-visible { outline: 2px solid var(--accent-fg); outline-offset: -2px; }

/* Ohne Lage traegt die Zeile den Ton des Offenen - sie ist eine Aufgabe,
   keine Einstellung. Nicht als Alarm, nur als Hinweis. */
.lm-lage:not([open]) .lm-lage-kopf { color: var(--text-secondary); }
.lm-lage[open] .lm-lage-kopf { color: var(--text-primary); }

.lm-lage-inhalt {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 12px 12px;
}

/* ---------------------------------------------------------------------------
   Zwei Nachbesserungen am Aussehen
   --------------------------------------------------------------------------- */

/* 1. Die Flaeche darf mehr Hoehe nehmen. Eine Karte, auf der zwanzig Punkte
      liegen, war bei 520px so gedraengt, dass die Namen uebereinander lagen.
      Auf dem Rechner ist Platz - eine Livemap, die den Bildschirm nicht
      nutzt, sieht aus wie ein Vorschaubild. */
@media screen and (min-width: 861px) {
  .lm-flaeche { height: clamp(460px, 64vh, 760px); }
  .lm-dienste { max-height: clamp(460px, 64vh, 760px); }

  /* Fuenfzig Punkte in einer einzigen Spalte sind auf einem 1360 Bildpunkte
     breiten Bildschirm eine Rolltreppe: Man scrollt an der Karte vorbei, bis
     man sie nicht mehr sieht — und verliert damit genau die Verbindung, die
     die Hervorhebung gerade hergestellt hat. Ab derselben Breite, ab der auch
     die Rundenliste neben die Karte rueckt, stehen die Punkte in Spalten.
     Die Lesefolge bleibt von links nach rechts, also stimmt die Numerierung
     weiter mit dem, was das Auge erwartet. */
  .lm-liste {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 6px;
  }
  .lm-liste .lm-zeile { margin-bottom: 0; }

  /* Die Karte darf breiter werden als die uebrigen Ansichten: Sie ist das
     Einzige im Haus, das von Flaeche wirklich profitiert. */
  .lm { max-width: 1360px; }
}

/* 2. Die klebende Fussleiste geht ueber die runden Knoepfe, nicht unter sie.
      Auf der Probeaufnahme lag der Notrufknopf mitten auf "Einlesen" - beides
      sind Knoepfe, die man im Ernstfall trifft, und ausgerechnet die duerfen
      sich nicht ueberlagern. 92px ist die Hoehe der Knopfreihe plus Luft. */
.lm-fuss { bottom: 92px; }
@media screen and (max-width: 860px) {
  /* Wie hoch die Fussleiste sitzt, steht in navigation.css und nur dort.
     Hier stand eine eigene Zahl – und sie war um vier Pixel falsch, sodass
     die Fussleiste in das Band von Hilfe und Plus-Knopf reichte. */
  /* Das Polster unten steht in navigation.css. */
}

/* DIE UMGRENZUNG um den gemeinten Kontrollpunkt.
 *
 * Eine Marke sagt "hier ist etwas", aber nicht, WIE WEIT das reicht - und auf
 * einem Luftbild voller Daecher findet das Auge einen einzelnen Punkt schlecht
 * wieder. Der Ring zieht eine sichtbare Grenze um die Stelle.
 *
 * ZWEI LINIEN UEBEREINANDER, und das ist der ganze Trick: Ein Luftbild hat
 * helle Daecher und dunkle Schatten dicht nebeneinander. Eine einzelne Linie
 * verschwindet immer auf der einen oder der anderen Flaeche. Die dunkle Fassung
 * darunter traegt die helle - zusammen sind sie auf JEDEM Untergrund lesbar.
 *
 * Der Ring behauptet ausdruecklich KEINE Grundstuecksgrenze: Die kennen wir
 * nicht. Darum ein Kreis mit dem Mass daneben und keine gezeichnete Parzelle. */
.lm-umgrenzung-schatten {
  fill: none;
  stroke: rgba(0, 0, 0, .55);
  stroke-width: 4;
  pointer-events: none;
}
.lm-umgrenzung-ring {
  fill: color-mix(in srgb, var(--accent) 8%, transparent);
  stroke: #fff;
  stroke-width: 1.6;
  /* Gestrichelt, damit die Linie nicht mit den festen Formen der Karte
     (Gebaeudekanten, Wege) verwechselt wird - eine gestrichelte Linie liest
     jeder als Hilfslinie, nicht als Sache. */
  stroke-dasharray: 7 5;
  pointer-events: none;
}
.lm-umgrenzung-mass {
  fill: #fff;
  font-size: 11px;
  font-weight: 500;
  paint-order: stroke;
  stroke: rgba(0, 0, 0, .6);
  stroke-width: 3;
  pointer-events: none;
}
/* Ohne Luftbild waere Weiss auf hellem Grund unsichtbar - dann traegt die
   Markenfarbe, und der Schatten wird zur hellen Kante.
   Die Bedingung haengt an der Kachelebene selbst (g.lm-kacheln entsteht nur,
   wenn wirklich Kacheln gezeichnet werden) - eine eigene Zustandsklasse waere
   eine zweite Wahrheit, die irgendwann nicht mehr stimmt. */
svg:not(:has(g.lm-kacheln)) .lm-umgrenzung-ring { stroke: var(--accent); }
svg:not(:has(g.lm-kacheln)) .lm-umgrenzung-schatten { stroke: rgba(255, 255, 255, .8); }
svg:not(:has(g.lm-kacheln)) .lm-umgrenzung-mass { fill: var(--accent); stroke: rgba(255, 255, 255, .85); }
@media print { .lm-umgrenzung-ring, .lm-umgrenzung-schatten, .lm-umgrenzung-mass { display: none; } }
