/* Layout für bewertung.php (Monitoring Hohendeicher See) */
  :root { --teal:#1e40af; --teal-d:#193490;
          /* Hauptknopf (.btn-primary): dunkles Kobaltblau, eigene Variablen
             statt --teal, damit Menü-Hervorhebung, Fokusrahmen und Tabs ihr
             Blaugrün behalten. */
          --btn-primary:#1e40af; --btn-primary-d:#193490;
          /* Speichern-/Anlegen-Knöpfe (.btn-save): Frühlingsgrün. */
          --btn-save:#16a34a; --btn-save-d:#12863d;
          --slate:#0f172a; --muted:#64748b; --line:#e2e8f0; --bg:#f1f5f9; --red:#991b1b; --red-l:#fee2e2;
          /* --amber/--amber-l wurden von .setup-hint (hier) und .flash-warn
             (admin.css) benutzt, waren aber in KEINER der beiden Dateien
             definiert - die Kommentare in beiden Dateien verwiesen jeweils auf
             die andere. Eine ungültige var()-Referenz macht die ganze
             Deklaration ungültig; .flash-warn in admin.css bekam damit keinen
             gelben Hintergrund, sondern gar keinen. Werte übernommen aus den
             literalen Angaben, die an anderen Stellen dieser Datei stehen
             (.b-offen, .flash-warn weiter unten). */
          --amber:#92400e; --amber-l:#fef3c7; }
  * { box-sizing: border-box; }
  body { margin:0; font-family: system-ui, -apple-system, "Segoe UI", sans-serif; color:var(--slate); background:var(--bg);
         /* Waagerecht abschneiden, damit eine zu breite Tabelle nicht die
            ganze Seite verschiebbar macht.

            ABER: overflow-x:hidden macht das Element zu einem Scroll-Container
            - die andere Achse kann dann nicht mehr "visible" sein und wird zu
            "auto". Damit wird der <body> selbst scrollbar, obwohl gescrollt in
            Wirklichkeit das Fenster wird. Danach zielen scrollIntoView() und
            position:sticky im Zweifel auf den falschen Container; auf dem Handy
            faellt das eher auf als am Schreibtisch, weil dort zusaetzlich die
            Bildschirmtastatur die Viewport-Hoehe aendert.

            overflow-x:clip schneidet genauso ab, OHNE einen Scroll-Container
            anzulegen - genau das, was hier gemeint war. Die hidden-Zeile bleibt
            als Rueckfall fuer Safari unter 16 davor stehen; wo clip bekannt
            ist, ueberschreibt es sie. Reihenfolge also nicht tauschen. */
         overflow-x:hidden;
         overflow-x:clip; }
  /* Unten deutlich weniger Luft als früher (war 48px): Seinerzeit gab es den
     Footer nur auf messwerte.php, die 48px waren also auf allen anderen Seiten
     schlicht der Seitenabschluss. Seit Impressum/Datenschutz im Footer stehen,
     erscheint er auf JEDER Seite – 48px darunter wirken dann wie ein Loch.
     Der Abstand ÜBER dem Footer kommt nicht von hier, sondern aus dessen
     eigenem margin-top (siehe footer weiter unten). */
  .wrap { max-width: none; margin: 0; padding: 24px 20px 20px; }
  header { display:flex; align-items:center; gap:18px; margin-bottom:28px; }

  /* --- Sidebar-Navigation ------------------------------------------------
     Struktur und Aktiv-Zustände kommen aus menue.php (ein Datenbaum, ein
     Renderer). Die früheren Klassen .nav-group/.nav-label/.nav-indent und
     .sidebar nav a.active entfallen; neue Klassen sind bewusst deutsch
     benannt (.nav-punkt/.aktiv/.pfad), damit sie sich nicht mit dem
     bestehenden .active aus admin.css (.tab/.tab-panel) überschneiden. */
  .shell { display:flex; gap:24px; align-items:flex-start; }
  .sidebar {
    width:220px; flex-shrink:0; position:sticky; top:16px;
    background:#fff; border:1px solid var(--line); border-radius:12px;
    padding:14px 12px;
    /* Falls die Sidebar höher ist als das Fenster: eigener Scroll, sonst wäre
       der untere Teil bei kurzen Fenstern nicht erreichbar (sticky hält sie
       ja an top:16px fest). */
    max-height: calc(100vh - 32px);
    overflow-y: auto;
  }
  .main-content { flex:1; min-width:0; max-width:100%; }

  /* Umschalter für das Bereichsmenü: nur unter 900px sichtbar (siehe unten). */
  .nav-kopf  { display:none; }
  /* Baum: auf dem Desktop immer offen. */
  .nav-baum  { display:block; }

  .nav-punkt {
    display:flex; align-items:center; gap:8px;
    padding:9px 11px; border-radius:8px; font-size:14px; font-weight:600;
    color:#475569; text-decoration:none; margin-bottom:2px;
  }
  .nav-punkt:hover { background:var(--bg); color:var(--slate); }
  /* Blatt = aktuell geöffnete Seite: Teal plus linker Balken. Bei einseitigem
     Rand KEINE abgerundeten Ecken – sonst bricht die Ecke optisch auf. */
  .nav-punkt.aktiv {
    background:var(--bg); color:var(--btn-primary);
    border-left:2px solid var(--btn-primary); border-radius:0;
  }
  /* Pfad = Elternknoten des aktiven Blatts: Teal, aber ohne Balken. Sagt
     "du bist in diesem Ast", ist also Weg und nicht Ziel. */
  .nav-punkt.pfad { background:var(--bg); color:var(--btn-primary); }
  /* Feste Icon-Spalte, damit die Textkante je Zeile auf gleicher Höhe steht.
     Die Icons kommen aus dem Tabler-Sprite (svg/tabler.svg, menue_icon_html()
     in menue.php) und übernehmen die Textfarbe (currentColor). */
  .nav-icon  { flex:0 0 1.25em; display:inline-flex; align-items:center; justify-content:center;
               font-size:15px; line-height:1; }
  .ti        { width:1.2em; height:1.2em; flex:none; stroke-width:2; vertical-align:-0.22em; }
  /* Knöpfe, die nur ein Icon enthalten, bleiben so hoch wie Textknöpfe. */
  .btn > .ti:only-child { vertical-align:middle; }
  .chip-icon { display:inline-flex; vertical-align:-0.2em; margin-right:4px; }
  .nav-text  { min-width:0; }
  .nav-pfeil { margin-left:auto; font-size:10px; color:#94a3b8; }
  .nav-zaehler {
    margin-left:auto; font-size:11px; color:var(--muted);
    font-variant-numeric:tabular-nums;
  }
  /* Bernstein bleibt reserviert für "hier liegt Arbeit an" (Warteschlangen).
     Farben hier literal, weil --amber/--amber-l in admin.css stehen und die
     Sidebar auf allen Seiten gerendert wird. */
  .nav-zaehler-offen {
    background:#fef3c7; color:#b45309; font-weight:700;
    padding:1px 7px; border-radius:999px;
  }
  /* Zweites Badge direkt hinter dem ersten (nicht wieder ganz nach rechts). */
  .nav-zaehler + .nav-zaehler-zusatz { margin-left:4px; }
  /* Filterzeilen über Tabellen (Tabs Seen, Einstiege): Beschriftung und Feld als
     Paar nebeneinander, die Paare nebeneinander, solange Platz ist. Die globale
     Regel select{width:100%} würde jedes Feld auf eine eigene Zeile zwingen. */
  .filterzeile .filter-feld { display:inline-flex; align-items:center; gap:6px; max-width:100%; }
  .filterzeile .filter-feld > label { white-space:nowrap; }
  .filterzeile select { width:auto; max-width:260px; min-width:140px; }

  /* Unterpunkte: Führungslinie statt Einrückung per padding-left. Ersetzt
     .nav-indent (admin.php/links.php) und die inline-Paddings (kartieren.php). */
  .nav-unter { margin:2px 0 6px 19px; padding-left:11px; border-left:1px solid var(--line); }
  .nav-unter .nav-punkt       { font-size:13px; padding:6px 9px; }
  .nav-unter .nav-punkt.aktiv { margin-left:-12px; padding-left:19px; }
  .nav-unter .nav-unter       { margin-left:16px; padding-left:10px; }

  /* Konto-Block: abgesetzter Fuß der Sidebar (ersetzt .nutzer-info). */
  .nav-konto { margin-top:14px; padding-top:12px; border-top:1px solid var(--line); }
  .nav-konto .nav-punkt { font-size:13px; color:var(--muted); }
  .nav-nutzer { display:flex; align-items:center; gap:9px; padding:2px 10px 10px; }
  .nav-initialen {
    flex:none; width:26px; height:26px; border-radius:50%;
    background:var(--bg); color:#475569;
    display:flex; align-items:center; justify-content:center;
    font-size:11px; font-weight:700;
  }
  .nav-nutzer-text { min-width:0; line-height:1.3; }
  .nav-nutzer-text strong { display:block; font-size:13px; color:var(--slate); }
  .nav-rolle { font-size:11px; color:var(--muted); }

  /* Zustandsanzeige im Inhalt (z. B. "Bogen bearbeiten") – ersetzt die
     früheren Kontext-Links in der Sidebar, die keine Navigationsziele waren. */
  .kontext-pfad { font-size:12px; color:var(--muted); margin:0 0 12px; }

  /* --- Kontexthilfe (menue_hilfe_html() in menue.php, hilfe.php) -----------
     Aufklappbar über <details>/<summary>, ohne JavaScript. Der Block steht am
     Ende des Inhaltskopfs, also VOR dem Seiteninhalt - deshalb zugeklappt
     schlank und unauffällig: Er soll erreichbar sein, nicht die Seite
     anmoderieren.

     list-style/::marker: Die Standard-Dreiecke der Browser sehen je System
     anders aus; ein eigenes Zeichen mit fester Drehung ist einheitlich. Der
     Zustand kommt vom [open]-Attribut, das <details> selbst pflegt - kein
     JavaScript nötig. */
  .hilfe-block { margin: 0 0 16px; }
  /* display:inline-block und NICHT inline-flex: Flexbox auf einem <summary>
     setzen ältere Engines nicht um und stapeln Zeichen, Text und Pfeil
     untereinander. inline-block mit inline-Kindern fließt überall waagerecht.
     Aus demselben Grund der Abstand am ::after per margin statt per gap. */
  .hilfe-block > summary {
    display: inline-block; cursor: pointer;
    font-size: 13px; font-weight: 600; color: var(--btn-primary);
    padding: 5px 10px; border: 1px solid var(--line); border-radius: 8px;
    background: #fff; list-style: none;
  }
  /* Das Standard-Dreieck der Browser sieht je System anders aus - beide
     Schreibweisen abschalten (WebKit kennt nur die erste) und ein eigenes
     Zeichen setzen. Der Zustand kommt vom [open]-Attribut, das <details>
     selbst pflegt; kein JavaScript nötig. */
  .hilfe-block > summary::-webkit-details-marker { display: none; }
  .hilfe-block > summary::marker { content: ''; }
  .hilfe-block > summary::after { content: '▾'; font-size: .8em; margin-left: 6px; }
  .hilfe-block[open] > summary::after { content: '▴'; }
  .hilfe-block > summary:hover { background: var(--bg); }

  .hilfe-inhalt {
    margin: 10px 0 0; padding: 14px 16px; font-size: 14px; line-height: 1.65;
    background: #fff; border: 1px solid var(--line); border-radius: 10px;
    max-width: 80ch;   /* Lesbarkeit: lange Zeilen verliert das Auge */
  }
  /* Der Inhalt kommt aus einer HTML-Datei im Quelldaten-Verzeichnis und bringt
     eigene Überschriften, Listen und Tabellen mit. Die Regeln hier sind
     deshalb bewusst allgemein und auf .hilfe-inhalt begrenzt - so bleibt die
     Datei einfaches HTML, ohne dass wer sie schreibt Klassennamen kennen muss. */
  .hilfe-inhalt > :first-child { margin-top: 0; }
  .hilfe-inhalt > :last-child  { margin-bottom: 0; }
  .hilfe-inhalt h3 { font-size: 15px; margin: 18px 0 6px; }
  .hilfe-inhalt h4 { font-size: 14px; margin: 14px 0 4px; }
  .hilfe-inhalt p  { margin: 0 0 10px; }
  .hilfe-inhalt ul, .hilfe-inhalt ol { margin: 0 0 10px; padding-left: 22px; }
  .hilfe-inhalt li { margin: 0 0 4px; }
  .hilfe-inhalt code {
    background: var(--bg); border: 1px solid var(--line); border-radius: 4px;
    padding: 1px 5px; font-family: monospace; font-size: 12px;
  }
  .hilfe-inhalt a { color: var(--btn-primary); }
  .hilfe-inhalt table { border-collapse: collapse; font-size: 13px; margin: 0 0 10px; }
  .hilfe-inhalt th, .hilfe-inhalt td {
    text-align: left; padding: 4px 12px 4px 0; vertical-align: top;
  }

  /* Nur für Admins: fehlender Hilfetext (siehe menue_hilfe_html()). */
  .hilfe-fehlt {
    font-size: 12px; line-height: 1.6; color: var(--amber);
    background: var(--amber-l); border-radius: 8px;
    padding: 6px 10px; margin: 0 0 16px; max-width: 80ch;
  }
  .hilfe-fehlt code {
    background: #fef9c3; border-radius: 4px; padding: 1px 5px;
    font-family: monospace; font-size: 11px;
  }

  /* Themenübersicht auf hilfe.php: mehrspaltig, damit zwei Dutzend Themen
     nicht als endlose Liste dastehen. */
  .hilfe-inhaltsverzeichnis {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 2px 16px;
  }
  .hilfe-inhaltsverzeichnis a { font-size: 13px; padding: 3px 0; }

  /* Tab-Leiste (Ebene 2) und Chips (Ebene 3): nur mobil, siehe Media Query. */
  .tab-leiste, .chip-leiste { display:none; }

  @media (max-width: 900px) {
    .shell { display:block; }
    .sidebar {
      width:auto; position:static; max-height:none; overflow:visible;
      background:none; border:0; padding:0; margin-bottom:14px;
    }
    .nav-kopf {
      display:flex; align-items:center; gap:9px; width:100%;
      background:#fff; border:1px solid var(--line); border-radius:10px;
      padding:9px 11px; font:inherit; color:var(--slate);
      text-align:left; cursor:pointer;
    }
    .nav-kopf[aria-expanded="true"] { border-color:var(--btn-primary); border-radius:10px 10px 0 0; }
    .nav-kopf .nav-icon  { color:var(--btn-primary); font-size:17px; }
    .nav-kopf-text  { min-width:0; line-height:1.25; }
    .nav-kopf-label { display:block; font-size:10px; letter-spacing:.05em;
                      text-transform:uppercase; color:#94a3b8; }
    .nav-kopf-wert  { font-size:14px; font-weight:600; }

    .nav-baum {
      display:none; background:#fff;
      border:1px solid var(--btn-primary); border-top:0; border-radius:0 0 10px 10px;
      padding:8px;
    }
    .nav-baum.offen { display:block; }
    /* Touch-Ziele auf ~44px */
    .nav-punkt                  { padding:12px 11px; }
    .nav-unter .nav-punkt       { padding:10px 9px; }
    .nav-unter .nav-punkt.aktiv { padding-left:19px; }

    /* Ebene 2: eine Zeile, horizontal scrollbar. Umbruch würde die Höhe
       unvorhersehbar machen; der angeschnittene letzte Eintrag ist der
       Hinweis, dass rechts noch etwas kommt. */
    .tab-leiste {
      display:flex; gap:2px; overflow-x:auto; scrollbar-width:none;
      -webkit-overflow-scrolling:touch;
      background:#fff; border:1px solid var(--line); border-radius:10px;
      padding:0 4px; margin-bottom:12px;
    }
    .tab-leiste::-webkit-scrollbar { display:none; }
    .tab-leiste a {
      flex:none; white-space:nowrap; text-decoration:none;
      padding:11px 11px 9px; font-size:13px; font-weight:600;
      color:var(--muted); border-bottom:2px solid transparent;
    }
    .tab-leiste a.aktiv { color:var(--btn-primary); border-bottom-color:var(--btn-primary); }
    .tab-leiste .nav-zaehler { margin-left:5px; }

    /* Ebene 3: Statusfilter als Chips – im Inhalt, nicht in der Navigation. */
    .chip-leiste {
      display:flex; gap:6px; overflow-x:auto; scrollbar-width:none;
      margin-bottom:12px;
    }
    .chip-leiste::-webkit-scrollbar { display:none; }
    .chip-leiste a {
      flex:none; display:flex; align-items:center; gap:5px; white-space:nowrap;
      padding:6px 11px; border:1px solid var(--line); border-radius:999px;
      background:#f8fafc; color:var(--muted);
      font-size:12px; font-weight:600; text-decoration:none;
    }
    .chip-leiste a.aktiv { background:#fff; border-color:var(--btn-primary); color:var(--btn-primary); }
    .chip-leiste .nav-zaehler { margin-left:2px; }
  }
  .logo {
/*    width:108px; height:108px; border-radius:16px; background:#fff;*/
    width:110px; height:110px; 
/*    display:flex; align-items:center; justify-content:center; color:#fff;*/
    display:flex; align-items:center; justify-content:center;
    font-size:22px; overflow:hidden; flex-shrink:0;
/*    border:1px solid var(--line); box-shadow:0 1px 3px rgba(15,23,42,.08);*/
  }
  .logo img { width:100%; height:100%; object-fit:cover; display:block; }
  h1 { font-size:35px; line-height:1.2; margin:0; font-weight:700; letter-spacing:-.01em; }
  header h2 { font-size:25px; line-height:1.3; margin:2px 0 0; font-weight:600; color:var(--muted); }
  /* Testserver (Servername enthält "test", siehe ist_testserver() in lib.php und layout.php):
     rote Kennzeichnung hinter "Monitoring Seen" und Hinweis-Layer nach der Anmeldung. */
  header h2 .testserver-marke { color:#dc2626; font-weight:700; }
  .testserver-layer { position:fixed; inset:0; z-index:3000; display:flex; align-items:center; justify-content:center;
                      padding:16px; background:rgba(15,23,42,.6); }
  .testserver-layer-box { background:#fff; border-radius:12px; border-top:6px solid #dc2626; max-width:520px; width:100%;
                          padding:20px 22px; box-shadow:0 20px 60px rgba(0,0,0,.35); font-size:15px; line-height:1.55; }
  .testserver-layer-box h3 { margin:0 0 10px; color:#dc2626; font-size:20px; }
  .testserver-layer-box p { margin:0 0 10px; }
  .testserver-layer-box a { overflow-wrap:anywhere; }
  .testserver-layer-ok { margin-top:6px; }
  .sub { color:var(--muted); font-size:15px; font-weight:700; margin-top:4px; }
  @media (max-width: 520px) {
    header { gap:14px; }
    .logo { width:80px; height:80px; border-radius:14px; }
    h1 { font-size:22px; }
    header h2 { font-size:14px; }
    .sub { font-size:13px; }
  }
  .card { background:#fff; border:1px solid var(--line); border-radius:12px; padding:20px; margin-bottom:20px; max-width:100%; }

  /* Scroll-Container für breite Tabellen (z. B. Bögen mit vielen Spalten,
     Nutzerverwaltung): ohne Höhenbegrenzung sitzt der horizontale Scrollbalken
     ganz unten unter allen Zeilen und ist bei langen Tabellen erst nach viel
     Scrollen erreichbar. Mit max-height + eigenem Scroll bleibt er in der Nähe
     des sichtbaren Bereichs; die Kopfzeile bleibt dabei sticky oben stehen. */
  .tabelle-scroll { max-height:60vh; overflow:auto; }
  .tabelle-scroll thead th { position:sticky; top:0; z-index:1; }
  .card h2 { font-size:16px; margin:0 0 14px; }
  label { display:block; font-size:13px; font-weight:600; color:#334155; margin:0 0 4px; }
  select, input { width:100%; padding:8px 10px; font-size:14px; border:1px solid #cbd5e1; border-radius:8px; }
  /* textarea fehlte hier bislang komplett - jedes Mehrzeilenfeld brachte sein
     Aussehen als Inline-Style mit (kartieren.php: Teilflächen-Beschreibungen,
     "Sonstige Beobachtung", Gewässer-Beschreibung; jeweils dieselben fünf
     Angaben wie oben plus resize/font-family). Damit liess sich die
     Schriftgröße per Media Query nicht anfassen - genau das braucht der
     Handy-Abschnitt weiter unten aber (iOS zoomt bei Feldern unter 16px
     automatisch hinein). Deshalb wie bei den Ankreuzfeldern oben: Regel hier,
     Inline-Duplikate entfernt.
     resize:vertical - waagerechtes Ziehen würde bei width:100% das Layout
     sprengen; font-family:inherit, weil Browser für textarea sonst eine
     Monospace-Schrift wählen. */
  textarea {
    width:100%; padding:8px 10px; font-size:14px;
    border:1px solid #cbd5e1; border-radius:8px;
    resize:vertical; font-family:inherit;
  }
  textarea:focus { outline:none; border-color:var(--btn-primary); box-shadow:0 0 0 3px rgba(30,64,175,.15); }
  /* Ankreuzfelder und Radios aus der Regel darüber wieder herausnehmen. Die
     gilt für JEDES input - also auch für sie, und dann sind sie 100 % breit,
     haben 8 px Innenabstand und einen Rahmen. Sichtbare Folge: ein breites
     Kästchen, dessen Häkchen mittig darin sitzt, und eine Klickfläche, die
     weit über das Kästchen hinausreicht.
     Bisher wurde das an jeder Fundstelle einzeln geflickt - siehe
     .beob-modus-schalter input[type=radio] hier und .teil-bereich
     input[type=checkbox] in admin.css, dazu ein halbes Dutzend
     style="width:auto" im Markup. Diese Regel behebt die Ursache; die
     Einzelfixes bleiben wirkungslos daneben stehen und können bei Gelegenheit
     entfallen.
     box-shadow und outline bleiben unangetastet, damit der Fokusrahmen aus der
     Zeile darunter weiter sichtbar ist - Tastaturbedienung soll erkennbar
     bleiben. */
  input[type=checkbox], input[type=radio] {
    width:auto; padding:0; margin:0; border:0; border-radius:0;
  }
  select:focus, input:focus { outline:none; border-color:var(--btn-primary); box-shadow:0 0 0 3px rgba(30,64,175,.15); }

  /* -------------------------------------------------------------------------
     Mehrfachauswahl-Dropdown (z. B. Regionalgruppe: index.php, konto.php,
     admin.php) - ersetzt <select multiple>, das auf dem Handy (v. a. iOS
     Safari) kaum bedienbar ist. JS-Logik (Auf-/Zuklappen, Knopftext) liegt
     zentral in basis.js (dd-mehrfach()), rein über Event-Delegation auf
     document verdrahtet - siehe dortigen Funktionskopf für die Markup-
     Konvention. Ohne JavaScript bleibt das Panel offen und über die
     Checkboxen normal bedienbar (kein <noscript> nötig).
     ------------------------------------------------------------------------- */
  .dd-mehrfach { position:relative; }
  .dd-mehrfach-btn {
    width:100%; display:flex; align-items:center; justify-content:space-between;
    gap:8px; padding:9px 12px; font-size:14px; text-align:left; font-family:inherit;
    background:#fff; border:1px solid var(--line); border-radius:8px;
    cursor:pointer; color:var(--slate);
  }
  .dd-mehrfach-btn:focus-visible { outline:none; border-color:var(--btn-primary); box-shadow:0 0 0 3px rgba(30,64,175,.15); }
  .dd-mehrfach-pfeil { color:var(--muted); flex-shrink:0; transition:transform .15s; }
  .dd-mehrfach.offen .dd-mehrfach-pfeil { transform:rotate(180deg); }
  .dd-mehrfach-text.dd-mehrfach-platzhalter { color:var(--muted); }
  /* Panel ohne JS immer offen und im normalen Fluss (kein position:absolute) -
     erst .offen (von basis.js gesetzt) hebt es heraus und legt es über den
     nachfolgenden Inhalt. So bleibt die Mehrfachauswahl auch ohne
     JavaScript vollständig benutzbar. */
  .dd-mehrfach-panel {
    margin-top:6px; border:1px solid var(--line); border-radius:8px;
    padding:4px; max-height:260px; overflow-y:auto;
  }
  .dd-mehrfach.offen .dd-mehrfach-panel {
    position:absolute; left:0; right:0; top:calc(100% + 2px); z-index:5;
    background:#fff; box-shadow:0 8px 24px rgba(0,0,0,.12);
  }
  .dd-mehrfach-option {
    display:flex; align-items:center; gap:10px;
    padding:9px 8px; border-radius:6px; cursor:pointer; font-size:14px; font-weight:400;
  }
  .dd-mehrfach-option:hover { background:var(--bg); }

  .grid { display:grid; gap:12px; grid-template-columns: repeat(auto-fit, minmax(160px,1fr)); }
  .row { display:flex; flex-wrap:wrap; gap:10px; align-items:flex-end; }
  button, .btn { display:inline-flex; align-items:center; gap:6px; padding:9px 16px; font-size:14px; font-weight:600; border-radius:8px; border:1px solid transparent; cursor:pointer; text-decoration:none; line-height:1; }
  /* .btn-sm: verschoben aus admin.css, aus demselben Grund wie .btn-reject
     unten - kartieren.php, messwerte.php und links.php nutzen die Klasse
     ebenfalls (u. a. bei den Bearbeiten-Icons), laden admin.css aber nicht.
     Ohne diese Regel hier blieb "btn-sm" dort wirkungslos, und die Buttons
     fielen auf die volle Basisgröße von button/.btn oben zurück - deutlich
     größer als admin.php, wo admin.css die Regel bislang exklusiv lieferte. */
  .btn-sm { padding:5px 10px; font-size:12px; }
  .btn-primary { background:var(--btn-primary); color:#fff; } .btn-primary:hover { background:var(--btn-primary-d); }
  .btn-save { background:var(--btn-save); color:#fff; } .btn-save:hover { background:var(--btn-save-d); }
  .btn-ghost { background:#fff; color:#334155; border-color:#cbd5e1; } .btn-ghost:hover { background:#f8fafc; }
  /* Helles Grün für "anlegen/senden/wieder freigeben": verschoben aus
     admin.css (dort lag sie exklusiv) - kartieren.php lädt admin.css nur für
     Admins, bei allen anderen blieb z. B. "Jetzt senden" in "Meine Bögen"
     ungestylt. Farben als Werte statt var(--green…), weil diese Variablen nur
     in admin.css definiert sind. */
  .btn-approve { background:#dcfce7; color:#166534; border-color:#bbf7d0; }
  .btn-approve:hover { background:#bbf7d0; }
  /* „＋ Neu … anlegen“ über den Tabellen: helles Taubenblau */
  .btn-neu { background:#e0e7ff; color:#3730a3; border-color:#c7d2fe; }
  .btn-neu:hover { background:#c7d2fe; }
  /* Löschen-Pille: verschoben aus admin.css, weil sie inzwischen auch außerhalb
     des Moderationsbereichs gebraucht wird (links.php, kartieren.php) - beide
     laden admin.css nicht. Einheitliche Optik für JEDE endgültige Löschaktion
     im Projekt (siehe jeweilige Fundstellen: admin.php, konto.php, links.php,
     kartieren.php). admin.css definiert sie deshalb nicht mehr selbst. */
  .btn-reject { background:var(--red-l); color:var(--red); border-color:#fecaca; }
  .btn-reject:hover { background:#fecaca; }
  /* "Fertig zurück" neben der Bogen-Pfadkarte: wechselt von Weiß auf Grün,
     sobald der Marker für ein neues Gewässer gesetzt ist (siehe
     fertigZurueckKnopfAktualisieren() in bogen.js). Dieselbe Grüntönung wie
     --sp-ok (Statuspunkt "freigegeben" weiter unten), damit "erledigt/gesetzt"
     überall im Bogenformular dieselbe Farbe trägt. */
  .btn-ghost.btn-position-gesetzt { background:#16a34a; border-color:#16a34a; color:#fff; }
  .btn-ghost.btn-position-gesetzt:hover { background:#15803d; }

  /* --- Cookie-Hinweis (layout_template.html) ---------------------------------
     Sichtbarkeit haengt am hidden-Attribut im Markup. Wichtig: display steht
     NUR unter :not([hidden]) – eine Regel wie ".cookie-banner{display:flex}"
     wuerde das hidden-Attribut aushebeln, weil das browsereigene
     "[hidden]{display:none}" aus dem UA-Stylesheet von jeder Autor-Regel
     ueberschrieben wird, unabhaengig von der Spezifitaet. Das Banner waere
     dann dauerhaft sichtbar. */
  .cookie-banner:not([hidden]) {
    display:flex; flex-wrap:wrap; align-items:center; gap:12px;
    position:fixed; left:0; right:0; bottom:0; z-index:900;
    padding:14px 20px;
    background:#fff; border-top:1px solid var(--line);
    box-shadow:0 -2px 12px rgba(15,23,42,.10);
    font-size:13px; line-height:1.5; color:var(--slate);
  }
  .cookie-banner-text { flex:1 1 260px; min-width:0; }
  .cookie-banner-text a { color:var(--btn-primary); }
  .cookie-banner #cookie-ok { flex:0 0 auto; white-space:nowrap; }
  /* Schmale Bildschirme: Button auf ganze Breite unter den Text. */
  @media (max-width:520px) {
    .cookie-banner #cookie-ok { width:100%; justify-content:center; }
  }
  table { width:100%; border-collapse:collapse; font-size:14px; }
  th, td { text-align:left; padding:9px 10px; border-top:1px solid var(--line); }
  th a { color:#475569; text-decoration:none; } th a:hover { color:var(--slate); }
  thead th { border-top:none; background:#f8fafc; font-size:12px; text-transform:uppercase; letter-spacing:.03em; color:#64748b; }
  .num { text-align:right; font-variant-numeric: tabular-nums; }
  .badge { display:inline-block; padding:2px 8px; border-radius:999px; font-size:12px; font-weight:600; }
  .b-frei { background:#dcfce7; color:#166534; } .b-offen { background:#fef3c7; color:#92400e; }
  /* Eigene offene Einstiege in "Bestehende Einstiege / Messstellen" (kartieren.php): Zeile in der
     Farbe des Status "Offen" (.b-offen). Auf den Zellen statt auf der tr, damit der Ton auch hinter
     klebenden/eingefärbten Zellen ankommt. */
  /* Nutzer in Klammern unter dem Status-Badge (stammdaten_status_zelle_html(), Tabelle "Bestehende Seen"). */
  .sd-nutzer { margin-top:3px; font-size:12px; color:var(--muted); white-space:nowrap; }
  #ms-tabelle tr.ms-zeile-eigen-offen > td,
  #gew-tabelle tr.gew-zeile-eigen-offen > td { background:#fef3c7; }
  /* Dasselbe für eigene offene Bögen in "Meine Bögen" - Farbe wie die Status-Pille "offen"
     dort ($statusFarbe['offen'] in kartieren.php). */
  #meine-boegen-tabelle tr.meine-zeile-eigen-offen > td { background:#fef9c3; }
  .b-neu { background:#e0e7ff; color:#3730a3; }   /* wie .btn-neu */
  /* Zwei Endzustände, beide rot: 'abgelehnt' heißt "war nie freigegeben"
     (Zurückweisung), 'deaktiviert' heißt "war freigegeben, wurde
     zurückgezogen" (Verwaltungshandlung) - unterschiedliche Ursachen, aber
     beide zeigen an, dass der Eintrag gerade NICHT aktiv/sichtbar ist, daher
     dieselbe Warnfarbe statt eines eigenen neutralen Grautons. */
  .b-abgelehnt   { background:var(--red-l); color:var(--red); }
  .b-deaktiviert { background:var(--red-l); color:var(--red); }
  .pill { font-size:12px; color:var(--muted); }
  .flash { padding:10px 14px; border-radius:8px; font-size:14px; margin-bottom:16px; }
  .flash-ok { background:#dcfce7; color:#166534; } .flash-err { background:#fee2e2; color:#991b1b; }
  .flash-warn { background:#fef3c7; color:#92400e; }
  /* .setup-hint: fehlte bisher komplett (siehe Kommentar im Dateikopf oben) -
     admin.css und diese Datei verwiesen jeweils nur aufeinander, ohne dass
     eine von beiden die Regel tatsächlich enthielt. Dieselbe Amber-Farbgebung
     wie .flash-warn (informativer Hinweis, keine Fehlermeldung), aber als
     eigener Kasten mit Rahmen statt einer reinen Flash-Zeile, weil der Inhalt
     hier mehrzeiliger Fließtext ist (siehe konto.php) und nicht nur eine
     kurze Statusmeldung. margin-bottom wie .flash, damit auf mehrere direkt
     aufeinanderfolgende Boxen kein Sonderfall nötig ist - einzelne
     Aufrufstellen setzen es bei Bedarf mit Inline-Style auf 0 zurück (siehe
     konto.php, letzte Box vor Formularende). */
  .setup-hint {
    background:var(--amber-l); color:var(--amber); border:1px solid #fde68a;
    border-radius:8px; padding:12px 14px; font-size:13px; line-height:1.5;
    margin-bottom:16px;
  }
  .stat-row { display:flex; justify-content:space-between; align-items:center; font-size:12px; padding:4px 0; color:var(--muted); }
  .stat-row strong { color:var(--slate); font-size:15px; }
  /* Der Footer ist eine eigene Fläche im gleichen Stil wie .sidebar und .card
     (weiß, 1px Rahmen in --line, Radius 12px) – so liest er sich als Bereich
     und nicht als loser Text unter der Seite. Er steht im Template innerhalb
     von .main-content und ist damit links und rechts bündig zum Anzeigebereich.
     margin-top:20px statt der früheren 8px: Der Footer ist jetzt ein normales
     Geschwister der letzten .card im selben Fluss, dadurch KOLLABIEREN die
     beiden Abstände (früher, als Geschwister von .shell, addierten sie sich,
     weil .main-content ein Flex-Item ist). Wirksam sind also 20px – derselbe
     Abstand, den auch zwei Karten untereinander haben. Der Wert steht hier
     trotzdem explizit, damit es auch dann stimmt, wenn das letzte Element im
     Inhalt gar kein margin-bottom hat. */
  footer {
    background:#fff; border:1px solid var(--line); border-radius:12px;
    padding:12px 16px; margin-top:20px;
    color:var(--muted); font-size:12px; line-height:1.6;
  }
  /* Links erben die gedämpfte Footer-Farbe (kein Teal wie sonst): Impressum
     und Datenschutz sind Pflichtangaben, keine Handlungsaufforderung – sie
     sollen auffindbar sein, ohne den Blick zu ziehen. Unterstrichen bleiben
     sie trotzdem, damit sie als Links erkennbar sind. */
  footer a { color:inherit; text-decoration:underline; }
  footer a:hover { color:var(--slate); }
  /* Trennzeichen zwischen den Links etwas Luft geben. */
  .footer-trenner { padding:0 6px; }
  /* Beobachtungsgruppen-Eingabe (Tab „Bogen erfassen"): eine Tabelle je Gruppe,
     Zeilen = Arten, Spalten = Teilflächen (+ "Gesamt") – analog zur Anzeige
     (.gruppe-block weiter unten). overflow-x:auto wie dort, aus demselben Grund
     (bis zu 10 Teilflächen-Spalten + "Gesamt"). Aufgebaut von bogen.js
     (beobGruppenAufbauen()). */
  .beob-tabelle-wrap { overflow-x:auto; }
  /* KEIN min-width:max-content (mehr): Damit war die Tabelle immer mindestens
     so breit wie die Summe aller Spalteninhalte in voller Laenge - ein Umbruch
     wurde also nie noetig, und die Namensspalten konnten nur ueber harte
     Breitenvorgaben klein gehalten werden, was den Umbruch wiederum erzwang,
     auch wenn Platz da war.

     Jetzt fuellt die Tabelle die Breite (width:100%) und schrumpft bei Bedarf:
     Reicht der Platz, stehen die Namen einzeilig; wird es eng (schmales Fenster,
     viele Teilflaechen-Spalten), weichen zuerst die Namensspalten und brechen um.
     Erst wenn selbst das nicht reicht - die Mengenfelder haben min-width:56px,
     darunter geht es nicht -, laeuft die Tabelle ueber und .beob-tabelle-wrap
     scrollt wie bisher waagerecht. */
  .beob-tabelle { width:100%; border-collapse:collapse; font-size:13px; }
  /* Alle Spalten AUSSER den beiden Namensspalten so schmal wie ihr Inhalt
     (width:1% heisst in der automatischen Tabellenberechnung "so schmal wie
     moeglich"). Ohne das bekaemen sie den freien Platz anteilig mit ab - genau
     das liess die Mengenspalten breit werden, waehrend die Namen daneben
     umbrachen. Zellen mit colspan sind ausgenommen (Kopfzeile "Teilflaeche",
     Synonym-Hinweiszeile): eine Breitenangabe an ihnen wuerde sich auf mehrere
     Spalten gleichzeitig beziehen und nichts Sinnvolles bewirken. */
  .beob-tabelle th:not(.sp-art):not([colspan]),
  .beob-tabelle td:not(.sp-art):not([colspan]) { width:1%; }
  .beob-tabelle th, .beob-tabelle td { padding:5px 8px; border-top:none; border-bottom:1px solid rgba(0,0,0,.08); text-align:center; }
  .beob-tabelle td:first-child { text-align:left; }
  /* Art-Kopfzelle: eigene Klasse statt :first-child, weil bei mehreren
     Teilflächen die zweite Kopfzeile (nur Nummern) selbst kein Art-<th> mehr
     hat (rowspan) – ihr jeweils erstes <th> ist dann schon "Teilfläche 1". */
  .beob-tabelle th.sp-art { text-align:left; }
  /* Wissenschaftlicher Name (zweite Art-Spalte, siehe beobGruppenAufbauen() in
     bogen.js): ebenfalls linksbündig, analog zur Artenliste (Tab "Arten") -
     :first-child greift hier nicht, da die Trivialname-Spalte davor steht.
     "–" bei fehlendem wissenschaftlichen Namen wird wie dort abgeblendet. */
  .beob-tabelle td.sp-art-wiss { text-align:left; }
  .beob-tabelle .sp-art-wiss-leer { color:var(--muted); }
  /* Artnamen duerfen umbrechen - aber nur, wenn der Platz wirklich nicht reicht.
     Zwei Dinge gehoeren dazu:

     1. Die Tabelle darf schrumpfen (kein min-width:max-content mehr, siehe die
        Begruendung oben). Nur dann entsteht ueberhaupt je eine Lage, in der ein
        Umbruch noetig ist.
     2. Der Name muss die Zellbreite ausnutzen duerfen: display:block statt
        eines in der Breite begrenzten inline-block. Eine max-width am Namen
        selbst waere falsch - sie bricht den Text auch dann um, wenn die Spalte
        breiter ist.

     Die beiden Namensspalten sind die einzigen ohne Breitenangabe (alle anderen
     stehen auf width:1%, siehe oben) und bekommen damit den gesamten freien
     Platz. min-width haelt sie bei sehr vielen Spalten noch lesbar, statt sie
     auf die Breite des laengsten Wortes zusammenfallen zu lassen.

     overflow-wrap:break-word als Notnagel fuer einzelne Woerter, die laenger
     sind als die Spalte - ohne das ragte so ein Wort heraus. */
  .beob-tabelle th.sp-art, .beob-tabelle td.sp-art { min-width:12ch; }
  .beob-tabelle .sp-art-text {
    display:block; white-space:normal; overflow-wrap:break-word;
  }
  /* LakeExplorer-Spalte: Die Datenzellen enthalten nur ein Zeichen (Pfeil bzw.
     "-"), die Breite bestimmt allein der Kopftext. Die width:1%-Regel oben
     greift hier bereits; das weiche Trennzeichen im Kopf (siehe
     beobGruppenAufbauen() in bogen.js) sorgt dafuer, dass der Mindestinhalt
     dieser Spalte nur "Explorer" ist statt des ganzen Wortes - der Kopf wird
     dann zweizeilig ("Lake-" / "Explorer") statt die Spalte breit zu halten.
     Die Klasse bleibt als benannter Anker fuer diese Spalte bestehen. */
  .beob-tabelle th.sp-art .sort-th {
    white-space:normal; overflow-wrap:break-word;
    /* Sortierpfeil oben halten, wenn die Beschriftung zweizeilig wird - sonst
       sitzt er auf halber Hoehe neben dem Text. */
    align-items:flex-start;
  }
  /* Gemeinsame "Teilfläche"-Kopfzeile über den Teilflächen-Spalten (Zeile 1 von
     2): keine Trennlinie zur Nummern-Zeile darunter, die zusammengehören. */
  .beob-tabelle th.sp-tf-oben { border-bottom:none; }
  .beob-tabelle thead th { background:transparent; border-bottom:1px solid rgba(0,0,0,.15); }
  /* Zeilenfarben in Desktop UND Handyansicht gleich: Zeilen sind weiß; nur
     Zeilen mit .beob-zeile-ohne-rand (siehe bogen.js, 'arten_ohne_rand') und
     der Tabellenkopf erben den Farbton der Gruppen-Box. Dafür reichen Wrap,
     Tabelle und tbody die Farbe durch (inherit). :where() hält die Spezifität
     bei 0, damit tr.indikator-* die Grundfarbe weiterhin überstimmt. */
  :where(.beob-tabelle) tr { background-color:#fff; }
  .beob-gruppe .beob-tabelle-wrap, .beob-gruppe .beob-tabelle,
  .beob-gruppe .beob-tabelle tbody { background-color:inherit; }
  .beob-tabelle tr.beob-zeile-ohne-rand { background-color:inherit; }
  .beob-gruppe .beob-tabelle thead, .beob-gruppe .beob-tabelle thead tr { background-color:inherit; }
  /* Mengen-Auswahlfeld so schmal wie noetig. width:auto statt der frueheren
     100%: Mit 100% zog sich das Feld ueber die ganze Zelle und nahm damit jeden
     Platz mit, den die Tabelle bei wenigen Spalten uebrig hat - die Namen
     daneben blieben schmal und brachen um, waehrend hier Leerraum stand.
     max-width:100% verhindert, dass ein Feld mit langen Beschriftungen (die
     Klartext-Stufen des LRT 3140b, siehe $skala_3140b in config.php) aus der
     Zelle laeuft; min-width haelt es auch bei kurzen Stufen (r, +, 1-5) noch
     gut treffbar. Die Zelle ist zentriert (siehe .beob-tabelle td oben), das
     Feld sitzt also mittig statt am linken Rand zu kleben. */
  .beob-tabelle .menge-sel { width:auto; min-width:56px; max-width:100%;
                              padding:4px 6px; font-size:13px; }
  /* Freitext-Zeile (zusätzliche, frei benannte Art): Artname-Zelle enthält
     Texteingabe + Entfernen-Button nebeneinander. */
  .beob-tabelle td.frei-art-zelle { display:flex; align-items:center; gap:6px; }
  .beob-tabelle .frei-art-zelle input { flex:1; min-width:100px; padding:6px 8px; font-size:13px; }
  /* Zweite Freitext-Zelle "Wissenschaftlicher Name": eigenes Eingabefeld statt
     der frueheren leeren Platzhalterzelle (siehe freitextZeileBauen() in
     bogen.js). Kursiv wie bei den bekannten Arten (<em> in sp-art-wiss dort),
     damit beide Zeilenarten optisch gleich wirken - hier per font-style direkt
     am Eingabefeld, weil ein <em> um ein <input> nichts bewirken wuerde. */
  .beob-tabelle td.frei-art-wiss-zelle { text-align:left; }
  .beob-tabelle .frei-art-wiss-zelle input { width:100%; min-width:100px; padding:6px 8px;
                                              font-size:13px; font-style:italic; }
  .beob-tabelle .frei-art-wiss-zelle input::placeholder { font-style:normal; }
  /* Synonym-Hinweis: eigene Zeile mit einer Zelle über alle Spalten (colspan
     setzt freitextZeileBauen() in bogen.js). Vorher stand der Satz in der
     Artzelle und drückte die Spalte "Art (Trivialname)" auseinander - eine
     Tabellenspalte richtet sich nach ihrem breitesten Inhalt, und das war dann
     der Hinweis statt der Artnamen.

     Bewusst in der Hinweisfarbe (Teal) und nicht in Rot: Der Eintrag ist
     richtig, die Art heißt in der Artenliste nur anders - eine Warnfarbe ließe
     den Nutzer nach einem Fehler suchen, den es nicht gibt.

     Die Sichtbarkeit steuert allein das hidden-Attribut an der <tr>, kein
     Inline-display - so können sich "verbergen" und "als Tabellenzeile
     anzeigen" nicht widersprechen (dieselbe Überlegung wie beim
     Cookie-Banner). Die eigene display:none-Regel ist nötig, weil hidden bei
     <tr> in manchen Browsern von der Tabellendarstellung überstimmt wird. */
  .beob-tabelle tr.beob-zeile-frei-hinweis[hidden] { display:none; }
  .beob-tabelle tr.beob-zeile-frei-hinweis > td { padding:0 0 6px; border-top:none; }
  .beob-tabelle .frei-art-hinweis {
    display:block; font-size:12px; line-height:1.45; color:var(--btn-primary);
    background:#f0fdfa; border:1px solid #99f6e4; border-radius:6px;
    padding:4px 8px;
  }
  .beob-tabelle .btn-rm { flex:0 0 auto; padding:6px 10px; font-size:16px; line-height:1;
                           background:#fff; border:1px solid #cbd5e1; border-radius:8px;
                           cursor:pointer; color:var(--muted); }
  .beob-tabelle .btn-rm:hover { background:var(--red-l); color:var(--red); border-color:#fecaca; }

  /* Spalte „Indikatorgruppe" und Zeilenfarbe (nur Makrophyten bei TKg10/TKg13,
     Gruppen mit hat_tiefenbereich=true): zeigt je Art/Tiefenbereich-Zeile die
     Einstufung A++/A/B/C aus der Tabelle arten (siehe
     arten_tkg_tiefenbereiche() in db.php); die Klasse setzt bogen.js
     (indikatorKlasse() in beobGruppenAufbauen()).

     Die Farbe liegt auf der ganzen <tr>, nicht nur auf der Zelle – so ist auf
     einen Blick erkennbar, wie eine Art in dieser Tiefe eingestuft ist, ohne
     erst die Spalte lesen zu müssen. Bewusst NICHT unter .beob-tabelle
     verschachtelt: dieselben Klassen färben auch die Farblegende in der Karte
     „Häufigkeits-/Deckungsskala" (kartieren.php), die eine eigene, einfache
     Tabelle ist. Zeilen ohne Einstufung (z. B. Freitext-Arten) bekommen gar
     keine dieser Klassen und bleiben ungefärbt.

     A++ und A sind beide grün (fachlich beides Referenzarten), A++ kräftiger –
     der Unterschied muss sichtbar sein, ohne die Verwandtschaft zu verwischen.
     Textfarbe bleibt überall die normale, dunkle Schrift: die Flächen sind hell
     genug, ein Farbwechsel des Textes würde nur den Kontrast verschlechtern. */
  tr.indikator-app { background:#4ade80; }
  tr.indikator-a   { background:#bbf7d0; }
  tr.indikator-b   { background:#fde047; }
  tr.indikator-c   { background:#fca5a5; }
  .beob-tabelle td.sp-indikatorgruppe { font-weight:700; }

  /* Moduswahl "Alle möglichen Arten" / "Nur ausgewählte Arten" (Tab „Bogen
     erfassen", oberhalb der Beobachtungsgruppen-Tabellen). */
  .beob-modus-schalter {
    display:flex; flex-wrap:wrap; gap:6px 18px; align-items:center;
    margin-bottom:14px; font-size:13px;
  }
  .beob-modus-schalter strong { font-size:13px; }
  .beob-modus-schalter label {
    display:inline-flex; align-items:center; gap:6px;
    font-weight:400; font-size:13px; margin:0; cursor:pointer;
  }
  .beob-modus-schalter input[type=radio] { width:auto; margin:0; }

  /* "+ weitere Art"-Auswahlliste im Kompakt-Modus: optisch wie der
     Freitext-Button (.btn-add-zeile) darüber/daneben, nur als <select>. */
  .btn-add-zeile-waehler {
    margin-top: 6px;
    font-size: 12px;
    padding: 6px 10px;
    width: auto;
    background: rgba(255,255,255,.7);
    border: 1px solid transparent;
    border-radius: 8px;
    cursor: pointer;
  }
  .btn-add-zeile-waehler:hover { background:#fff; }
  /* Doppelter Zeitbereich-Schieberegler */
  .range-wrap { position:relative; padding: 8px 0 28px; margin-top:4px; }
  .range-wrap input[type=range] {
    position:absolute; left:0; width:100%;
    -webkit-appearance:none; appearance:none;
    height:4px; background:transparent; pointer-events:none;
    outline:none; margin:0;
  }
  .range-wrap input[type=range]::-webkit-slider-thumb {
    -webkit-appearance:none; appearance:none;
    width:18px; height:18px; border-radius:50%;
    background:var(--btn-primary); border:2px solid #fff;
    box-shadow:0 1px 4px rgba(0,0,0,.25);
    cursor:pointer; pointer-events:all;
    position:relative; z-index:2;
  }
  .range-wrap input[type=range]::-moz-range-thumb {
    width:18px; height:18px; border-radius:50%;
    background:var(--btn-primary); border:2px solid #fff;
    box-shadow:0 1px 4px rgba(0,0,0,.25);
    cursor:pointer; pointer-events:all;
  }
  .range-track {
    position:absolute; top:15px; left:0; right:0;
    height:4px; background:var(--line); border-radius:2px;
  }
  .range-fill {
    position:absolute; top:0; height:4px;
    background:var(--btn-primary); border-radius:2px;
  }
  .range-labels {
    position:absolute; bottom:0; left:0; right:0;
    display:flex; justify-content:space-between;
    font-size:12px; color:var(--muted);
  }
  .range-label-von, .range-label-bis {
    background:#fff; padding:0 3px; border-radius:3px;
    font-weight:600; color:var(--btn-primary);
  }
  .toolbar { display:flex; flex-wrap:wrap; gap:10px; align-items:flex-end; margin-bottom:16px; }
  .toolbar .grow { flex:1; }

  /* Tabs */
  .tabs-nav {
    display:flex; gap:0; margin-bottom:24px;
    border-bottom:2px solid var(--line);
  }
  .tab-btn {
    padding:10px 24px; font-size:14px; font-weight:600;
    color:var(--muted); background:none; border:none;
    border-bottom:3px solid transparent; margin-bottom:-2px;
    cursor:pointer; text-decoration:none; display:inline-block;
    transition:color .15s;
  }
  .tab-btn:hover { color:var(--slate); }
  .tab-btn.active { color:var(--btn-primary); border-bottom-color:var(--btn-primary); }
  .tab-panel { display:none; }
  .tab-panel.active { display:block; }

/* Gruppenfarben (ausgelagert aus config.php beobachtungsgruppen) */
.gruppe-block, .beob-gruppe { background: #f8fafc; }
.gruppe-grundrasen    { background: #dcfce7; }  /* hellgrün */
.gruppe-lrt_art       { background: #e0f2fe; }  /* hellblau */
.gruppe-eutrophierung { background: #ffaaaa; }  /* hellorange */
.gruppe-weitere_arten { background: #ffffcc; }  /* hellgelb */
.gruppe-tiere         { background: #ffffff; }  /* weiß */
.gruppe-uferbewuchs   { background: #ffffff; }  /* weiß, wie Tiere */
.gruppe-GR            { background: #6dd900; }  /* GR, 3150 */
.gruppe-TF            { background: #ccccff; }  /* TF, 3150 */
.gruppe-SD            { background: #ffff00; }  /* SD, 3150 */
.gruppe-SR            { background: #ffffcc; }  /* SR, 3150 */
.gruppe-SM            { background: #ff99fd; }  /* SM, 3150 */
.gruppe-hypertrophierung_3150 { background: #d38b8b; }  /* hellrot, hypertrophierung, 3150 */


/* Beobachtungsgruppen-Box im Eingabeformular (Bewertungsbogen).
   Einzige Quelle für dieses Aussehen – wird sowohl von bewertung.php (PHP-Template,
   Erstaufbau) als auch vom JS in beobGruppenAufbauen() (Neuaufbau bei Änderung
   der Teilflächen-Anzahl) per Klasse referenziert, damit beide Varianten
   garantiert gleich aussehen. */
.beob-gruppe {
  margin-bottom: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid rgba(0,0,0,.07);
}
.beob-gruppe-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--slate);
  display: block;
  margin-bottom: 8px;
  letter-spacing: .01em;
}
.btn-add-zeile {
  margin-top: 6px;
  font-size: 12px;
  background: rgba(255,255,255,.7);
}

/* Teilflächen: fasst die Abschnitte (Teilfläche 1..N + Gesamtergebnis) einer
   Beobachtungsgruppe visuell zusammen. */
.beob-gruppe-set {
  margin-bottom: 14px;
  padding: 10px;
  border-radius: 12px;
  border: 1px dashed rgba(0,0,0,.15);
}
.beob-gruppe-set-titel {
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-bottom: 8px;
}

/* Beobachtungsgruppen-Box in der Bogen-Vorschau/Moderation (bewertung.php).
   overflow-x:auto, weil die Tabelle je Gruppe inzwischen eine Spalte pro
   Teilfläche hat (bis zu 10 + "Gesamt") und auf schmalen Bildschirmen sonst
   das Layout sprengen würde. */
.gruppe-block {
  margin-bottom: 8px;
  padding: 14px 16px;
  border-radius: 10px;
  border: 1px solid rgba(0,0,0,.07);
  overflow-x: auto;
}
.gruppe-block table { min-width: max-content; }
/* LakeExplorer-Spalte der Anzeige: wie im Eingabeformular auf ihre
   Mindestbreite gedrueckt, damit der Kopf am weichen Trennzeichen umbricht
   (siehe .beob-tabelle th.sp-lakeexplorer oben und beobachtungen_tabelle_kopf_html()
   in lib.php). */
/* NICHT width:1%: eine Prozentbreite an einer Spalte rechnet die Tabelle bei
   min-width:max-content (oben) auf Inhalt / 1 % hoch - aus der 117px breiten
   Spalte wurde so eine rund 11.700px breite Tabelle (auf dem Handy ein
   Vielfaches der Bildschirmbreite). width:1px schrumpft die Spalte genauso auf
   ihren Mindestinhalt, ohne diesen Effekt. */
.gruppe-block th.sp-lakeexplorer { width:1px; }
/* Handy: die Tabellen der Anzeige dürfen schrumpfen (Artnamen brechen um) statt auf die
   volle Textbreite zu wachsen, mit engeren Zellen. Reicht der Platz trotzdem nicht (viele
   Teilflächen), scrollt nur der Kasten waagerecht (.gruppe-block, overflow-x:auto). Die
   Zellen tragen ihr Padding/min-width inline (kartieren.php, beobachtungen_tabelle_kopf_html()),
   daher !important. */
@media (max-width: 700px) {
  .gruppe-block { padding: 10px 8px; max-width: 100%; }
  .gruppe-block table { min-width: 0; }
  .gruppe-block th, .gruppe-block td { padding-left: 4px !important; padding-right: 4px !important; }
  .gruppe-block th { min-width: 34px !important; letter-spacing: 0 !important; font-size: 11px !important; }
  .gruppe-block td.sp-art, .gruppe-block th.sp-art { min-width: 13ch; overflow-wrap: break-word; }
}
.gruppe-block-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--slate);
  margin-bottom: 10px;
}

/* Leerzustand (keine Einträge) – gemeinsam genutzt von bewertung.php und admin.php. */
.empty { color:var(--muted); font-size:13px; padding:20px 0; text-align:center; }

/* Schwebendes Tooltip für abgeschnittene Texte in Tabellenzellen (z. B.
   Beschreibung im Tab "Seen") - siehe langtextTooltipInit() in kartieren.php.
   Reagiert dort sowohl auf Maus-Hover als auch auf Tippen: ein natives
   title-Attribut erscheint auf Touchscreens gar nicht oder nur unzuverlässig. */
.schwebe-tooltip {
  position: fixed;
  z-index: 1000;
  max-width: 320px;
  background: #1e293b;
  color: #fff;
  font-size: 13px;
  line-height: 1.4;
  padding: 8px 10px;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,.25);
  pointer-events: none;
  white-space: normal;
  visibility: hidden;
}
.schwebe-tooltip.sichtbar { visibility: visible; }

/* Passwort-Felder: Augen-Umschalter (anzeigen/verbergen) – identisch zu admin.css */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { padding-right: 42px; }
.pw-eye {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  border: none; background: transparent; cursor: pointer;
  padding: 2px 4px; margin: 0; font-size: 16px; line-height: 1;
  color: #64748b; border-radius: 6px;
}
.pw-eye:hover { color: #334155; background: rgba(0,0,0,.05); }

/* Sortierbare Spaltenköpfe (tabelleInitSort in tabelle.js) */
.sort-th { all:unset; cursor:pointer; font:inherit; font-weight:600;
            display:inline-flex; align-items:center; gap:4px; white-space:nowrap; }
.sort-th:hover { color:var(--btn-primary); }
.sort-th::after { content:'⇅'; font-size:.75em; opacity:.35; }
.sort-th[data-dir=asc]::after  { content:'▲'; opacity:1; color:var(--btn-primary); }
.sort-th[data-dir=desc]::after { content:'▼'; opacity:1; color:var(--btn-primary); }

/* Karten-Container (Leaflet-Boxen). Bewusst als Klassen in style.css statt als
   Inline-Styles in bewertung.php: nur so kann die Overlay-Regel weiter unten das
   4:3 per Spezifität aufheben. Ein Inline-aspect-ratio wäre nicht überschreibbar
   und würde die vergrößerte Karte im „Karte vergrößern"-Overlay auf 4:3 stauchen,
   statt sie den Overlay-Kasten füllen zu lassen (dort setzt bogen.js height:100%
   -> definite Höhe + aspect-ratio => Breite würde aus dem Verhältnis abgeleitet). */
.karte-box { border-radius:10px; border:1px solid var(--line); }
/* Anzeige-Karte + Pfad-Zeichenkarte: 4:3 als Basis-Verhältnis.
   Die Begrenzung auf max. 90% der Fensterhöhe (bei Bedarf NUR die Höhe, ohne
   die Breite zu verändern) übernimmt bewusst NICHT CSS max-height (das
   Zusammenspiel mit aspect-ratio ist je nach Layout nicht zuverlässig,
   manche Browser leiten daraus doch wieder eine schmalere Breite ab),
   sondern gezielt JS – siehe kartenHoeheAnpassen() weiter unten / in
   bewertung.php (initBogenKarte). */
.karte-box--4zu3 { aspect-ratio: 4 / 3; }

/* Handy/schmale Screens: KEIN festes 4:3 – sonst wird die Karte (volle Breite
   × ¾) sehr hoch, geht „über den Bildschirm" und erschwert das Scrollen (die
   Leaflet-Karte fängt zudem Touch-Gesten ab). Stattdessen aspect-ratio aus und
   eine begrenzt mitwachsende Höhe.
   Die Regel dazu steht NICHT hier, sondern im Handy-Abschnitt weiter unten
   (Suchwort "Handy-Bedienung") - dort zusammen mit den übrigen
   Karten-/Trefferflächen-Regeln, damit die Handy-Bedienung an EINER Stelle
   nachvollziehbar bleibt statt über die Datei verteilt. Die frühere feste
   height:260px hier ist dort durch clamp() ersetzt: 260px reichten nicht, um
   Eckpunkte zu setzen. Das Vergrößern-Overlay (#bogen-pfad-karte in
   .karte-overlay-inhalt) bleibt über die höhere Spezifität unberührt und füllt
   weiter den Kasten. */

/* Großflächiges Karten-Overlay (z. B. Teilflächen-Pfad-Karte beim Bogen
   bearbeiten – siehe pfadKarteOverlayUmschalten() in bogen.js). Der
   eigentliche Karten-Container wird per DOM-Move hierher verschoben und beim
   Schließen wieder zurück; das Overlay selbst ist reine Präsentation. */
.karte-overlay {
  display:none; position:fixed; inset:0; z-index:2000;
  background:rgba(15,23,42,.6);
  align-items:center; justify-content:center; padding:20px;
}
.karte-overlay.aktiv { display:flex; }
.karte-overlay-box {
  background:#fff; border-radius:12px; width:100%; max-width:1100px; height:88vh;
  display:flex; flex-direction:column; overflow:hidden; box-shadow:0 20px 60px rgba(0,0,0,.35);
}
.karte-overlay-kopf {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:12px 16px; border-bottom:1px solid var(--line); flex-shrink:0;
}
.karte-overlay-kopf strong { font-size:15px; }
.karte-overlay-werkzeuge {
  display:flex; flex-wrap:wrap; gap:14px; align-items:flex-end;
  padding:10px 16px; border-bottom:1px solid var(--line); flex-shrink:0;
}
.karte-overlay-werkzeuge:empty { display:none; }
.karte-overlay-werkzeuge #tf-anzahl-block { margin-bottom:0 !important; }
.karte-overlay-inhalt { flex:1; min-height:0; }
.karte-overlay-inhalt #bogen-pfad-karte { aspect-ratio:auto; height:100%; border-radius:0; border:0; }

/* Drag-&-Drop-Anfasser zum Anordnen von Tabellenzeilen (tabelleInitDrag in
   tabelle.js), z. B. im Tab „Bögen zusammenfügen". */
.drag-handle {
  cursor: grab; user-select: none; -webkit-user-select: none;
  color: var(--muted); font-size: 16px; line-height: 1;
  padding: 2px 6px; display: inline-block;
}
.drag-handle:active { cursor: grabbing; }
tr.zieht, th.zieht { opacity: .5; background: var(--bg); }

/* Spalten verschieben (tabelleInitSpaltenZiehen in tabelle.js): die Überschrift
   selbst ist der Anfasser; die Balken zeigen beim Ziehen, auf welcher Seite der
   Zielspalte die gezogene landet. */
th.sort-klickbar { cursor: pointer; }
th.spalten-ziehbar { cursor: grab; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
body.spalten-zieht, body.spalten-zieht * { cursor: grabbing !important; user-select: none; }
/* Anzeige beim Ziehen wie in der scientec-Tabelle (export/table.css): Kopie der
   Überschrift folgt dem Zeiger, gegriffene Kopfzelle abgeblendet, rote Ziel-Linie. */
th.spalten-quelle { opacity: .4; }
.spalten-geist {
  position: fixed; z-index: 1000; pointer-events: none; opacity: .85;
  box-sizing: border-box; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  box-shadow: 0 2px 6px rgba(0,0,0,.4);
}
.spalten-marke {
  position: fixed; z-index: 999; width: 3px; margin-left: -1px;
  background: #e2001a; pointer-events: none;
}
/* Spaltenbreite: Griff am rechten Rand der Überschrift (tabelleInitSpaltenZiehen).
   position:relative nur als Grundlage - der klebende Kopf (.tabelle-scroll thead th,
   position:sticky) ist spezifischer und bleibt; sticky dient ebenso als Bezug. */
th.spalten-breite-th { position: relative; }
/* Tabellen mit verschiebbaren Spalten: linker und rechter Rand jeder Kopfzelle als
   dünne Linie. Als inset-Schatten statt border: Rahmen einer border-collapse-Tabelle
   bleiben beim klebenden Kopf (position:sticky) nicht stehen. Rechts an jeder Zelle,
   links nur an der ersten - so entsteht zwischen zwei Zellen keine doppelte Linie. */
table.spalten-tabelle > thead th { box-shadow: inset -1px 0 0 #cbd5e1; }
table.spalten-tabelle > thead tr:first-child > th:first-child { box-shadow: inset 1px 0 0 #cbd5e1, inset -1px 0 0 #cbd5e1; }
.spalten-breite-griff {
  position: absolute; top: 0; right: 0; width: 6px; height: 100%;
  cursor: col-resize; z-index: 2; touch-action: none;
}
.spalten-breite-griff:hover { background: rgba(30,64,175,.25); }
body.spalten-breite-zieht, body.spalten-breite-zieht * { cursor: col-resize !important; user-select: none; }
/* Nach einer Breitenänderung (table-layout:fixed): zu langer Inhalt wird
   abgeschnitten statt in die Nachbarspalte zu ragen. */
table.spalten-breite-fest th, table.spalten-breite-fest td { overflow: hidden; text-overflow: ellipsis; }

/* "?"-Knopf im Tabellenkopf und seine Erklärbox (tabelleInitSpaltenZiehen in
   tabelle.js): Sortieren und Spalten verschieben. */
.tabelle-hilfe-knopf {
  all: unset; box-sizing: border-box; width: 18px; height: 18px; border-radius: 50%;
  border: 1px solid var(--muted); color: var(--muted); font: 700 11px/16px system-ui, sans-serif;
  text-align: center; cursor: pointer; vertical-align: middle; margin-left: 4px;
}
.tabelle-hilfe-knopf:hover, .tabelle-hilfe-knopf:focus-visible { color: var(--teal); border-color: var(--teal); }
.tabelle-hilfe-box {
  position: fixed; z-index: 1000; max-width: 320px; display: none;
  background: #fff; color: var(--slate); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,.2); padding: 10px 12px; font-size: 13px; line-height: 1.4;
  text-transform: none; font-weight: 400; text-align: left;
}
.tabelle-hilfe-box.sichtbar { display: block; }
.tabelle-hilfe-box p { margin: 0 0 6px; }
.tabelle-hilfe-box p:last-child { margin-bottom: 0; }

/* Foto-Lightbox in der Anzeige (fotoviewer.js): zeigt ein Bogen-Foto in
   maximal für das Fenster darstellbarer Größe, mit Bildunterschrift,
   Teilflächen-Angabe und nummerierten Links zu allen Fotos des Bogens. */
.foto-viewer-overlay {
  display:none; position:fixed; inset:0; z-index:2100;
  background:rgba(15,23,42,.85);
  align-items:center; justify-content:center; padding:20px;
}
.foto-viewer-overlay.aktiv { display:flex; }
.foto-viewer-box {
  position:relative; width:100%; height:100%;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:10px;
}
.foto-viewer-bildbox {
  flex:1; min-height:0; width:100%;
  display:flex; align-items:center; justify-content:center;
  position:relative;
  /* Die Bildbox selbst fängt keine Klicks ab (sonst liegt sie – da im DOM nach
     dem Schließen-Button – im Klick-Stapel über den absolut positionierten
     Buttons und blockiert deren Klicks, obwohl sie transparent ist und die
     Buttons sichtbar bleiben). Bild und Pfeile holen sich Klicks gezielt zurück. */
  pointer-events:none;
}
.foto-viewer-bildbox img {
  max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain;
  display:block; border-radius:8px; box-shadow:0 10px 40px rgba(0,0,0,.5);
  pointer-events:auto;
}
.foto-viewer-pfeil {
  position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  background:rgba(255,255,255,.9); border:0; border-radius:50%;
  width:44px; height:44px; font-size:20px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  color:var(--slate); box-shadow:0 2px 8px rgba(0,0,0,.3);
  pointer-events:auto;
}
.foto-viewer-pfeil:hover { background:#fff; }
.foto-viewer-pfeil--prev { left:8px; }
.foto-viewer-pfeil--next { right:8px; }
.foto-viewer-schliessen {
  position:absolute; top:14px; right:14px; z-index:2;
  background:rgba(255,255,255,.9); border:0; border-radius:8px;
  padding:8px 12px; font-size:16px; cursor:pointer; color:var(--slate);
}
.foto-viewer-schliessen:hover { background:#fff; }
.foto-viewer-info { flex-shrink:0; text-align:center; color:#fff; max-width:700px; }
.foto-viewer-gruppe {
  font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.04em;
  color:#cbd5e1; margin-bottom:2px;
}
.foto-viewer-unterschrift { font-size:14px; }
/* Position (left/width/top) wird per JS (fotoviewer.js) exakt auf die
   tatsächliche Größe/Position des Fotos gesetzt, da dieses per
   object-fit:contain in Größe und Lage variiert. So steht der Text
   immer bündig am rechten Rand des Fotos, direkt darunter. */
.foto-viewer-fotograf {
  position:absolute; font-size:12px; color:#cbd5e1;
  text-align:right; white-space:nowrap; pointer-events:none;
}
.foto-viewer-zaehler { font-size:12px; color:#94a3b8; margin-top:2px; }
.foto-viewer-links {
  flex-shrink:0; display:flex; flex-wrap:wrap; gap:6px; justify-content:center;
  max-width:90%; max-height:60px; overflow-y:auto;
}
.foto-viewer-links button {
  min-width:28px; height:28px; padding:0 6px; border-radius:6px; border:0;
  background:rgba(255,255,255,.15); color:#e2e8f0; font-size:12px; cursor:pointer;
}
.foto-viewer-links button:hover { background:rgba(255,255,255,.3); }
.foto-viewer-links button.aktiv { background:var(--btn-primary); color:#fff; font-weight:700; }

/* Thumbnails in der Anzeige-Fotogalerie sind jetzt Buttons für die Lightbox,
   kein normaler Link mehr – Cursor entsprechend anpassen. */
.foto-thumb { cursor:zoom-in; }

/* Bögen-Layer (Artenliste, 📋-Knopf "N Bögen"): zeigt die Bögen einer Art als
   scrollbare Liste in einem Overlay statt einer aufklappenden Tabellenzeile -
   bei vielen Bögen würde diese sonst die ganze Tabelle auseinanderreißen.
   Aufbau/Klassen analog zum Foto-Lightbox-Overlay oben (fixed, zentriert,
   .aktiv schaltet sichtbar), aber als normale weiße Karte statt Vollbild-Bühne,
   da hier Text/Links und kein Bild im Mittelpunkt stehen. */
.bogen-liste-overlay {
  display:none; position:fixed; inset:0; z-index:2100;
  background:rgba(15,23,42,.55);
  align-items:center; justify-content:center; padding:20px;
}
.bogen-liste-overlay.aktiv { display:flex; }
.bogen-liste-box {
  background:#fff; border-radius:12px; width:100%; max-width:440px;
  max-height:80vh; display:flex; flex-direction:column;
  box-shadow:0 20px 60px rgba(0,0,0,.35);
}
.bogen-liste-kopf {
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:14px 16px; border-bottom:1px solid var(--line); flex-shrink:0;
}
.bogen-liste-kopf strong { font-size:15px; }
.bogen-liste-inhalt { overflow-y:auto; padding:6px; }
/* Je Bogen ein eigener, klickbarer Block statt einer schmalen Textzeile -
   Datum und Gewässer sollen beide auf einen Blick lesbar sein, nicht nur als
   aneinandergereihter Text wie zuvor die "✎ Datum · Status"-Knopfreihe. */
.bogen-liste-eintrag {
  display:flex; flex-direction:column; gap:2px;
  padding:10px 12px; border-radius:8px; text-decoration:none; color:inherit;
}
.bogen-liste-eintrag:hover { background:var(--bg); }
.bogen-liste-datum { font-weight:600; font-size:13.5px; }
.bogen-liste-gewaesser { font-size:12.5px; color:var(--muted); }
.bogen-liste-ohne { color:var(--muted); font-style:italic; }

/* Markierte Zeile der Artentabelle (Tab "Artenliste"): zeigt, welche Zeile
   das gemeinsame Bearbeiten-Formular oberhalb der Tabelle gerade füllt -
   bleibt bestehen, bis der Fokus ein anderes Element trifft (siehe
   artZeileMarkieren()/der focusin-Listener in kartieren.php). */
#arten-tabelle tr.art-row-ausgewaehlt > td { background:#eef2ff; }

/* Markierte Zeile(n) in "Alle Synonyme" nach einem Sprung aus der Spalte
   "Syn." der Artentabelle (siehe synonymZuArtSpringen() in kartieren.php). */
#synonyme-tabelle tr.syn-row-markiert > td { background:#eef2ff; }

/* -----------------------------------------------------------------------------
   Handy-Bedienung (Schwerpunkt: Kartenarbeit im Erfassungsformular)
   -----------------------------------------------------------------------------
   Das Seitengerüst ist schon länger mobiltauglich (Navigation/Tab-Leiste, siehe
   der Breakpoint weiter oben). Was fehlte, war die Bedienung IM Formular: zu
   kleine Trefferflächen und eine Karte, die auf dem Handy nur ein Streifen ist.

   Zwei Schalter, bewusst getrennt:
     - Dieser CSS-Breakpoint (900px) für Größen/Layout - dieselbe Grenze, die im
       Projekt schon "mobil" bedeutet.
     - matchMedia('(pointer: coarse)') in karte.js für die Trefferflächen IN der
       Karte (Eckpunkte, Hit-Linie). Getrennt, weil ein schmales Desktop-Fenster
       kein Finger ist und umgekehrt ein Tablet im Querformat breiter als 900px
       sein kann.
   ----------------------------------------------------------------------------- */

/* Leaflets eigene Bedienelemente: Die Bibliothek setzt auf Touch selbst nur
   30x30 px (vendor/leaflet/leaflet.css). Kein Breakpoint nötig - die Klasse
   .leaflet-touch vergibt Leaflet ausschließlich auf Touch-Geräten, am
   Schreibtisch greift diese Regel also ohnehin nie. */
.leaflet-touch .leaflet-bar a {
  width:44px; height:44px; line-height:44px;
}
.leaflet-touch .leaflet-control-zoom-in,
.leaflet-touch .leaflet-control-zoom-out { font-size:24px; }

@media (max-width: 900px) {
  /* --- Trefferflächen ------------------------------------------------------
     44px ist die von Apple/Google empfohlene Mindestgröße. Die Schrift darf
     klein bleiben (sonst platzen die Knopfreihen an der Karte), die FLÄCHE
     nicht. .btn-sm war mit ~22px Höhe der schlimmste Fall - und genau die
     Klasse tragen mehrere Knöpfe am Formular. */
  button, .btn { min-height:44px; padding:11px 16px; }
  .btn-sm { min-height:40px; padding:9px 12px; font-size:13px; }

  /* Knopfreihen an der Karte (Teilflächen, Vergrößern, Punkt entfernen, GPS,
     GPX): mehr Luft zwischen den Zielen, damit man nicht den Nachbarknopf
     trifft. */
  #pfad-tf-buttons, .karte-overlay-werkzeuge { gap:8px; }

  /* --- Karte im Formular ---------------------------------------------------
     260px waren zu wenig, um darin Eckpunkte zu setzen. Trotzdem KEIN 4:3
     (volle Breite x 3/4 wäre höher als der halbe Bildschirm und würde beim
     Scrollen die Touch-Gesten der Karte in den Weg legen) - deshalb eine
     mitwachsende, aber gedeckelte Höhe. Ersetzt die frühere feste Angabe. */
  /* Untergrenze 200px statt 300px: im Querformat ist der Bildschirm nur gut
     350px hoch, 300px Karte plus Adressleiste ragten dann über den Rand. */
  .karte-box--4zu3 { aspect-ratio:auto; height:clamp(200px, 55vh, 460px); max-width:100%; }

  /* --- Vollbild-Overlay ----------------------------------------------------
     Auf dem Handy ist das Vollbild der REGELFALL für Kartenarbeit (bogen.js
     öffnet es beim Umschalten der Karte automatisch, siehe
     vollbildBeiSchmalOeffnen()). Dann soll es auch die ganze Fläche nutzen:
     kein Rahmen, keine Ecken, kein Rand.

     height zweimal: 100vh als Rückfall für Browser ohne dvh-Einheit, danach
     100dvh - sonst springt das Overlay beim Ein-/Ausfahren der Adressleiste
     und die Werkzeugzeile rutscht aus dem Bild.

     overscroll-behavior:contain statt body{overflow:hidden} per JS: Letzteres
     würde den <body> zum Scroll-Container machen - genau das, was der
     Kommentar bei body{overflow-x:clip} ganz oben aus guten Gründen vermeidet
     (scrollIntoView/sticky zielen danach auf den falschen Container). */
  .karte-overlay { padding:0; overscroll-behavior:contain; }
  .karte-overlay-box {
    max-width:none; border-radius:0;
    height:100vh;
    height:100dvh;
  }
  /* Werkzeugzeile im Vollbild: eine Zeile, waagerecht schiebbar - dasselbe
     Muster wie die Tab-Leiste oben. Umbruch würde die Höhe unvorhersehbar
     machen und der Karte Platz wegnehmen. */
  .karte-overlay-werkzeuge {
    flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none;
    -webkit-overflow-scrolling:touch;
    padding:8px 10px;
  }
  .karte-overlay-werkzeuge::-webkit-scrollbar { display:none; }
  .karte-overlay-kopf { padding:8px 10px; }

  /* --- Formularfelder ------------------------------------------------------
     16px ist keine Geschmacksfrage: iOS-Safari zoomt beim Fokussieren
     automatisch in die Seite hinein, wenn ein Feld kleiner als 16px schreibt.
     Danach steht die Seite verschoben da und muss von Hand wieder
     herausgezoomt werden - bei einem Formular mit dutzenden Feldern jedes Mal.
     Die Regel greift OHNE !important, weil die Inline-Styles an den Feldern
     dafür aus kartieren.php und bogen.js entfernt wurden (Ursache statt
     Symptom, siehe die textarea-Regel weiter oben).

     min-height nur für Felder, die man antippt - Ankreuzfelder/Radios haben
     ihre eigene Größe (siehe die Ausnahme-Regel oben bei "select, input") und
     würden sonst zu Balken. */
  input, select, textarea { font-size:16px; }
  input:not([type=checkbox]):not([type=radio]), select, textarea { min-height:44px; }

  /* Artentabellen: hier zählt jeder Pixel Breite (bis zu 10 Teilflächen-Spalten
     plus "Gesamt"), deshalb NUR die Schrift auf 16px gegen den Zoom - die Höhe
     bleibt kompakter als 44px, sonst wird eine Tabelle mit 50 Artenzeilen
     unüberschaubar lang. Die eigenen Regeln dieser Felder (font-size:13px, s.
     .menge-sel/.frei-art-*) sind spezifischer als die allgemeine Regel oben und
     müssen deshalb ausdrücklich überschrieben werden. */
  .beob-tabelle .menge-sel,
  .beob-tabelle .frei-art-zelle input,
  .beob-tabelle .frei-art-wiss-zelle input { font-size:16px; min-height:40px; }

  /* --- Artname bleibt beim Querscrollen stehen -----------------------------
     Die Artentabelle scrollt auf dem Handy waagerecht (.beob-tabelle-wrap).
     Ohne diese Regel füllt man Mengen aus, während die Art, zu der sie
     gehören, links aus dem Bild gewandert ist.

     Sticky gilt bewusst NUR für die Trivialname-Spalte (.sp-art-trivial), NICHT
     für .sp-art-wiss: Trivialname muss immer sichtbar bleiben, der
     wissenschaftliche Name darf bei Platzmangel normal weggescrollt werden
     (nicht ausgeblendet - er bleibt über das horizontale Scrollen der Tabelle
     erreichbar). Wären beide gleichzeitig position:sticky;left:0, würde die
     zweite Spalte (wiss) beim Scrollen die erste (Trivialname) überdecken
     statt daneben zu stehen, da beide auf denselben Versatz klemmen.

     Zum Hintergrund: Eine klebende Zelle MUSS deckend sein, sonst scrollen die
     übrigen Zellen sichtbar darunter durch. Die Zeilenfarben der
     Indikatorgruppen (tr.indikator-*, siehe weiter oben) sollen dabei erhalten
     bleiben - deshalb erbt die Zelle die Farbe ihrer Zeile, und die Zeilen
     bekommen hier eine deckende Grundfarbe. Der :where()-Umschlag sorgt dafür,
     dass diese Grundfarbe NICHT spezifischer ist als tr.indikator-* und die
     Einfärbung also weiterhin gewinnt (:where() zählt 0 zur Spezifität). */
  .beob-tabelle td.sp-art-trivial,
  .beob-tabelle th.sp-art-trivial {
    position:sticky; left:0; z-index:1;
    background-color:inherit;
  }
  /* Kopfzeile: Farbton der Gruppe (erbt über thead/tr, siehe oben). */
  .beob-tabelle thead th.sp-art-trivial { background-color:inherit; }

  /* --- Mehr nutzbare Breite -----------------------------------------------
     24/20px Rand kosten auf einem 360px-Bildschirm rund ein Neuntel der
     Breite - und die fehlt genau den Artentabellen. */
  .wrap { padding:8px 6px 12px; }
  /* Karten-Kästen: der 20px-Innenrand kostete links und rechts zusammen
     noch einmal 40px - auf dem Handy der größte Posten. */
  .card { padding:12px 10px; margin-bottom:12px; border-radius:10px; }

  /* --- Speicherleiste am unteren Rand haftend ------------------------------
     Nur der ABSCHLIESSENDE "Bogen speichern"-Knopf (kartieren.php, ganz am
     Formularende) bekommt das - der frühere Knopf vor den Artentabellen
     bleibt normaler Blockinhalt, sonst gäbe es zwei haftende Leisten
     gleichzeitig. Das Formular ist auf dem Handy lang (mehrere
     Artengruppen-Tabellen); ohne das hier müsste man für jeden Speicherstand
     ganz nach unten scrollen. Negative Ränder gleichen genau das .wrap-Polster
     von oben aus, damit die Leiste randlos am Bildschirmrand sitzt.
     position:sticky statt fixed: bleibt Teil des Dokumentflusses (kein
     Überlappen von Inhalt beim Erscheinen) und braucht body{overflow-x:clip}
     statt hidden nicht extra - das gilt hier ohnehin schon (siehe oben). */
  .speicher-leiste {
    position:sticky; bottom:0;
    background:#fff;
    margin:16px -6px -12px;
    padding:10px 6px;
    border-top:1px solid #e2e8f0;
    box-shadow:0 -2px 8px rgba(0,0,0,.08);
    z-index:5;
  }
}

/* Zweispaltige Feldpaare (Breite/Länge, Datum/Kartierer, …). Als Klasse statt
   inline in kartieren.php, weil sich ein Inline-Style per Media Query nicht
   überschreiben lässt - und genau das braucht die Regel darunter. */
.grid-2 { grid-template-columns:1fr 1fr; }
/* Sehr schmale Geräte: einspaltig. Erst ab hier, nicht schon bei 900px - zwei
   Spalten Koordinatenfelder sind auf einem Tablet noch gut bedienbar und
   halten Breite/Länge sichtbar beieinander. */
@media (max-width: 520px) {
  .grid-2 { grid-template-columns:1fr; }
}

/* -----------------------------------------------------------------------------
   Druckansicht "Bogen ansehen" (bewertung.php): der Detailinhalt eines Bogens
   wird beim Drucken in #bogen-druck eingehüllt. Beim Drucken wird NUR dieser
   Bereich angezeigt (Topbar/Sidebar/Tabs/Buttons der Hauptseite werden
   ausgeblendet) – unabhängig vom genauen Aufbau von layout.php. Elemente mit
   der Klasse "druck-ausblenden" (z. B. die Export-/Fenster-Buttons) werden
   zusätzlich beim Drucken entfernt.
   ----------------------------------------------------------------------------- */
@media print {
  /* Bekannte Layout-Bereiche aus layout_template.html direkt ausblenden.
     Nötig unabhängig vom #bogen-druck-Block weiter unten: der greift nur auf
     Seiten MIT Kartierungsbogen, hier soll auf allen Seiten kein Header/keine
     Sidebar/kein Footer mitgedruckt werden – das vermeidet auch unnötigen
     Leerraum durch die Sidebar-Breite. */
  header, .sidebar, footer { display: none !important; }
  .cookie-banner { display: none !important; }
  /* basis.js haelt bei sichtbarem Cookie-Hinweis unten Platz frei, indem es
     padding-bottom direkt am body setzt (Inline-Style). Beim Drucken ist das
     Banner ausgeblendet – der reservierte Platz wuerde sonst als Leerraum
     bzw. zusaetzliche Leerseite mitgedruckt. !important ist hier notwendig,
     weil ein Inline-Style sonst gewinnt. */
  body { padding-bottom: 0 !important; }
  .tab-leiste, .chip-leiste, .kontext-pfad { display: none !important; }

  /* Hilfetexte im Ausdruck: Der Aufklapp-Knopf wäre auf Papier sinnlos, der
     Inhalt dagegen ist genau das, was man ausdrucken will. Deshalb
     Zusammenklappen aufheben statt die Blöcke auszublenden.
     Das display:block auf .hilfe-block > div ist nötig, weil Browser den
     Inhalt eines geschlossenen <details> selbst verbergen - das lässt sich
     nur über den Inhalt, nicht über das <details> aufheben. */
  .hilfe-block > summary { display: none !important; }
  .hilfe-block > .hilfe-inhalt {
    display: block !important; margin-top: 0;
    border: none; padding: 0; max-width: none;
  }
  .hilfe-fehlt { display: none !important; }   /* Admin-Notiz, nicht drucken */
  .wrap { padding: 0; max-width: none; }
  .shell { display: block; }
  .main-content { width: 100% !important; margin: 0 !important; }

  /* Zusätzlich generisch abgesichert: enthält die Seite einen Kartierungsbogen,
     ist beim Drucken NUR dessen Inhalt relevant (nicht z. B. die
     Bögen-Liste/Formulare, die auf derselben Seite mit ausgegeben werden).
     WICHTIG – die :has()-Bedingung ist keine Kosmetik: #bogen-druck gibt es
     ausschließlich in kartieren.php und dort nur in der Bogen-Anzeige. Ohne
     die Einschränkung galt "body * { visibility:hidden }" auf JEDER Seite,
     ohne dass ein sichtbares Gegenstück existierte – Impressum, Datenschutz,
     Messwerte, Adminbereich usw. druckten dadurch komplett leere Seiten. Leer,
     aber nicht weg: visibility:hidden erhält die Layouthöhe, es kamen also
     mehrere leere Blätter aus dem Drucker.
     Kennt ein Browser :has() nicht, entfallen diese Regeln ganz – dann wird
     beim Bogen-Druck zu VIEL gedruckt statt nichts. Das ist die harmlosere
     Richtung. */
  body:has(#bogen-druck) * { visibility: hidden; }
  body:has(#bogen-druck) #bogen-druck,
  body:has(#bogen-druck) #bogen-druck * { visibility: visible; }
  #bogen-druck { position: absolute; left: 0; top: 0; width: 100%; }

  /* Elemente, die nie in den Ausdruck gehören (Export-/Fenster-Buttons u. Ä.).
     Bewusst nicht mehr nur innerhalb von #bogen-druck, damit die Klasse auch
     auf allen übrigen Seiten wirkt, die jetzt tatsächlich gedruckt werden. */
  .druck-ausblenden { display: none !important; }

  /* Karten-Bedienelemente machen beim Ausdruck keinen Sinn. */
  .leaflet-control-zoom, .leaflet-control-attribution { display: none !important; }

  /* 4:3 erzwingen: hoeheAnpassen() (karte.js) setzt bei kleinen Fensterhöhen
     ein Inline-height + aspect-ratio:auto, um die Karte auf max. 90% der
     Bildschirmhöhe zu deckeln – das gilt aber nur für den Bildschirm, nicht
     für den Ausdruck. !important überschreibt dieses Inline-Style gezielt
     nur innerhalb der Druckansicht; siehe auch invalidateSize() auf
     'beforeprint' in karte.js, damit Leaflet passend neu zeichnet. */
  #bogen-druck .karte-box--4zu3 {
    aspect-ratio: 4 / 3 !important;
    height: auto !important;
  }

  /* Bewertungsfarben (Ampel-Badges) werden von Browsern standardmäßig NICHT
     mitgedruckt – ohne diese Regel wäre die Bewertung farblos. */
  #bogen-druck * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    color-adjust: exact;
  }

  /* Kein Abschneiden von Karten mitten auf der Seite. */
  #bogen-druck .card { break-inside: avoid; page-break-inside: avoid; }

  /* Beobachtungsgruppen-Tabellen: statt horizontal zu scrollen (wie am
     Bildschirm), alle Teilflächen-Spalten auf die Seitenbreite pressen. */
  .gruppe-block { overflow-x: visible !important; }
  .gruppe-block table { min-width: 0 !important; width: 100% !important; table-layout: fixed; }
  .gruppe-block th, .gruppe-block td { width: auto !important; white-space: normal !important; word-break: break-word; }
  .gruppe-block th.sp-art, .gruppe-block td.sp-art { width: 34% !important; }
}

/* Linkliste (links.php): Baumdarstellung für Anzeige + Verwaltung. */
.linkbaum { list-style:none; margin:0; padding:0; }
.linkbaum .linkbaum { padding-left:20px; border-left:2px solid var(--line); margin:6px 0 0; }
.linkbaum > li { margin:0 0 10px; }
.link-titel, .link-ordner { font-weight:600; }
/* padding-left:20px hier bewusst gleich wie bei .link-zeile/.ordner-zeile/
   a.link-titel (siehe unten): der Kommentar ist ein eigenes li-Geschwister-
   Element, nicht Teil dieser Zeilen, und muss daher separat auf denselben
   Einzug gebracht werden, damit er unter dem Titel (nicht unter dem
   Toggle/Icon) beginnt. */
.link-kommentar { color:var(--muted); font-size:13px; margin:2px 0 0; padding-left:20px; }
/* position:relative + padding-left reservieren den Platz für den optionalen
   .ordner-toggle (siehe unten) – so verschiebt sich der restliche Zeileninhalt
   NICHT je nachdem, ob ein Toggle-Button gerendert wird (nur bei Ordnern mit
   Kindern) oder nicht (Ordner ohne Kinder, Links). Ohne das würden Geschwister
   auf derselben Baumtiefe optisch unterschiedlich weit eingerückt wirken. */
.link-zeile { display:flex; align-items:center; gap:8px; flex-wrap:wrap; position:relative; padding-left:20px; }
.link-actions { display:inline-flex; gap:4px; margin-left:auto; }
.link-actions form { display:inline-flex; }
.link-edit-form {
  display:flex; gap:10px; flex-wrap:wrap; align-items:flex-end;
  background:#f8fafc; border:1px solid var(--line); border-radius:8px;
  padding:12px; margin:4px 0;
}
.link-edit-form > div { min-width:140px; }
/* Info-Chips im Link-Bearbeiten-Formular: zeigen (nur lesend), in welchen
   Ordnern der Link aktuell liegt. Die eigentliche Verwaltung der Ablage läuft
   über den Baum (Drag&Drop / 🗑). */
.platz-chips { display:flex; flex-wrap:wrap; gap:6px; padding:2px 0; }
.platz-chip {
  display:inline-flex; align-items:center; gap:4px;
  padding:3px 9px; border:1px solid var(--line); border-radius:999px;
  background:#f1f5f9; font-size:12px; white-space:nowrap;
}
.platz-chip-leer { color:var(--muted); background:none; border-style:dashed; }

/* Auf-/Zuklappen von Ordnern (Anzeige + Bearbeiten), siehe links.js.
   Der Toggle-Pfeil dreht sich per aria-expanded, die Kind-Liste eines
   eingeklappten Ordners wird nur ausgeblendet (bleibt im DOM erhalten). */
.ordner-zeile { display:inline-flex; align-items:center; position:relative; padding-left:20px; }

/* Gleiche Reservierung auch für einzelne Links in der (nur lesenden) Anzeige:
   dort steht kein .ordner-zeile/.link-zeile drumherum, sondern <a
   class="link-titel"> direkt als li-Kind – damit er trotzdem bündig mit den
   Ordnern derselben Ebene beginnt, braucht er denselben Vorsprung. Betrifft
   NUR den Direktkind-Fall (Anzeige); im Bearbeiten-Tab sitzt .link-titel als
   <span> innerhalb von .link-zeile, das schon selbst eingerückt ist – die
   Kindselektor-Einschränkung (>) verhindert eine doppelte Einrückung dort. */
.linkbaum > li > a.link-titel { display:inline-block; padding-left:20px; }

.ordner-toggle {
  position:absolute; left:0; top:50%; width:16px; text-align:center;
  background:none; border:none; cursor:pointer; padding:0;
  font-size:.8em; line-height:1; color:var(--muted);
  transform:translateY(-50%) rotate(0deg); transition:transform .15s ease;
}
.ordner-toggle:hover { color:var(--slate); }
.ordner-toggle[aria-expanded="false"] { transform:translateY(-50%) rotate(-90deg); }
.linkbaum li.eingeklappt > ul { display:none; }

/* Nur für Screenreader/Formularlogik vorhanden, visuell unsichtbar (z. B.
   das versteckte Drag&Drop-Formular in links.php). */
.visually-hidden {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

/* --- Drag & Drop beim Verschieben von Ordnern/Links (links.js) ------------ */

/* Griff-Symbol vor jeder Zeile, signalisiert die Ziehbarkeit. */
.dnd-handle {
  cursor:grab; color:var(--muted); font-size:14px; line-height:1;
  padding:0 2px; user-select:none;
}
.dnd-zeile { cursor:grab; }
.dnd-zeile:active { cursor:grabbing; }

/* Zeile, die gerade gezogen wird. */
.dnd-dragging { opacity:0.4; }

/* Gültiges Drop-Ziel unter dem Mauszeiger. */
.dnd-drop-hover {
  outline:2px dashed var(--btn-primary); outline-offset:2px;
  background:#eef4ff; border-radius:6px;
}

/* Wie oben, aber im Kopier-Modus (Link mit gedrückter Strg/Alt/⌘-Taste
   gezogen) – grün statt blau, damit Kopieren klar vom Verschieben unterscheidbar ist. */
.dnd-drop-copy {
  outline-color:var(--btn-primary-d); background:#eff6ff;
}

/* Ordner, der als Drop-Ziel ungültig ist (der gezogene Ordner selbst oder
   einer seiner eigenen Unterordner) – wird beim Drag optisch ausgegraut. */
.dnd-drop-invalid { opacity:0.35; cursor:not-allowed; }

/* Permanente Wurzel-Drop-Zone ("auf die oberste Ebene verschieben"): im
   Ruhezustand dezent, während eines laufenden Drags (body.dnd-aktiv, von
   links.js gesetzt) deutlicher hervorgehoben. */
.dnd-root-drop {
  margin:0 0 12px; padding:8px 12px; border:2px dashed var(--line);
  border-radius:8px; text-align:center; font-size:13px; color:var(--muted);
  transition:background 0.15s, border-color 0.15s, color 0.15s;
}
body.dnd-aktiv .dnd-root-drop {
  border-color:var(--btn-primary); color:var(--slate);
}

/* --- Linkcheck ------------------------------------------------------------ */

/* Statusfarben (auch für Punkte und Badges genutzt). */
:root {
  --sp-ok:#16a34a; --sp-weiterleitung:#0284c7; --sp-warnung:#d97706;
  --sp-fehler:#dc2626; --sp-ungeprueft:#cbd5e1; --sp-unpruefbar:#94a3b8;
  /* Von Hand bestätigt (siehe link_manuell_bestaetigen() in lib.php).
     Absichtlich ein ruhiges Schiefergrau und kein Warnton: Diese Links sind
     geprüft, nur eben nicht von der Maschine - eine bernsteinfarbene Zahl
     daneben würde nach Arbeit aussehen, die es nicht mehr gibt. */
  --sp-manuell:#64748b;
}

/* Kleiner Statuspunkt vor einer Link-Zeile. */
.status-punkt {
  display:inline-block; width:10px; height:10px; border-radius:50%;
  flex:0 0 auto; vertical-align:middle; background:var(--sp-ungeprueft);
}
.status-punkt.sp-ok            { background:var(--sp-ok); }
.status-punkt.sp-weiterleitung { background:var(--sp-weiterleitung); }
.status-punkt.sp-warnung       { background:var(--sp-warnung); }
.status-punkt.sp-fehler        { background:var(--sp-fehler); }
.status-punkt.sp-ungeprueft    { background:var(--sp-ungeprueft); }
.status-punkt.sp-unpruefbar    { background:var(--sp-unpruefbar); }
/* Von Hand bestätigt - bisher nur als Badge (.lc-badge.sp-manuell unten)
   genutzt, seit dem Statuspunkt in der Gewässertabelle (gewaesser_status_punkt()
   in lib.php) auch als Punkt. */
.status-punkt.sp-manuell       { background:var(--sp-manuell); }

/* Gewässertabelle (kartieren.php, Tab "Gewässer"): Zeile des Gewässers, das
   gerade im gemeinsamen Formular unter der Karte bearbeitet wird (gesetzt von
   gewVerwZeileMarkieren()). Kobalt wie das Bearbeiten-Formular (Randstreifen,
   Abschnittsetiketten); die Randlinie links macht die Zeile auch bei hellem
   Bildschirm eindeutig. */
#gew-tabelle tr.gew-zeile-bearbeitet > td { background:#dbeafe; }
#gew-tabelle tr.gew-zeile-bearbeitet > td:first-child { box-shadow:inset 3px 0 0 var(--btn-primary); }
/* Gegenstück im Tab "Einstiege / Messstellen" (msVerwZeileMarkieren()). */
#ms-tabelle tr.ms-zeile-bearbeitet > td { background:#dbeafe; }
#ms-tabelle tr.ms-zeile-bearbeitet > td:first-child { box-shadow:inset 3px 0 0 var(--btn-primary); }

/* Zusammenfassung als farbige Badges. */
.lc-summary { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:12px; }
.lc-badge {
  font-size:12px; padding:3px 10px; border-radius:999px; color:#fff;
  background:var(--sp-ungeprueft); white-space:nowrap;
}
.lc-badge.sp-ok            { background:var(--sp-ok); }
.lc-badge.sp-weiterleitung { background:var(--sp-weiterleitung); }
.lc-badge.sp-warnung       { background:var(--sp-warnung); }
.lc-badge.sp-fehler        { background:var(--sp-fehler); }
.lc-badge.sp-ungeprueft    { background:var(--sp-unpruefbar); }
.lc-badge.sp-unpruefbar    { background:var(--sp-unpruefbar); }
.lc-badge.sp-manuell       { background:var(--sp-manuell); }

.lc-actions { display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.lc-info { font-size:12px; color:var(--muted); }

/* Fortschrittsbalken. */
.lc-progress { margin-top:12px; }
.lc-bar { height:8px; background:var(--line); border-radius:4px; overflow:hidden; }
.lc-bar-fill { height:100%; width:0; background:var(--btn-primary); transition:width .25s; }
.lc-progress-text { font-size:12px; color:var(--muted); margin-top:5px; }

/* Problemliste. */
.lc-probleme { margin-top:14px; }
.lc-probleme > summary { cursor:pointer; font-weight:600; }
.lc-tabelle { width:100%; border-collapse:collapse; margin-top:8px; font-size:13px; }
.lc-tabelle th { font-size:12px; color:var(--muted); }
.lc-tabelle td, .lc-tabelle th { border-top:1px solid var(--line); padding:7px 8px; vertical-align:top; }
.lc-hinweis { color:var(--muted); }
.lc-zeilen-aktion { white-space:nowrap; text-align:right; }

/* Zeile, die per "Erneut testen" (Knopf .lc-einzeln, siehe linkcheck.js) soeben
   fehlerfrei geworden ist. Sie bleibt absichtlich stehen, statt zu
   verschwinden: die Zaehlerleiste oben hat PHP gerendert und wuerde sonst nicht
   mehr zur Tabelle passen, und der Bezug zum gerade angeklickten Link ginge
   verloren. Beim naechsten Seitenaufbau ist die Zeile von selbst weg.

   Kurzes Aufleuchten wie bei .zeile-gespeichert weiter unten, danach
   dauerhaft abgesetzt - ohne die Animation ist die Aenderung bei einer langen
   Liste leicht zu uebersehen. */
@keyframes lc-behoben-fade {
  from { background-color: rgba(22,163,74,.22); }
  to   { background-color: transparent; }
}
.lc-tabelle tr.lc-behoben {
  animation: lc-behoben-fade 2.5s ease-out;
  opacity: .55;
}
/* Der Titel wird zusaetzlich durchgestrichen: die Deckkraft allein kann bei
   hellem Hintergrund untergehen. */
.lc-tabelle tr.lc-behoben td:first-child a { text-decoration: line-through; }

/* Waehrend die Einzelpruefung laeuft (linkcheck.js setzt disabled). Ohne das
   sieht ein Klick bei einem langsamen Host wie eine Nichtreaktion aus - die
   Pruefung darf mit den Wiederholungsversuchen aus link_pruefen_batch()
   durchaus eine Minute brauchen. */
.lc-einzeln[disabled] { opacity: .6; cursor: progress; }

/* Von Hand bestätigte Links (link_check_manuell_liste() in lib.php): Hosts, die
   automatisierte Abrufe abweisen und deshalb dauerhaft mit 401/403 antworten,
   im Browser aber erreichbar sind. Aufbau wie .lc-probleme darüber, damit die
   beiden Listen in derselben Karte gleich aussehen - nur die Beschriftung ist
   nicht fett, weil hier nichts zu tun ist. */
.lc-manuell-liste { margin-top:14px; }
.lc-manuell-liste > summary { cursor:pointer; color:var(--muted); font-size:13px; }
.lc-manuell-liste > summary:hover { color:var(--slate); }

/* Notiz, die beim Bestätigen mitgegeben wurde ("Bot-Sperre, Inhalt geprüft").
   Steht unter dem Titel in derselben Zelle, deshalb kleiner und abgesetzt. */
.lc-notiz { font-size:12px; color:var(--muted); margin-top:2px; }

/* Beide Zeilenknöpfe der Handbestätigung verhalten sich beim Speichern wie die
   Einzelprüfung (linkcheck.js setzt disabled) - dieselbe Rückmeldung. */
.lc-manuell[disabled], .lc-manuell-weg[disabled] { opacity: .6; cursor: progress; }

/* Kopfzeile eines Tab-Panels: Überschrift links, Aktion (z. B. Seiten-Wechsel
   Bearbeiten <-> Linkcheck) rechts. */
.tab-panel-kopf { display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-bottom:6px; }
.tab-panel-kopf h2 { margin:0; }

/* Hervorheben einer Tabellenzeile, z. B. nachdem "Meine Bögen" nach dem
   Speichern eines Bogens per Redirect dorthin zurückgescrollt hat, oder nach
   einem Sprung von einem Kartenmarker zur zugehörigen Zeile (siehe
   markierenBisFokusWeg() in basis.js, benutzt von bogen.js und karte.js).
   Bewusst KEIN zeitgesteuertes Fade-out (@keyframes/animation): Die Klasse
   verschwindet erst, wenn JavaScript sie entfernt - dort, weil der Fokus auf
   ein Objekt außerhalb der Zeile gewandert ist, nicht weil ein Timer abläuft.
   Kein transition auf dieser Klasse selbst: Eine hier deklarierte transition
   würde beim ENTFERNEN der Klasse nicht mehr greifen (sie verschwindet ja mit
   der Klasse zusammen) - das Verblassen sähe also nur beim Erscheinen sanft
   aus, beim Verschwinden aber weiterhin hart abgeschnitten. */
.zeile-gespeichert { background-color: rgba(30,64,175,.18); }

/* Zusatzkriterium UMG (TKg10/TKg13, #umg-zusatz-tabelle in kartieren.php):
   hebt die von umgZusatzAktualisieren() (bogen.js) ermittelte Zelle hervor -
   dieselbe Zelle, deren ri_delta gerade im Ergebnistext darüber steht. */
.umg-zelle.umg-treffer {
  background: var(--btn-primary);
  color: #fff;
  font-weight: 700;
  border-radius: 4px;
}

/* -----------------------------------------------------------------------------
   Strukturierte Stammdaten-Formulare (.stamm-form): Kopfzeile mit Titel und
   Schließen, nummerierte Abschnitte (fieldset/legend), Knopfleiste. Genutzt
   vom Bearbeiten-Formular der Artenliste (#art-bearbeiten-formular) und vom
   gemeinsamen Formular im Tab "Einstiege / Messstellen"
   (#ms-formular-karte), beide in kartieren.php. Die Anordnung der Abschnitte
   je Formular steht in den mit der jeweiligen id beginnenden Regeln.

   Artenliste: Die TKg-/NRW-Felder kommen aus
   arten_tkg_formularfelder()/arten_nrw_formularfelder() (lib.php) mit eigenen
   Inline-Stilen - deren feste Breiten werden hier je Ansicht überschrieben
   (daher die wenigen !important).

   Desktop (> 900px): möglichst wenig Höhe - Namen in EINER Zeile (4 Spalten),
   darunter LRT und Seetypen nebeneinander, Knöpfe unten rechts in derselben
   Zeile, sofern Platz ist. Kleinere Felder, keine Trennlinien.
   Mobil (<= 900px, dieselbe Grenze wie die übrigen Handy-Regeln): alles
   untereinander, Felder volle Breite (Tippgröße 44px kommt aus der
   allgemeinen Handy-Regel), TKg-Noten als 4er-Raster, Knopfleiste klebt am
   unteren Bildschirmrand, damit "Speichern" ohne Scrollen erreichbar bleibt.
   ----------------------------------------------------------------------------- */
.stamm-form {
  margin:0 0 14px; background:#fff;
  border:1px solid var(--line); border-left:4px solid var(--btn-primary); border-radius:10px;
  box-shadow:0 2px 10px rgba(15,23,42,.06);
}
.stamm-form-kopf {
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:6px 8px 6px 14px; border-bottom:1px solid var(--line);
}
.stamm-form-kopf h3 { margin:0; font-size:14px; }
.stamm-form-titelname { font-weight:400; color:var(--muted); }
.stamm-form-schliessen {
  width:30px; height:30px; flex-shrink:0; padding:0; border:0; border-radius:8px;
  background:transparent; color:var(--muted); font-size:20px; line-height:1; cursor:pointer;
}
.stamm-form-schliessen:hover { background:var(--bg); color:var(--slate); }
.stamm-form > .flash { margin:10px 14px 0 !important; }

.stamm-form > form {
  display:flex; flex-wrap:wrap; align-items:flex-start; gap:10px 22px;
  padding:10px 14px 12px;
}
/* Abschnitte als umrandete Kästen; der Titel (legend) sitzt als
   nummeriertes Etikett IM oberen Rahmen (klassisches fieldset-Verhalten) -
   so ist auf einen Blick klar, welches Feld zu welchem Abschnitt gehört. */
.stamm-form > form { counter-reset:art-abschnitt; }
.stamm-form-abschnitt {
  flex:1 1 auto; margin:0; padding:4px 10px 10px; min-width:0;
  border:1px solid #cbd5e1; border-radius:8px; background:#fcfdfe;
  counter-increment:art-abschnitt;
}
.stamm-form-abschnitt legend {
  display:inline-flex; align-items:center; gap:6px;
  padding:2px 10px 2px 3px; margin:0 0 4px -2px;
  font-size:11px; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  color:#fff; background:var(--btn-primary); border-radius:999px;
}
.stamm-form-abschnitt legend::before {
  content:counter(art-abschnitt);
  display:inline-flex; align-items:center; justify-content:center;
  width:17px; height:17px; border-radius:50%;
  background:#fff; color:var(--btn-primary); font-size:10.5px; letter-spacing:0;
}
.stamm-form-raster { display:grid; gap:6px 12px; grid-template-columns:repeat(auto-fill, minmax(150px, 1fr)); }
/* Artenliste: Namen in einer Zeile, darunter LRT (schmal) und Seetypen. */
#art-bearbeiten-formular .stamm-form-abschnitt:first-of-type { flex:1 1 100%; }
#art-bearbeiten-formular .stamm-form-abschnitt:first-of-type .stamm-form-raster { grid-template-columns:repeat(4, minmax(0, 1fr)); }
#art-bearbeiten-formular .stamm-form-abschnitt:nth-of-type(2) { flex:0 1 400px; }
#art-bearbeiten-formular .stamm-form-abschnitt:nth-of-type(2) .stamm-form-raster { grid-template-columns:repeat(2, minmax(0, 1fr)); }
/* Einstiege/Messstellen: Stammdaten (breit) und Position nebeneinander,
   Knopfleiste darunter über die volle Breite (Löschen links). */
#ms-formular-karte .stamm-form-abschnitt:nth-of-type(1) { flex:2 1 420px; }
#ms-formular-karte .stamm-form-abschnitt:nth-of-type(2) { flex:1 1 300px; }
#ms-formular-karte .stamm-form-raster { grid-template-columns:repeat(2, minmax(0, 1fr)); }
#ms-formular-karte .stamm-form-fuss { flex:1 1 100%; align-items:center; }
/* Gewässer: Stammdaten (breit, Beschreibung über die volle Breite) und
   Position nebeneinander, Knopfleiste darunter. */
#gew-formular-karte .stamm-form-abschnitt:nth-of-type(1) { flex:2 1 520px; }
#gew-formular-karte .stamm-form-abschnitt:nth-of-type(2) { flex:1 1 300px; }
#gew-formular-karte .stamm-form-abschnitt:nth-of-type(1) .stamm-form-raster { grid-template-columns:repeat(3, minmax(0, 1fr)); }
#gew-formular-karte .stamm-form-abschnitt:nth-of-type(2) .stamm-form-raster { grid-template-columns:repeat(2, minmax(0, 1fr)); }
#gew-formular-karte .stamm-form-fuss { flex:1 1 100%; }
.stamm-form-voll { grid-column:1 / -1; }
.stamm-form textarea { padding:5px 8px; font-size:13px; min-height:0; }
.stamm-form-aktion { display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; }
.stamm-form-aktion .karte-wasser-pruef { display:inline-flex; flex-wrap:wrap; align-items:center; gap:6px 8px; }
/* button/.btn setzen display:inline-flex und hebeln damit das hidden-
   Attribut aus (z. B. Löschen-Knopf im Messstellen-Formular). */
.stamm-form [hidden] { display:none !important; }
.stamm-form-fuss-links { order:-1; margin-right:auto; display:flex; align-items:center; gap:8px; }
.stamm-form-fuss-links:not(:has(> :not([hidden]))) { display:none; }
.stamm-form-aktion { margin-top:8px; }
.stamm-form label { font-size:12px; margin-bottom:2px; }
.stamm-form input:not([type=checkbox]):not([type=radio]), .stamm-form select { padding:5px 8px; font-size:13px; }
.stamm-form-schalter { display:flex; flex-direction:column; gap:3px; margin-top:6px; }
.stamm-form-schalter label { font-weight:400; margin:0; font-size:12.5px; }
.stamm-form-seetypen { flex:1 1 480px; display:flex; flex-wrap:wrap; gap:8px 10px; align-items:flex-start; }
.stamm-form-seetypen > div {
  padding:6px 8px; background:#fff; border:1px solid var(--line); border-radius:6px;
}
.stamm-form-seetypen > div > label:first-child { margin-bottom:4px; font-size:11.5px; }
.stamm-form-seetypen select { padding:3px 4px !important; }
.stamm-form-pflicht { color:var(--red); }
.stamm-form-fuss {
  display:flex; justify-content:flex-end; gap:8px;
  margin-left:auto; align-self:flex-end;
}
.stamm-form-fuss .btn { padding:6px 16px; }

@media (max-width: 900px) {
  .stamm-form { border-radius:10px; }
  .stamm-form-kopf { padding:6px 6px 6px 12px; }
  .stamm-form-schliessen { width:44px; height:44px; font-size:24px; }
  .stamm-form > form { display:block; padding:8px 10px 0; }
  .stamm-form-abschnitt { padding:6px 10px 12px; margin-bottom:12px; }
  .stamm-form-abschnitt legend { font-size:12px; padding:3px 12px 3px 4px; }
  .stamm-form-abschnitt legend::before { width:19px; height:19px; font-size:11.5px; }
  .stamm-form label { font-size:13px; }
  .stamm-form input:not([type=checkbox]):not([type=radio]), .stamm-form select { padding:8px 10px; font-size:16px; }
  .stamm-form-raster,
  #art-bearbeiten-formular .stamm-form-abschnitt:first-of-type .stamm-form-raster,
  #art-bearbeiten-formular .stamm-form-abschnitt:nth-of-type(2) .stamm-form-raster { grid-template-columns:repeat(2, minmax(0, 1fr)); gap:8px 10px; }
  .stamm-form-aktion .btn { width:100%; padding:10px 12px; }
  .stamm-form-aktion, .stamm-form-aktion .karte-wasser-pruef { display:block; }
  .stamm-form-aktion .btn { margin-top:6px; }
  .stamm-form-aktion .karte-wasser-status { display:block; margin-top:6px; }
  .stamm-form textarea { padding:8px 10px; font-size:16px; }
  #gew-formular-karte .stamm-form-abschnitt:nth-of-type(1) .stamm-form-raster,
  #gew-formular-karte .stamm-form-abschnitt:nth-of-type(2) .stamm-form-raster { grid-template-columns:repeat(2, minmax(0, 1fr)); }
  .stamm-form-schalter { gap:10px; margin-top:10px; }
  .stamm-form-schalter label { font-size:14px; }
  .stamm-form-seetypen { display:block; }
  .stamm-form-seetypen > div { margin-top:8px; }
  .stamm-form-seetypen > div > div {
    display:grid !important; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:6px !important;
  }
  .stamm-form-seetypen select { width:100% !important; max-width:none !important; }
  .stamm-form-seetypen > div:last-child > div { grid-template-columns:repeat(2, minmax(0, 1fr)); }
  .stamm-form-seetypen > div:last-child label { white-space:normal !important; }
  .stamm-form-fuss {
    position:sticky; bottom:0; z-index:5;
    margin:0 -10px; padding:10px 10px calc(10px + env(safe-area-inset-bottom, 0px));
    background:#fff; border-top:1px solid var(--line); border-radius:0 0 10px 10px;
    box-shadow:0 -4px 12px rgba(15,23,42,.06);
  }
  .stamm-form-fuss .btn { flex:1 1 0; padding:10px 12px; }
}
@media (max-width: 520px) {
  .stamm-form-raster,
  #art-bearbeiten-formular .stamm-form-abschnitt:first-of-type .stamm-form-raster,
  #art-bearbeiten-formular .stamm-form-abschnitt:nth-of-type(2) .stamm-form-raster,
  #ms-formular-karte .stamm-form-raster,
  #gew-formular-karte .stamm-form-abschnitt:nth-of-type(1) .stamm-form-raster,
  #gew-formular-karte .stamm-form-abschnitt:nth-of-type(2) .stamm-form-raster,
  .stamm-form-seetypen > div:last-child > div { grid-template-columns:1fr; }
}
/* --- Vorschlagsliste unter einem Textfeld (vorschlag.js) -----------------
   Optik wie die Treffer der Art-Suche im Erfassen-Formular
   (.beob-suche-treffer, steht dort im Panel selbst): weißer Layer am Feld,
   Hervorhebungsbalken in der Hauptfarbe. Der Layer hängt am Feld, nicht am
   Dokument - er wandert beim Scrollen mit. */
.vorschlag-wrap { position:relative; }
.vorschlag-status { display:block; font-size:12px; color:var(--muted); min-height:1em; margin-top:2px; }
.vorschlag-liste {
  position:absolute; top:calc(100% - 1.2em); left:0; z-index:50;
  width:max(100%, 340px); max-width:min(480px, 90vw); max-height:320px; overflow-y:auto;
  background:#fff; border:1px solid var(--line); border-radius:8px;
  box-shadow:0 6px 20px rgba(0,0,0,.13); text-align:left;
}
.vorschlag-liste[hidden] { display:none; }
.vorschlag-liste button {
  display:block; width:100%; padding:7px 10px; border:0; border-bottom:1px solid rgba(0,0,0,.06);
  background:none; font:inherit; font-size:13px; line-height:1.4; text-align:left; cursor:pointer;
  color:var(--slate);
}
.vorschlag-liste button:last-child { border-bottom:0; }
.vorschlag-liste button:hover,
.vorschlag-liste button.aktiv { background:rgba(0,0,0,.05); box-shadow:inset 3px 0 0 var(--btn-primary); }
.vorschlag-titel { font-weight:600; }
.vorschlag-badge {
  display:inline-block; margin-left:6px; padding:0 6px; border-radius:999px;
  background:var(--bg); border:1px solid var(--line); font-size:11px; color:var(--muted);
}
.vorschlag-meta { display:block; font-size:11px; color:var(--muted); }
.vorschlag-leer { padding:8px 10px; font-size:13px; color:var(--muted); }
/* Bereich "Offline-Nutzung" (Formular "Neuen Bogen eingeben" und "Meine Bögen"):
   startet zugeklappt, der Knopf sitzt rechts. Hier statt im Tab-Block von
   kartieren.php, damit beide Seiten dieselbe Optik haben. */
.offline-bereich {
  margin:0 0 12px; padding:6px 14px 10px; min-width:0;
  border:1px solid #cbd5e1; border-radius:10px; background:#f8fafc;
}
/* Zugeklappt: nur die Beschriftung, kein leerer Rahmen darunter. */
.offline-bereich.zu { border-color:transparent; background:none; padding:0 0 4px; }
/* Knopf rechts statt links: margin-left:auto verschiebt die Legende ans
   rechte Ende; text-align:right am Rahmen ist der Rückfall für Browser,
   die Legenden nur darüber ausrichten (Inhalt bleibt linksbündig). */
.offline-bereich { text-align:right; }
.offline-bereich > legend { padding:0; margin-left:auto; }
.offline-inhalt { text-align:left; }
/* min-height:0 hebt die Handy-Regel "button { min-height:44px }" auf -
   sonst wäre der Knopf dort doppelt so hoch. */
.offline-umschalter {
  display:inline-flex; align-items:center; gap:4px;
  min-height:0; padding:2px 9px; border:0; border-radius:999px; cursor:pointer;
  font-size:11px; line-height:1.4; font-weight:700; letter-spacing:.03em; text-transform:uppercase;
  color:#fff; background:var(--btn-primary);
}
.offline-umschalter:hover { background:var(--btn-primary-d); }
.offline-pfeil { display:inline-block; transition:transform .15s; }
.offline-umschalter[aria-expanded="true"] .offline-pfeil { transform:rotate(90deg); }
#offline-status-kurz, #meine-offline-kurz { text-transform:none; }
.offline-inhalt { display:flex; flex-direction:column; gap:8px; margin-top:4px; }
.offline-inhalt[hidden] { display:none; }
.offline-zeile { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
@media (max-width: 900px) {
  .offline-bereich { padding:6px 10px 10px; }
  .offline-bereich.zu { padding:0 0 4px; }
}
/* Tab "Seen": ✓ Freigeben mit ✕ Ablehnen darunter (offene Seen) - der seitliche
   Abstand von .sd-aktion (admin.css) entfällt. */
.gew-entscheiden .sd-aktion, .ms-entscheiden .sd-aktion { margin:0; }