/* seite.css — aus atlas/index.html ausgelagert (#1014): <style>-Bloecke und style-Attribute, damit style-src ohne unsafe-inline gilt. */
    /* v3: D3-Canvas füllt #map (unter dem crt-overlay) */
    #map-container { position: relative; }
    #map { position: absolute; inset: 0; overflow: hidden; }
    .sa-map-canvas { display: block; }

    /* #699 Lage-Cockpit: chrome-loser Panel-Modus (same-origin in die geheime Lage-Seite eingebettet).
       Body ist Flex-Column (Header / main-layout flex:1 / Footer) → Header+Footer weg = main-layout füllt den iframe. */
    html.cockpit .tt-header,
    html.cockpit .tt-footer,
    html.cockpit #map-controls-panel,
    html.cockpit #sa-banner,
    html.cockpit #map-burger-btn,
    html.cockpit #sidebar-toggle-btn { display: none !important; }

    /* #718 ZEITSCHALTER — Gate verengt. Bis 2026-07-27 stand hier `html.cockpit #sa-timebar`, also
       im Cockpit hart aus, begründet mit „Zeit steuert das Terminal". Das stammte aus der Kernel-Ära
       und trägt nicht mehr: CHR vermisst den Zeitschalter, und der Dirigent fährt dieselbe Achse
       über welt.zeit → setZeitfenster. Der Scrubber (js/sa-timebar.js + initTimebar) ist eine
       fertige, abgenommene Komponente mit Histogramm, Fenster-Chips und Tiefzeit — er wird
       freigeschaltet statt nachgebaut. NUR im BROADCAST bleibt er unsichtbar: dort bedient
       niemand, dort fährt die Regie. */
    html.cockpit.pult-sendung #sa-timebar { display: none !important; }
    /* #950 H1: wo die Zeitachse ausgeblendet ist, braucht das Panel den Streifen nicht
       freizuhalten — sonst schwebte es im Sendebild ohne Grund 82 px ueber der Kante. */
    html.cockpit.pult-sendung #map-controls-panel { bottom: 24px; }
    /* Im Cockpit rechtsbündig statt mittig: unten links sitzt der Ebenen-Filter (.wf im td1-Dokument). */
    /* ⚠ Im Cockpit KEIN Raster: html.cockpit blendet Kopfzeile, Fusszeile und beide Schienen aus,
       die Karte fuellt den iframe allein. Die Achse bleibt dort die schwebende Insel, die sie war —
       rechtsbuendig, weil unten links der Ebenen-Filter des td1-Dokuments sitzt. */
    html.cockpit #sa-timebar { position: absolute; grid-area: auto; bottom: 8px;
      left: auto; right: 12px; transform: none; width: min(620px, 62%); border: 1px solid var(--at-linie); }
    html.cockpit .sa-support { display: none !important; }   /* #718 CHR: Cockpit ist intern — kein Spendenlink im Sendebild (öffentliche Seite behält ihn) */
    html.cockpit-ort .sidebar { display: none !important; }  /* ORT = voll chrome-los: nur die nackte 2D-Karte */

    /* ── #718 Das Pult: die WELT-Sidebar im Cockpit ────────────────────────────────────────────
       Umschaltbares OSINT-/FORSCHUNGS-Panel statt der Publikums-Sidebar. Ersetzt im Cockpit-WELT
       Tabs, Aktionen und den „BEREIT_"-Platzhalter (eine Bedienungsaufforderung an einen Schirm
       ohne Maus). Öffentliche Seite: kein html.cockpit → völlig unberührt. */
    /* Breite: 300 → 340 → 380px. Unter td1-zoom:0.8 sind 380 CSS-px erst ~304 physische px auf
       1080p — bei 340 liefen Ortsnamen und Tausenderzahlen weiter aus der Spalte. Die rechte
       Grid-Spalte ist 1fr, der Globus verliert also nur die Differenz. */
    html.cockpit-welt .sidebar { width: 380px; }
    html.cockpit-welt .sidebar-tabs,
    html.cockpit-welt .sidebar-actions { display: none !important; }
    html.cockpit-welt .sidebar-header { padding-top: 42px; }  /* 36px Ruhezone: darüber liegen Sende-Ident und #welt-stat */
    html.cockpit-welt .sidebar-title  { display: none; }      /* der Streckenkopf ersetzt „▸ INTELLIGENCE" */
    /* Das Pult IST der Sidebar-Inhalt — die Publikums-Panes darunter verschwinden. Damit geht auch
       der Platzhalter „BEREIT_ · Land oder Entität wählen" weg (eine Bedienungsaufforderung an einen
       Schirm ohne Maus) und die klickbaren Artikel-/Entitätslisten, die im Broadcast ein
       Sende-Unfall auf Knopfdruck wären. Fokus-Informationen trägt der Pult-Block FOKUS selbst. */
    html.cockpit-welt .sidebar-body > .tab-pane { display: none !important; }
    html.cockpit-welt .sidebar-footer { display: none; }      /* Quellen-Zustand steht im Pult-Fuß */
    html.cockpit-welt.pult-sendung #tt-pult { pointer-events: none; }   /* Broadcast: nichts anklickbar, kein Sende-Unfall */

    /* Schriftgrad: 11px waren unter td1-zoom:0.8 nur ~8,8 physische px — auf einem TV aus
       Sitzabstand nicht mehr lesbar. 12,5px ergeben ~10 physische px. */
    /* ⚠⚠ SCHRIFTGRÖSSEN ALS VARIABLEN (CHR 2026-08-16: „muss schöner eindeutiger lesbar sein").
       WARUM: td1 setzt `documentElement.style.zoom = 0.8` (fitScale, 1920×1080). Die kleinen
       Größen von 9–10 px landeten damit bei 7,2–8,0 PHYSISCHEN Pixeln, und zwar genau auf den
       Zeilen, die sagen was eine Zahl bedeutet und von wann sie ist. Auf einem H.264-Stream
       frisst das Kompressionsrauschen so etwas weg.
       ⚠ Der Kommentar in pultFeedKante behauptete, „das Sendeprofil setzt andere Schriftgrößen
       als das Cockpit" — DAS WAR UNWAHR: `pult-sendung` machte genau drei Dinge (Klasse setzen,
       Zeitleiste ausblenden, Klickbarkeit nehmen), keine einzige Größe. Mit diesem Block wird
       die Behauptung wieder wahr. */
    /* ⚠ 2026-09-04 · DAS KLEID HAENGT AB JETZT AN EINER KLASSE, NICHT AN EINER ID.
       Grund: die Land-Leiste benutzt dieselben Bloecke (pultUmwelt/pultKopraesenz/pultFeed …),
       und alle 42 Regeln hier waren auf `#tt-pult` gescoped — im `#land-werte` griff KEINE.
       Der Block war wiederverwendet, sein Kleid nicht: kein .p-row-Flex (Label und Wert liefen
       in einer Zeile zusammen), keine .z-mess/.z-rech-Farben — die FORMENLEHRE war dort
       unsichtbar. Befund von Fable, nachgemessen.
       ⇒ `.p-flaeche` traegt das Kleid, `#tt-pult` bleibt das Sendebild-MOEBEL (Position,
         Rahmen, Sendeprofil). Zwei Dinge, die vorher eins waren.
       ⚠ Bewacht von _test/pult-abdruck.mjs — er haelt Blockfolge, Klassenmenge und die
         GERECHNETEN Schriftgroessen fest. Vor diesem Umbau aufgenommen, danach geprueft. */
    .p-flaeche { font-family: 'Share Tech Mono', monospace; color: var(--at-schrift);
      --p-fs-basis: 12.5px;   /* Werte in .p-row */
      --p-fs-kopf:  11px;     /* Gruppen-/Blockköpfe .p-gruppe-h · .p-h */
      --p-fs-klein: 11px;     /* .p-zeile · .p-sub · .p-leer · .p-fuss — die Erklärzeilen */
      --p-fs-gross: 19px;     /* .p-gross */
      /* Kontrast gegen den Grund #120d07, gerechnet: Kopf 6,99:1 · Klein 6,23:1.
         Vorher stand beides auf #7a6a3a = 3,64:1, also unter dem Fließtext-Minimum. */
      --p-farbe-kopf:  #b9974a;
      --p-farbe-klein: #a89050;
      font-size: var(--p-fs-basis);
      display: flex; flex-direction: column; gap: 8px; line-height: 1.45;
      /* .sidebar-body hat padding:0 — ohne das hier klebten die rechtsbündigen Zahlen direkt am
         Bildschirmrand und wirkten abgeschnitten, obwohl sie vollständig waren. */
      padding: 0 13px 12px; }
    /* Das SENDEBILD wird aus Fernsehentfernung gelesen, das Cockpit aus Armlänge. Deshalb eine
       Stufe größer — und nur hier, damit Chris am Board die Dichte behält.
       ⚠ Mehr Größe heißt WENIGER Zeilen: pultFeedKante schneidet den Feed auf die Spaltenhöhe.
       Das ist gewollt, muss aber nachgemessen werden (siehe dort). */
    html.pult-sendung #tt-pult {
      --p-fs-basis: 14px; --p-fs-kopf: 13px; --p-fs-klein: 12.5px; --p-fs-gross: 22px; }
    /* #718 DER FEED FÜLLT DIE SPALTE. Gemessen im laufenden Sendebild: der Pult nutzte 244 von
       1.283 px, vier Fünftel lagen brach — die Spalte ist `display:block`, darin wächst er nur
       mit dem Inhalt. `.hat-pult` setzt sa-layers.js beim Einhängen; ohne diese Kette greift
       das flex:1 am Feed ins Leere.
       ⚠ min-height:0 ist NICHT kosmetisch: ohne das weigert sich ein Flex-Kind zu schrumpfen,
       overflow greift nie und die Spalte wächst über den Bildrand hinaus. */
    .sidebar-body.hat-pult { display: flex; flex-direction: column; min-height: 0; }
    #tt-pult { flex: 1 1 auto; min-height: 0; }
    .p-flaeche .p-feed { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
    .p-flaeche .p-feed-liste { flex: 1 1 auto; min-height: 0; overflow: hidden; }
    /* #718 Subfelder je Art (CHR: „das Feld in Alarm-Subfelder aufteilen und benennen").
       Der Gruppenkopf traegt die Trennung — eine zusaetzliche Linie waere doppelte Gliederung. */
    .p-flaeche .p-gruppe + .p-gruppe { margin-top: 6px; }
    .p-flaeche .p-gruppe-h { display: flex; justify-content: space-between; align-items: baseline;
      color: var(--p-farbe-kopf); font-size: var(--p-fs-kopf); letter-spacing: .14em;
      border-top: 1px solid var(--at-linie); padding-top: 4px; margin-bottom: 3px; }
    /* ⚠ DER NAME STAND DUNKLER ALS SEIN EIGENER KOPF (#7a6a3a auf #9a8038) — das wichtigste
       Wort der Zeile hatte den schlechtesten Kontrast. Jetzt umgekehrt: der Name trägt die
       Kopffarbe, der Zusatz daneben die gedämpfte. */
    .p-flaeche .p-gruppe-h .n { color: var(--p-farbe-kopf); flex: none; }
    /* Der Zusatz steht klein zwischen Name und Zahl — er beantwortet „wonach gezaehlt?"
       bzw. seit 2026-08-16 auch „von WANN?" („· jetzt", „· Jahresmittel 2024") und darf den
       Namen nicht ueberschreien. */
    .p-flaeche .p-gruppe-h .f { color: var(--p-farbe-klein); letter-spacing: .06em;
      font-size: var(--p-fs-klein); margin-left: 6px; flex: 1 1 auto; }
    /* Alarm-Gruppen tragen die Farbe im KOPF, nicht in jeder Zeile — sonst schreit die halbe
       Spalte rot und die Rangfolge innerhalb der Gruppe geht unter. */
    .p-flaeche .p-gruppe.g-alarm > .p-gruppe-h { color: #e74c3c; border-top-color: #5c2a1e; }
    /* Alarm-Rot wie die Kugel es führt (ALARM_EBENEN / deckung=alarme), nicht das Amber der Blöcke. */
    .p-flaeche .z-alarm { color: #e74c3c; }
    .p-flaeche .p-kopf { border-bottom: 1px solid var(--at-linie); padding-bottom: 6px; }
    .p-flaeche .p-titel { color: var(--at-schrift-hell); font-size: 13px; letter-spacing: .06em; line-height: 1.25; }
    .p-flaeche .p-klasse { font-size: 10px; letter-spacing: .12em; margin-top: 3px; }
    .p-flaeche .p-klasse.k-echtzeit   { color: var(--at-schrift-hell); }
    .p-flaeche .p-klasse.k-tagesbefund{ color: #b9974a; }
    .p-flaeche .p-klasse.k-bestand    { color: var(--at-schrift-leise); }
    .p-flaeche .p-zeile { color: var(--p-farbe-klein); font-size: var(--p-fs-klein); margin-top: 2px; }
    .p-flaeche .p-warn  { color: #d08a30; }
    /* Umschalter — sitzt am Platz der alten Tabs */
    .p-flaeche .p-modus { display: flex; gap: 4px; }
    .p-flaeche .p-modus button { flex: 1; cursor: pointer; font: inherit; font-size: 10px; letter-spacing: .16em;
      background: var(--at-grund-kasten); color: var(--at-schrift-leise); border: 1px solid #2e2410; padding: 4px 6px; }
    /* ⚠ AKTIV = GEFÜLLTE FLÄCHE, nicht nur ein Rahmen. Vorher unterschied den aktiven Knopf ein
       1-px-Rahmen plus etwas hellere Schrift auf fast gleichem Grund (#1c1409 gegen #120d07).
       Im Cockpit reicht das; im BROADCAST nicht: bei 1080p und 6.000 kbit/s bleibt von einem
       Pixel Rahmen nichts übrig — CHR hielt den richtigen Zustand deshalb für einen Fehler
       (2026-08-06). Umkehrung statt Verzierung, die trägt durch jede Kompression.
       ⚠ Zu prüfen ist das am SENDEBILD, nicht im Cockpit: dort war es nie das Problem. */
    .p-flaeche .p-modus button.on { color: var(--at-grund-kasten); border-color: var(--at-schrift); background: var(--at-schrift);
      font-weight: 700; }
    .p-flaeche .p-modus button .auto { color: var(--at-schrift-fern); font-size: 8px; letter-spacing: 0; }
    .p-flaeche .p-modus button.on .auto { color: #4a3c12; }
    /* Blöcke */
    /* ⚠ Die Trennlinie war #241b06 auf #120d07 = 1,14:1 — rechnerisch unsichtbar. Die Blöcke
       standen faktisch als durchlaufende Liste da. #3a2a10 (1,40:1) ist dieselbe Linie, die
       .p-kopf/.p-fuss/.p-gruppe-h schon führen — eine Trennstärke im ganzen Pult, nicht zwei. */
    .p-flaeche .p-block { border-top: 1px solid var(--at-linie); padding-top: 6px; }
    /* Sperrung von .22em auf .14em: bei einer Monospace kostet weite Sperrung zusätzlich
       Lesbarkeit, und .p-gruppe-h fährt längst .14em. */
    .p-flaeche .p-h { color: var(--p-farbe-kopf); font-size: var(--p-fs-kopf); letter-spacing: .14em; margin-bottom: 4px; }
    .p-flaeche .p-loesch { cursor: pointer; color: #b06a2a; margin-left: 4px; letter-spacing: 0; }
    .p-flaeche .p-loesch:hover { color: var(--at-schrift-hell); }
    .p-flaeche .p-gross { color: var(--at-schrift-hell); font-size: var(--p-fs-gross); line-height: 1.1; }
    .p-flaeche .p-sub { color: var(--p-farbe-klein); font-size: var(--p-fs-klein); }
    /* Label darf schrumpfen und mit … enden, der Wert nie — sonst drückt ein langer Ländername
       die Zahl aus der Spalte. min-width:0 ist Pflicht, sonst ignoriert das Flex-Kind das Ellipsis. */
    .p-flaeche .p-row { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
    .p-flaeche .p-row > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .p-flaeche .p-row .v { color: var(--at-schrift-hell); white-space: nowrap; flex: none; }
    /* Ereigniszeile: feste Spalten für Marke und Uhrzeit, der Ort füllt den Rest und endet mit … */
    .p-flaeche .p-ev { display: flex; gap: 6px; align-items: baseline; }
    .p-flaeche .p-ev > .t { color: var(--at-schrift-matt); flex: none; font-variant-numeric: tabular-nums; }
    .p-flaeche .p-ev > .w { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    /* ⚠ Alarm-Zeilen: eine schmale Kante, sonst nichts. Der Gruppenkopf sagt „7/54" — darunter
       stehen alle 54, und ohne Markierung sah man nicht, wo die sieben aufhören (CHR 2026-08-06).
       Bewusst KEINE Farbe und kein zweites Zeichen: die Gattungs-Marke (gemessen/gerechnet/
       gestört) bleibt die Hauptaussage der Zeile und darf nicht übertönt werden. */
    .p-flaeche .p-ev.ist-alarm { border-left: 2px solid var(--at-schrift); padding-left: 5px; margin-left: -7px; }
    /* ⚠ Stand auf #5a4a28 = 2,25:1 — der Satz, der ERKLÄRT warum nichts da ist, war der
       unlesbarste im ganzen Pult. #8a7a40 = 4,55:1. */
    .p-flaeche .p-leer { color: var(--at-schrift-leise); font-size: var(--p-fs-klein); font-style: italic; }
    /* Bildsprache (SCHATTENATLAS_LAYER.md §7b): gefüllt=gemessen · hohl=gerechnet · Schraffur=gestört */
    .p-flaeche .z-mess { color: var(--at-schrift-hell); } .p-flaeche .z-rech { color: var(--at-schrift-matt); } .p-flaeche .z-stoer { color: #b06a2a; }
    .p-flaeche .p-fuss { border-top: 1px solid var(--at-linie); padding-top: 5px; color: var(--p-farbe-klein); font-size: var(--p-fs-klein); letter-spacing: .06em; }
    /* Die Quellennamen tragen die Auskunft — sie stehen heller als die Legende darunter, damit
       im Sendebild zuerst lesbar ist, WER liefert, und erst danach, was die Zeichen bedeuten. */
    .p-flaeche .p-quellnamen { color: #b39442; letter-spacing: .04em; }
    .p-flaeche .p-bar { height: 3px; background: var(--at-linie); margin-top: 2px; }
    .p-flaeche .p-bar > i { display: block; height: 100%; background: var(--at-schrift); }

    /* #699 v2: kein CRT-Scanline/Flicker/Boot innerhalb der Cockpit-Panels.
       Öffentliche Schattenatlas-Seite hat kein html.cockpit → völlig unberührt. */
    html.cockpit body::after,        /* terminal-app.css: kräftiges statisches Raster (z99998) */
    html.cockpit #crt-overlay,       /* crt.css: rollende Scanline + feines Raster + Vignette */
    html.cockpit #crt-boot-overlay { display: none !important; }   /* terminal-app.css: Boot-Flash */
    html.cockpit body { animation: none !important; }              /* crt.css: crt-subtle Flicker (+ dormanter crt-on) */

    /* Atlas v4 (#664) P5 — Höhen-HUD des 3D-Globus: Flughöhe + Zoom-Band + Maßstabsleiste.
       Sitzt IM #globe3d-container (verschwindet also mit ihm) und fängt keine Klicks ab.
       OBEN links: unten links liegt das Karten-Optionen-Panel (bis ~y700), unten rechts die
       Legende — dazwischen ist der freie Streifen unter dem Header. */
    #globe3d-hud { position: absolute; left: 10px; top: 10px; z-index: 2; pointer-events: none;
                   font: 10px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--at-schrift);
                   background: rgba(5,7,12,.72); border: 1px solid #3a2f14; padding: 5px 8px; letter-spacing: .04em;
                   /* body erbt einen Amber-Glow (terminal-app.css:79: text-shadow 0 0 4px). Auf 10px-Ziffern
                      wird der zum Doppelbild — ein Messwert-HUD muss scharf sein, nicht atmosphärisch. */
                   text-shadow: none; }
    #globe3d-hud .g3-band  { color: var(--at-schrift-leiser); font-size: 9px; }
    #globe3d-hud .g3-ort   { color: var(--at-schrift); font-size: 10px; margin: 1px 0 2px; }
    #globe3d-hud .g3-hoehe { color: var(--at-schrift-hell); font-size: 13px; }
    #globe3d-hud .g3-scale { margin-top: 5px; }
    #globe3d-hud .g3-bar   { height: 3px; background: var(--at-schrift); border-left: 1px solid var(--at-schrift-hell);
                             border-right: 1px solid var(--at-schrift-hell); min-width: 8px; }
    #globe3d-hud .g3-num   { color: var(--at-schrift-leiser); font-size: 9px; margin-top: 1px; }

    /* Atlas v4 (#664): DARSTELLUNG im Header — Auswahl + Rotate, entkoppelt von den Ebenen.
       Nutzt bewusst die vorhandene .sa-grid-select-Optik (GITTER-Menü), kein neues Design. */
    /* #767 Ortssuche im Kopf. `position: relative` traegt die Trefferliste, die als Overlay
       darunter haengt — sie darf den Kopf nicht aufblaehen, sonst springt die Karte beim Tippen. */
    /* #838: abgeschaltete Ansicht (RADAR) — sichtbar, aber erkennbar aus, mit dem Grund darunter.
       Der Stil steht HIER und nicht in terminal-app.css: die Datei ist mit der Tribune geteilt
       und tabu. Der :hover-Zustand von .view-btn muss ausdrücklich zurückgenommen werden, sonst
       leuchtet ein gesperrter Knopf beim Überfahren wie ein bedienbarer. */
    .view-btn.ist-aus, .view-btn.ist-aus:hover {
      opacity: .42; cursor: default; background: none; border-color: var(--border);
      color: var(--amber-dim); text-shadow: none; box-shadow: none; line-height: 1.15;
    }
    .view-btn.ist-aus .view-badge { display: block; font-size: 7px; letter-spacing: .05em; opacity: .85; margin-top: 1px; }
    /* #767 Gebiets-Dossier im INTELLIGENCE-Panel. Nur die drei Klassen, die es ueber die
       vorhandenen (.land-detail/.land-coords/.ereignis-item/.keine-daten) hinaus braucht —
       terminal-app.css bleibt tabu, sie ist mit der Tribune geteilt. */
    .gebiet-gruppe { color: var(--at-schrift); font-size: 10px; letter-spacing: .12em; margin: 14px 0 6px;
      padding-bottom: 3px; border-bottom: 1px solid #2a1e0c; }
    .gebiet-fein { color: var(--at-schrift-leise); font-size: 10.5px; line-height: 1.45; margin-top: 3px; }
    .gebiet-warn { color: #c07a3a; font-size: 10.5px; line-height: 1.45; margin-top: 5px; }
    /* #796 — die zwei Hälften der Deutungsschicht. Sie sind bewusst SCHWÄCHER gesetzt als
       .gebiet-gruppe: HEUTE/GEDEUTET teilen eine Gruppe, sie eröffnen keine zwei. */
    .nomos-halb { color: #a89050; font-size: 9.5px; letter-spacing: .16em; margin: 9px 0 4px; }
    .nomos-ohne { color: #6d6038; font-size: 10px; font-style: italic; margin-top: 2px; }
    .tt-suche { position: relative; display: flex; gap: 4px; align-items: center; margin-left: 10px; }
    .tt-suche #sa-such-feld { background: var(--at-grund); color: var(--at-schrift-hell); border: 1px solid var(--at-linie); width: 150px;
      font-family: 'Share Tech Mono', monospace; font-size: 11px; padding: 4px 7px; letter-spacing: .04em; }
    .tt-suche #sa-such-feld:focus { outline: none; border-color: var(--at-schrift); box-shadow: 0 0 5px rgba(200,168,75,.35); }
    .tt-suche #sa-such-feld::placeholder { color: var(--at-schrift-fern); }
    .tt-suche #sa-such-hier { background: var(--at-grund-hoch); color: var(--at-schrift); border: 1px solid var(--at-linie); cursor: pointer;
      font-family: 'Share Tech Mono', monospace; font-size: 12px; padding: 3px 7px; line-height: 1; }
    .tt-suche #sa-such-hier:hover { border-color: var(--at-schrift); }
    .tt-suche #sa-such-hier.laeuft { opacity: .5; cursor: default; }
    #sa-such-liste { position: absolute; top: 100%; left: 0; z-index: 60; width: 320px; max-height: 300px;
      overflow-y: auto; background: var(--at-grund); border: 1px solid var(--at-linie); margin-top: 2px;
      box-shadow: 0 6px 18px rgba(0,0,0,.6); }
    #sa-such-liste .tr { padding: 6px 9px; cursor: pointer; border-bottom: 1px solid #1c1408;
      font-family: 'Share Tech Mono', monospace; font-size: 11px; color: var(--at-schrift); }
    #sa-such-liste .tr:last-child { border-bottom: none; }
    #sa-such-liste .tr:hover, #sa-such-liste .tr.aktiv { background: var(--at-grund-hoch); color: var(--at-schrift-hell); }
    #sa-such-liste .tr .wo { color: var(--at-schrift-leiser); font-size: 9.5px; margin-top: 2px; letter-spacing: .05em; }
    /* ⚠ Der leere Fall ist ein eigener, SICHTBARER Zustand — keine stille leere Liste. */
    #sa-such-liste .leer { padding: 8px 9px; color: var(--at-schrift-leise); font-family: 'Share Tech Mono', monospace; font-size: 10.5px; }
    /* ⚠ Dieselbe Falle wie bei .sa-such-nur3d: der Kopf ist 44 px hoch, alles mit top:100% haengt
       darunter und verschwand unter der Karte. Seit der Standort-Kaskade sind die Texte ausserdem
       deutlich laenger ("In deinem Revier: nichts. Naechster Alarm 40 km (Sektor): …") — die Zeile
       braucht Hintergrund, z-index UND Umbruch. Leer bleibt sie unsichtbar (:empty), sonst staende
       staendig ein leerer Kasten im Kopf. */
    .sa-such-stand { position: absolute; top: 100%; left: 0; margin-top: 2px; font-size: 9px; color: #a8934f;
      font-family: 'Share Tech Mono', monospace; max-width: 340px; z-index: 60;
      background: var(--at-grund); border: 1px solid #2a1e0c; padding: 4px 7px; line-height: 1.35; }
    .sa-such-stand:empty { display: none; }
    /* #767: oeffentlich ist die Suche ein 3D-Merkmal. Gesperrt heisst NICHT tot — der Klick
       wechselt auf die Kugel, deshalb bleibt der Zeiger ein Zeiger und der Grund steht sichtbar
       darunter (ein title ist auf dem Tablet unsichtbar). */
    .tt-suche.ist-aus #sa-such-feld, .tt-suche.ist-aus #sa-such-hier { opacity: .42; }
    .tt-suche.ist-aus { cursor: pointer; }
    /* ⚠ Der Kopf ist nur 44 px hoch (.tt-header, align-items:center). Eine Zeile mit top:100%
       ragt darunter hinaus, und ihr Fuss verschwand unter der Karte — CHR: "durch das Menü-Banner
       2 px abgeschnitten". Die Trefferliste im selben Bauteil hatte das nie, weil sie z-index UND
       einen eigenen Hintergrund traegt. Genau das bekommt die Zeile jetzt auch: kein neues Muster,
       sondern das vorhandene. */
    .sa-such-nur3d { position: absolute; top: 100%; left: 0; margin-top: 2px; white-space: nowrap;
      font-family: 'Share Tech Mono', monospace; font-size: 9px; color: #8a6a2a; letter-spacing: .04em;
      z-index: 60; background: var(--at-grund); border: 1px solid #2a1e0c; padding: 3px 7px; line-height: 1.2; }
    .tt-disp { display: flex; gap: 4px; align-items: center; margin-left: 10px; }
    .tt-disp #disp-select { width: auto; max-width: 132px; font-size: 10px; padding: 4px 20px 4px 7px; }
    .tt-disp #disp-rotate, .tt-disp #disp-terrain, .tt-disp #disp-center, .tt-disp #disp-design { background: var(--at-grund-hoch); color: var(--at-schrift); border: 1px solid var(--at-linie);
      font-family: 'Share Tech Mono', monospace; font-size: 11px; padding: 3px 7px; cursor: pointer; }
    .tt-disp #disp-rotate.active, .tt-disp #disp-terrain.active, .tt-disp #disp-center.active, .tt-disp #disp-design.active { border-color: var(--at-schrift); color: var(--at-klar); box-shadow: 0 0 5px rgba(200,168,75,.35); }
    .tt-disp #disp-rotate:disabled, .tt-disp #disp-terrain:disabled, .tt-disp #disp-center:disabled, .tt-disp #disp-design:disabled { opacity: .35; cursor: default; }   /* nur im 3D-Globus wirksam */

    /* Atlas v4 (#664) P4 — globaler Zeit-Scrubber (nur bei ?timebar=1). Untere Leiste, mittig. */
    /* #950: DIE ACHSE IST KEINE SCHWEBENDE INSEL MEHR, sondern die untere Zeile des Rasters.
       Vorher: `position:absolute; bottom:8px; left:50%; width:min(880px,94%)` — mittig ueber der
       Karte. Auf 800 px war sie damit 752 px breit und lag zwangslaeufig ueber allem, was unten
       links oder rechts sass: Ebenen-Panel (250x15 px), Burger und Sidebar-Knopf (je 44x44).
       Das war keine schlechte Zahl, sondern eine falsche Bauform — eine Leiste, die fuer die
       GANZE Karte gilt, gehoert nicht in die Karte hinein.
       ⚠ Der Cockpit-Zweig (Zeile ~85) setzt sie ausdruecklich wieder absolut; dort gibt es
         kein Raster, weil `html.cockpit` das ganze Chrome ausblendet. */
    #sa-timebar { grid-area: 2 / 1 / 3 / 4; z-index: 1100;
      background: rgba(10,8,6,.9); border-top: 1px solid var(--at-linie); padding: 4px 10px 6px;
      font-family: 'Share Tech Mono', monospace; color: var(--at-schrift); }
    #sa-timebar .tb-hist { display: block; width: 100%; height: 26px; }
    #sa-timebar .tb-row { display: flex; align-items: center; gap: 6px; margin-top: 3px; }
    #sa-timebar input[type=range].tb-stand { flex: 1; min-width: 60px; accent-color: var(--at-schrift); }
    #sa-timebar .tb-label { font-size: 10px; color: var(--at-schrift-hell); min-width: 190px; text-align: right; }
    #sa-timebar .tb-deep { background: var(--at-grund-hoch); color: var(--at-schrift); border: 1px solid var(--at-linie); font-size: 9px;
      font-family: 'Share Tech Mono', monospace; padding: 2px 6px; cursor: pointer; white-space: nowrap; }
    #sa-timebar .tb-deep.active { border-color: var(--at-schrift); color: var(--at-klar); box-shadow: 0 0 5px rgba(200,168,75,.35); }
    #sa-timebar .tb-chips { display: inline-flex; gap: 2px; }
    #sa-timebar .tb-chip { background: var(--at-grund-kasten); color: var(--at-schrift-matt); border: 1px solid #2e2410; font-size: 9px;
      font-family: 'Share Tech Mono', monospace; padding: 2px 5px; cursor: pointer; white-space: nowrap; }
    #sa-timebar .tb-chip.active { border-color: var(--at-schrift); color: var(--at-klar); background: #1c1409; }

    /* Atlas v4 (#664) P6b — Bestands-Charts (orbit_bestand/energie_ausbau), Kontext-Panel unten links. */
    /* #950 B23 (CHR: „warum ist wieder ein zeitbalken im menue"): der Kasten stand auf
       `left:10px; bottom:44px` — also DIREKT ueber dem Ebenen-Panel (`left:20px; bottom:0`),
       breiter als dieses und mit hoeherem z-index darueber gezeichnet. Er sah aus wie ein Teil
       des Menues, und der Jahresregler darin wie ein Zeitbalken im Menue. Jetzt oben mittig:
       dort liegt nichts (Zeitachse unten:8, Zustandsstreifen unten:74, HUD links oben), und der
       Kasten ist als das erkennbar, was er ist — eine Erlaeuterung zur aktiven Ebene. */
    #sa-chart { position: absolute; left: 50%; transform: translateX(-50%); top: 56px; z-index: 1090; width: 280px; display: none;
      background: rgba(10,8,6,.92); border: 1px solid var(--at-linie); padding: 6px 8px;
      font-family: 'Share Tech Mono', monospace; color: var(--at-schrift); font-size: 10px; }
    #sa-chart .ch-row { margin-bottom: 6px; }
    #sa-chart .ch-head { font-size: 10px; color: var(--at-schrift-hell); margin-bottom: 3px; }
    #sa-chart .ch-bar { display: flex; height: 14px; border: 1px solid var(--at-linie); overflow: hidden; }
    #sa-chart .ch-leg { display: flex; flex-wrap: wrap; gap: 5px; font-size: 8.5px; color: var(--at-schrift-leise); }

    /* Ebene in dieser Darstellung nicht renderbar → sichtbar, aber erklärt-inaktiv (#664) */
    .layer-controls label.ist-aus { opacity: .45; }
    .layer-controls label.ist-aus input { cursor: default; }
    .lyr-badge { font-size: 9px; color: var(--at-schrift-leiser); margin-left: 4px; letter-spacing: .04em; }
    .sa-grid-select { width: 100%; background: var(--at-grund-hoch); color: var(--at-schrift); border: 1px solid var(--at-linie);
      font-family: 'Share Tech Mono', monospace; font-size: 11px; letter-spacing: .04em; padding: 4px 22px 4px 8px;
      cursor: pointer; -webkit-appearance: none; appearance: none;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='8'%3E%3Cpath d='M0 1l5 6 5-6' fill='none' stroke='%23c8a84b' stroke-width='1.4'/%3E%3C/svg%3E");
      background-repeat: no-repeat; background-position: right 7px center; }
    .sa-grid-select:focus { outline: none; border-color: var(--at-schrift); }

    /* #731 Deckung: Top-N-Regler (nur sichtbar, wenn das Deckungs-Gitter aktiv ist) */
    .deckung-top { margin-top: 4px; }
    .deckung-top label { display: block; font-size: 9px; letter-spacing: .04em; color: #8a7333; margin-bottom: 2px; }
    .deckung-top #deckung-top-wert { color: var(--at-schrift); }
    .deckung-top input[type=range] { width: 100%; height: 3px; background: var(--at-linie); -webkit-appearance: none; appearance: none; cursor: pointer; }
    .deckung-top input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 9px; height: 13px;
      background: var(--at-schrift); border: 0; cursor: pointer; }
    .deckung-top input[type=range]::-moz-range-thumb { width: 9px; height: 13px; background: var(--at-schrift); border: 0; cursor: pointer; }

    /* Zeitraum-Picker (#405) */
    /* #950 B29: hiess `.zeit-apply-btn` und gehoerte zur entfernten Von/Bis-Auswahl.
       Sie traegt heute den Knopf 'Alle aus' — der alte Name log. Umbenannt statt geloescht. */
    .sa-panel-btn { background: var(--at-grund-hoch); color: var(--at-schrift); border: 1px solid var(--at-linie);
      font-family: 'Share Tech Mono', monospace; font-size: 10px; padding: 2px 8px; cursor: pointer; letter-spacing: .04em; }
    .sa-panel-btn:hover { border-color: var(--at-schrift); color: var(--at-klar); }

    /* Start-Banner (in-page, kein Popup) */
    /* ⚠⚠ DAS BANNER SCROLLT (2026-09-02). Vorher: `align-items:center` OHNE `overflow` — ein
       zentriertes Flex-Kind, das hoeher ist als sein Container, ragt nach BEIDEN Seiten heraus und
       ist nach oben nicht einmal wegzuscrollen. Gemessen auf 390x844 im echten Kurzfassungs-Zustand:
           #sa-banner        y  44, Hoehe 739, overflow-y: visible
           .sa-banner-inner  y  33, Hoehe 762   ← hoeher als das Banner, oben abgeschnitten
           letzte Kachel     y 1068 … 1195      ← 350 px unter dem Schirmrand
       Von elf Lagen waren SECHS per elementFromPoint erreichbar. Darunter fehlte ④ UEBERWACHUNG —
       dieselbe Lage, die am 01.09. schon einmal „im UI unerreichbar" war (H11) und die ich damals
       als Experten-Kachel gerettet habe. Ein Rueckweg, den man an einer Stelle schafft und an der
       naechsten wieder verliert.
       ⇒ `align-items: flex-start` + `margin:auto` am Kasten: zentriert, solange er passt, und
         beginnt oben, sobald er nicht mehr passt — ohne `safe center`, das aeltere Browser nicht
         kennen. Dazu `overflow-y:auto`. `overscroll-behavior:contain` verhindert, dass die Geste am
         Ende der Liste die Karte darunter mitzieht. */
    #sa-banner { position: absolute; inset: 0; z-index: 1500; display: none; align-items: flex-start; justify-content: center;
      overflow-y: auto; overscroll-behavior: contain;
      background: rgba(8,8,6,.78); backdrop-filter: blur(2px); }
    #sa-banner.open { display: flex; }
    .sa-banner-inner { max-width: 760px; margin: auto; padding: 22px 26px; background: rgba(12,10,8,.96); border: 1px solid var(--at-linie); box-shadow: 0 0 30px rgba(0,0,0,.7); }
    .sa-banner-inner h1 { font-family: 'VT323', monospace; color: var(--at-schrift-hell); font-size: 26px; margin: 0 0 4px; letter-spacing: .06em; }
    .sa-banner-inner .sub { color: var(--at-schrift-leise); font-size: 12px; margin-bottom: 16px; font-family: 'Share Tech Mono', monospace; }
    .sa-lenses { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
    .sa-lens { text-align: left; background: var(--at-grund); border: 1px solid var(--at-linie); padding: 12px 13px; cursor: pointer; color: var(--at-schrift);
      font-family: 'Share Tech Mono', monospace; transition: border-color .12s, box-shadow .12s; }
    .sa-lens:hover { border-color: var(--at-schrift); box-shadow: 0 0 8px rgba(200,168,75,.3); }
    .sa-lens .ln { font-family: 'VT323', monospace; font-size: 19px; color: var(--at-schrift-hell); }
    .sa-lens .ld { font-size: 10.5px; color: var(--at-schrift-leise); margin-top: 4px; line-height: 1.35; }
    .sa-lens .lp2 { color: var(--at-schrift-fern); font-size: 9px; margin-top: 5px; letter-spacing: .08em; }
    /* #827: Lage braucht die Kugel → ausgegraut, aber NICHT tot: der Klick wechselt zum 3D-Globus.
       Deshalb bleibt `cursor: pointer` und der Hover-Rahmen erhalten — ein `not-allowed` würde eine
       Sackgasse behaupten, die es nicht gibt. Der Grund steht als Zeile IN der Kachel (.lens-nur3d),
       nicht nur im title: ein Tooltip existiert auf dem Touchscreen nicht. */
    .sa-lens.ist-aus { opacity: .42; border-style: dashed; }
    .sa-lens.ist-aus:hover { opacity: .72; border-color: var(--at-schrift-leise); box-shadow: none; }
    .sa-lens .lens-nur3d { color: #8a6a2a; font-size: 9px; margin-top: 7px; letter-spacing: .06em; }
    .sa-subgrp { font-size: 9.5px; color: var(--at-schrift-leiser); letter-spacing: .12em; margin: 6px 0 1px; opacity: .85; }   /* #468 REALE-WELT-Untergruppen */
    /* ⚠ Der einzige Ausgang aus dem Banner war 214x13 PIXEL gross (gemessen 2026-09-02 auf dem
       Telefon). 13 px sind mit einem Finger nicht sicher zu treffen — die Hausregel aus #424 sagt
       44. Ein Ausgang, den man nicht trifft, ist derselbe Fehler wie ein Ausgang, den man nicht
       sieht; beides stand heute in derselben Flaeche. Die Schrift bleibt klein, die FLAECHE waechst. */
    #sa-banner-skip { margin-top: 14px; background: none; border: none; color: var(--at-schrift-fast); font-family: 'Share Tech Mono', monospace;
      font-size: 11px; cursor: pointer; text-decoration: underline;
      min-height: 44px; padding: 0 12px; }
    #sa-lens-hint { display: none; position: static; transform: none;
      background: rgba(12,10,8,.95); border: 1px solid var(--at-linie); color: var(--at-schrift); font-family: 'Share Tech Mono', monospace;
      font-size: 11px; padding: 7px 14px; }
    /* Archäologie-Zeitachse */
    /* Welt-Zustand-Strip (kosmische Skalar-Zeitreihen / Sacra-Energie) */
    /* Der Stapel sitzt UEBER den beiden Schienen-Griffen. Die Zahl ist gerechnet, nicht geraten:
       Griff 42 px hoch + 14 px Abstand zur Kante + 12 px Luft = 68. Steht die Rechnung hier,
       kann die naechste Sitzung sie nachziehen, statt eine runde Zahl zu waehlen — genau daran
       ist die alte 768 gescheitert. */
    /* ⚠ ZWEI STAPEL, DIE SICH NICHT TREFFEN KOENNEN — gerechnet, nicht geraten.
       Gefunden, als CHRs Telefon-quer-Fall (844x390) in die Formatmatrix kam: die Kartenzelle
       war dort nur 243 px hoch, und 56 (Kasten oben) + 69 + 57 (Stapel unten) + 68 = 250 > 243.
       Sie passten nicht mehr nebeneinander, also ueberlappten sie.
       DIE BEDINGUNG: der obere Kasten belegt [56, 56+h1], der untere [H-68-h2, H-68].
       Ueberlappungsfrei ist das genau dann, wenn h1 + h2 < H - 124.
       Mit `max-height: calc(50% - 64px)` je Stapel gilt h1+h2 = H-128 < H-124 — bei JEDER Hoehe,
       ohne eine weitere Konstante. Auf dem Schreibtisch merkt man davon nichts (409 px je Stapel),
       auf 390 px greift es (59 px je Stapel, dann scrollen sie).
       ⇒ Eine Formel statt einer vierten Zahl: die naechste Fenstergroesse ist damit schon
         mitbedacht, statt beim naechsten Geraet wieder aufzufallen. */
    #sa-chart { max-height: calc(50% - 64px); overflow-y: auto; }
    #sa-meldungen { position: absolute; left: 0; right: 0; bottom: 68px; z-index: 1200;
      max-height: calc(50% - 64px); overflow-y: auto;
      display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none;
      /* Seitlich die Griff-Zone freihalten: Griff 42 + Rand 14 + Luft 8 = 64. Auf einem breiten
         Schirm merkt man davon nichts; auf 390 px reichte der Streifen sonst unter den rechten
         Griff (gemessen 44x6 px). Wieder eine gerechnete Zahl statt einer geratenen. */
      padding: 0 64px; box-sizing: border-box; }
    #sa-meldungen > * { pointer-events: all; }
    #sa-statestrip { display: none; position: static; transform: none;
      width: min(760px, 100%); background: rgba(10,8,6,.86); border: 1px solid var(--at-linie); padding: 4px 7px; }
    #sa-statestrip .ws-head { display: flex; align-items: center; gap: 7px; font-size: 10px; color: var(--at-schrift); margin-bottom: 3px; font-family: 'Share Tech Mono', monospace; }
    #sa-statestrip .ws-tab { background: var(--at-grund-hoch); color: var(--at-schrift-leise); border: 1px solid var(--at-linie); font-family: 'Share Tech Mono', monospace; font-size: 9px; padding: 1px 6px; cursor: pointer; letter-spacing: .04em; }
    #sa-statestrip .ws-tab.active { color: var(--at-klar); border-color: var(--at-schrift); }
    #sa-statestrip .ws-cur { color: var(--at-schrift-hell); } #sa-statestrip .ws-ind { margin-left: auto; color: var(--at-schrift-leise); font-size: 9px; }
    #sa-statestrip .ws-strip { position: relative; height: 16px; background: #140f08; overflow: hidden; }
    #sa-statestrip .ws-cell { position: absolute; top: 0; width: 2px; height: 16px; }
    #sa-statestrip .ws-empty { color: var(--at-schrift-fast); font-size: 9px; padding: 3px; font-family: 'Share Tech Mono', monospace; }
    /* generischer Hover-Tooltip */
    #sa-tooltip { display: none; position: absolute; z-index: 1300; pointer-events: none;
      background: rgba(12,10,8,.95); border: 1px solid var(--at-schrift); color: var(--at-schrift-hell);
      font-family: 'Share Tech Mono', monospace; font-size: 11px; padding: 4px 8px; max-width: 280px; }
    /* Radio-Toggle — Terminal Tribune Radio (Jazz-Stream, an/aus) */
    .sa-radio-btn { background:var(--at-grund-hoch); color:var(--at-schrift); border:1px solid var(--at-linie); font-family:'Share Tech Mono',monospace;
      font-size:11px; padding:4px 9px; cursor:pointer; letter-spacing:.05em; margin-left:10px;
      transition:border-color .12s, box-shadow .12s, color .12s; }
    .sa-radio-btn:hover { border-color:var(--at-schrift); color:var(--at-klar); }
    .sa-radio-btn.on { border-color:var(--at-schrift); color:var(--at-schrift-hell); box-shadow:0 0 7px rgba(200,168,75,.45); }
    .sa-radio-btn.on .sa-radio-ico { display:inline-block; animation:sa-radio-pulse 1.4s ease-in-out infinite; }
    @keyframes sa-radio-pulse { 0%,100%{opacity:1} 50%{opacity:.4} }
    /* Legende ein-/ausklappbar (CHR) — Globus frei sichtbar */
    #sa-legende.collapsed { display: none; }
    /* #950: `position:absolute; bottom:0` gehoerte an den Fuss eines schwebenden Kastens.
       In der Schiene ist der Umschalter eine Zeile wie jede andere. */
    #sa-legende-toggle { position: static; width: 100%; text-align: left; flex: 0 0 auto; pointer-events: all;
      background: var(--at-grund-hoch); border: none; border-bottom: 1px solid var(--at-linie);
      color: var(--at-schrift); font-family: 'Share Tech Mono', monospace; font-size: 10px; letter-spacing: .14em;
      padding: 8px 12px; cursor: pointer; transition: background .12s, color .12s; }
    #sa-legende-toggle:hover { border-color: var(--at-schrift); color: var(--at-klar); }
    #sa-legende-toggle.open { border-color: var(--at-schrift); color: var(--at-schrift-hell); box-shadow: 0 0 12px rgba(200,168,75,.35); }
    @media (max-width: 768px) { #sa-legende.collapsed { display: block; } #sa-legende:not(.collapsed) { bottom: auto; } #sa-legende-toggle { display: none; } }
    /* Panel schmaler cappen (breiter als nötig, CHR). Die .proj-controls-Regel stand hier
       für die DARSTELLUNG-Buttons — die sitzen seit #664 im Header, Regel damit tot. */
    /* #950: war `max-width: 250px`, als der Kasten frei ueber der Karte schwebte. In der
       Schiene bestimmt die Schiene die Breite — eine zweite Breitenangabe waere eine zweite
       Wahrheit darueber, wie breit gesteuert wird. */
    .layer-controls { max-width: none; }
    /* KARTENOPTIONEN-Menü ein-/ausklappbar (CHR) — analog Legende, gibt den Globus frei */
    .layer-controls.collapsed { display: none; }
    #sa-menu-toggle { position: static; width: 100%; text-align: left; flex: 0 0 auto; pointer-events: all;
      background: var(--at-grund-hoch); border: none; border-bottom: 1px solid var(--at-linie);
      color: var(--at-schrift); font-family: 'Share Tech Mono', monospace; font-size: 10px; letter-spacing: .14em;
      padding: 8px 12px; cursor: pointer; transition: background .12s, color .12s; }
    #sa-menu-toggle:hover { border-color: var(--at-schrift); color: var(--at-klar); }
    #sa-menu-toggle.open { border-color: var(--at-schrift); color: var(--at-schrift-hell); box-shadow: 0 0 12px rgba(200,168,75,.35); }
    @media (max-width: 768px) { .layer-controls.collapsed { display: block; } .layer-controls:not(.collapsed) { bottom: auto; } .layer-controls { max-width: none; } #sa-menu-toggle { display: none; } }
    /* #578 CCTV Noir-Monitor — floating Kamera-Panel (Snapshot + Lazy-Stream + Einsatz-Feed) */
    #sa-cctv-panel { position: absolute; top: 14px; right: 14px; z-index: 1200; width: min(400px, calc(100% - 28px));
      background: rgba(12,10,8,.96); border: 1px solid var(--at-linie); box-shadow: 0 0 24px rgba(0,0,0,.75);
      font-family: 'Share Tech Mono', monospace; color: var(--at-schrift); }
    #sa-cctv-panel .cctv-head { display: flex; align-items: center; gap: 7px; padding: 6px 9px; border-bottom: 1px solid var(--at-linie); font-size: 11px; }
    #sa-cctv-panel .cctv-rec { color: #ff3b30; font-size: 9px; letter-spacing: .1em; white-space: nowrap; animation: sa-radio-pulse 1.4s ease-in-out infinite; }
    #sa-cctv-panel #cctv-name { color: var(--at-schrift-hell); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    #sa-cctv-panel #cctv-id { color: var(--at-schrift-leiser); font-size: 9.5px; white-space: nowrap; }
    #sa-cctv-panel #cctv-feed-badge { color: var(--at-signal); font-size: 9px; border: 1px solid var(--at-signal-tief); padding: 1px 4px; white-space: nowrap; }
    #sa-cctv-panel #cctv-close { background: none; border: none; color: var(--at-schrift-leise); cursor: pointer; font-size: 13px; }
    #sa-cctv-panel #cctv-close:hover { color: var(--at-klar); }
    #sa-cctv-panel .cctv-shot { position: relative; background: #000; min-height: 120px; }
    #sa-cctv-panel .cctv-shot img, #sa-cctv-panel .cctv-shot video { display: block; width: 100%; max-height: 260px; object-fit: contain; }
    #sa-cctv-panel .cctv-shot iframe { display: block; width: 100%; aspect-ratio: 16/9; border: 0; background: #000; }   /* P2: kuratierte YouTube-Embeds */
    #sa-cctv-panel .cctv-shot img[hidden], #sa-cctv-panel .cctv-shot video[hidden], #sa-cctv-panel .cctv-shot iframe[hidden] { display: none; }   /* display:block würde hidden sonst übersteuern (v2.5.0-Falle — gilt auch fürs iframe!) */
    /* #604: Artikel-Reader-Overlay (lesbare News-Seite im Iframe) */
    #sa-artikel-panel { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); z-index: 1600; width: min(760px, calc(100% - 40px)); height: min(88%, 900px); background: #0a0c10; border: 1px solid var(--at-linie); border-radius: 6px; box-shadow: 0 18px 60px rgba(0,0,0,.75); display: flex; flex-direction: column; overflow: hidden; }
    #sa-artikel-panel[hidden] { display: none; }
    #sa-artikel-panel .art-head { display: flex; align-items: center; gap: 9px; padding: 7px 11px; border-bottom: 1px solid var(--at-linie); font-size: 12px; background: #0d1015; }
    #sa-artikel-panel .art-mark { color: var(--at-signal); letter-spacing: .12em; white-space: nowrap; }
    #sa-artikel-panel #art-titel { color: var(--at-schrift-hell); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: 'Courier New', monospace; }
    #sa-artikel-panel #art-extern { color: var(--at-schrift-leise); text-decoration: none; font-size: 14px; }
    #sa-artikel-panel #art-extern:hover { color: var(--at-klar); }
    #sa-artikel-panel #art-close { background: none; border: none; color: var(--at-schrift-leise); cursor: pointer; font-size: 15px; }
    #sa-artikel-panel #art-close:hover { color: var(--at-klar); }
    #sa-artikel-panel #artikel-frame { flex: 1; width: 100%; border: 0; background: var(--at-klar); }
    #sa-cctv-panel #cctv-stream-note { position: absolute; bottom: 6px; left: 8px; font-size: 10px; color: #ff9f43; background: rgba(0,0,0,.6); padding: 2px 6px; }
    #sa-cctv-panel #cctv-still-note { padding: 4px 9px 5px; font-size: 9.5px; line-height: 1.35; color: var(--at-schrift-leise); border-bottom: 1px solid #241a0c; }   /* #578 Rest-Polish: ehrlicher Standbild-Hinweis (stream_typ=none) — kein Auto-Poll */
    #sa-cctv-panel #cctv-still-note b { color: var(--at-schrift); font-weight: 600; }
    #sa-cctv-panel .cctv-meta { display: flex; align-items: center; gap: 8px; padding: 5px 9px; font-size: 10px; color: var(--at-schrift-leise); border-bottom: 1px solid #241a0c; }
    #sa-cctv-panel #cctv-quelle { color: var(--at-schrift); }
    #sa-cctv-panel #cctv-stream-btn { margin-left: auto; background: var(--at-grund-hoch); color: var(--at-signal); border: 1px solid var(--at-signal-tief); font-family: inherit; font-size: 10px; padding: 2px 8px; cursor: pointer; }
    #sa-cctv-panel #cctv-stream-btn:hover { border-color: var(--at-signal); color: var(--at-klar); }
    #sa-cctv-panel #cctv-einsaetze { max-height: 200px; overflow-y: auto; padding: 4px 9px 8px; font-size: 10.5px; }
    #sa-cctv-panel .cctv-feed-head { color: var(--at-schrift-leiser); font-size: 9.5px; letter-spacing: .1em; margin: 4px 0; }
    #sa-cctv-panel .cctv-einsatz { margin: 4px 0; line-height: 1.4; }
    #sa-cctv-panel .cctv-einsatz a { color: var(--at-schrift-hell); text-decoration: none; }
    #sa-cctv-panel .cctv-einsatz a:hover { text-decoration: underline; }
    #sa-cctv-panel .cctv-einsatz-zeit { color: var(--at-schrift-leiser); font-size: 9.5px; }
    #sa-cctv-panel .cctv-einsatz-extra { color: var(--at-schrift-fern); font-size: 9px; margin-left: 18px; }
    #sa-cctv-panel .cctv-feed-quelle { color: var(--at-schrift-fast); font-size: 9px; margin-top: 6px; border-top: 1px solid #241a0c; padding-top: 4px; }
    @media (max-width: 768px) { #sa-cctv-panel { position: fixed; top: auto; left: 8px; right: 8px; bottom: 8px; width: auto; max-height: 55vh; overflow-y: auto; z-index: 1400; } }
    /* #578 Menü-Upgrade: Aktiv-Zähler je Gruppe (Badges via updateMenuBadges) */
    .lens-count { color: var(--at-schrift-leiser); font-size: 9px; margin-left: 6px; }
    .lens-count:empty { display: none; }
    /* #578 P2: Rubriken-Umschalter (dynamisch aus /cctv/typen) + Fokus-Chip in Gruppe ④ ÜBERWACHUNG */
    #cctv-rubriken { margin-left: 12px; }
    #cctv-rubriken .cctv-rubriken-hint { font-size: 9px; color: var(--at-schrift-fast); }
    #cctv-rubriken .cctv-rubrik-row { display: flex; align-items: center; gap: 5px; }
    #cctv-rubriken .cctv-rubrik-n { margin-left: auto; color: var(--at-schrift-leiser); font-size: 9px; }
    #cctv-fokus { margin: 4px 0 2px 12px; font-size: 10px; color: var(--at-signal); border: 1px solid var(--at-signal-tief); padding: 2px 6px; }
    #cctv-fokus button { background: none; border: none; color: var(--at-schrift-leise); cursor: pointer; font-size: 11px; }
    #cctv-fokus button:hover { color: var(--at-klar); }
  
    /* #768 S6: die frueheren Lagen bleiben erreichbar, treten aber zurueck.
       Bewusst zugeklappt und gedaempft — sie sind Altbestand, kein gleichwertiges Angebot. */
    #sa-lens-experte { margin-top: 18px; }
    #sa-lens-experte > summary {
      cursor: pointer; opacity: .55; font-size: 13px; letter-spacing: .08em;
      padding: 6px 2px; list-style: none; user-select: none;
    }
    #sa-lens-experte > summary:hover { opacity: .85; }
    #sa-lens-experte[open] > summary { opacity: .8; margin-bottom: 8px; }
    #sa-lens-experte .sa-lens { opacity: .72; }
    #sa-lens-experte .sa-lens:hover { opacity: 1; }
  

/* cytoscape.min.js erzeugt zur Laufzeit ein <style id="__________cytoscape_stylesheet"> mit genau dieser Regel — ein Element dieser ID
   (der <link> auf diese Datei) verhindert das; style-src ohne unsafe-inline sperrt das Laufzeit-Element sonst. */
.__________cytoscape_container { position: relative; }
