/* 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);
  border-left: 3px solid var(--accent);
  padding-left: 12px;
}
.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; }

@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);
}

/* ---------------------------------------------------------------------------
   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; }

.lm-zeile {
  border: 1px solid var(--border);
  border-left: 4px solid var(--border-strong);
  border-radius: 10px;
  margin-bottom: 8px;
  background: var(--surface-1);
}
.lm-zeile.ist-offen { border-left-color: var(--lm-offen); border-left-style: dashed; }
.lm-zeile.ist-eingelesen { border-left-color: var(--lm-eingelesen); }
.lm-zeile.ist-abweichung { border-left-color: var(--lm-abweichung); }
.lm-zeile.ist-unpruefbar { border-left-color: var(--lm-unpruefbar); }
.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. */
.lm-zeile-knopf {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  padding: 8px 12px;
  border-radius: 10px;
}
.lm-zeile-text { flex: 1; min-width: 0; }
.lm-zeile-name {
  display: block;
  font-weight: 600;
  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;
}
.lm-zeile-zustand {
  flex: none;
  font-size: max(13px, var(--fs-sm));
  color: var(--text-secondary);
}

/* ---------------------------------------------------------------------------
   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. */
  body:has(#view-livemap:not(.hidden)) .hilfe-knopf {
    bottom: calc(150px + env(safe-area-inset-bottom));
  }
}

/* ---------------------------------------------------------------------------
   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,
  .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. */
