/* ====================================================================
   M&W-Framework  ·  © 2026 Tobias Wachtel — Alle Rechte vorbehalten.
   Geschützter Quellcode — Nutzung nur mit schriftlicher Genehmigung.
   ====================================================================
   assets/grund.css — Grundregeln des Kerns, die VOR jedem Theme geladen
   werden (Gegenstück zu `assets/app.js`).

   Zweierlei gehört hier hinein:

     1. Was am SEITENGERÜST hängt und in jedem Theme gleich gelten soll
        (Fuß unten, Gerätebreite, gesperrter Hintergrund).

     2. Der brauchbare GRUNDZUSTAND der Bausteine, die der Kern SELBST ins
        HTML schreibt: Meldung (`mwToast`), Rückfrage (`mwConfirm`),
        Menü-Zeichen, Abzeichen. Wer ein Element erzeugt, muss auch dafür
        sorgen, dass es benutzbar ankommt — sonst hängt es davon ab, ob ein
        Theme zufällig daran gedacht hat. Genau das ist passiert:
        `themes/admin` kannte `.mw-toast` und `.mw-modal` nicht. Die Meldung
        stand am ENDE der Seite (2 883 px weit unten, nie im Bild), und die
        Rückfrage lag ohne Abdunklung mitten im Text — gemessen, nicht
        vermutet. `themes/papier` fehlt bis heute das Menü-Abzeichen, und
        der Updater fasst fremde Themes nie an (`Aktualisierung.php:24`):
        Was dort fehlt, kann NUR der Kern liefern.

   Alles Übrige — Farben, Abstände und Schrift der SEITE — bleibt Sache des
   Themes.

   WICHTIG — das Theme hat immer das letzte Wort. Es wird NACH dieser Datei
   gebündelt und gewinnt deshalb bei jedem Gleichstand.

   ⚠️ Aber NICHT jede Regel hier ist `:where()`. Es gibt drei Gewichte, und
   jedes hat einen Grund, der an Ort und Stelle noch einmal steht:

     · 0,0,1 — der Normalfall (`body:where(:has(> .fuss))`,
       `div:where(.mw-modal)`): Tag-Name plus `:where()`. Jede Theme-Regel
       mit Klasse (0,1,0) gewinnt, ein Theme-Reset `*{margin:0}` (0,0,0)
       verliert. Ohne `:where()` wöge `body:has(> .fuss)` mehr als ein
       schlichtes `body{…}` im Theme — der Kern würde dem Theme die Regel
       aufzwingen, und genau das soll er nicht.
     · 0,1,0 — für Bausteine, die es nur im Kern gibt (`.nav-zeichen`).
       Hier gibt es nichts zu überstimmen; ein Theme, das mitreden will,
       schreibt ohnehin seinen eigenen Kontext davor.
     · 0,2,0 — nur dort, wo der Kern gewinnen MUSS (`body.geraet-handy
       .inhalt`, die erzwungene Handy-Ansicht). Mit `:where()` kam sie
       gegen `.inhalt{max-width:…}` des Themes nicht an: 1 180 px trotz
       „Handy".
==================================================================== */

/* ── Fuß bleibt unten ────────────────────────────────────────────────
   Das Seitengerüst aus `Seite::rumpf()` ist: header.kopf + main.inhalt +
   footer.fuss untereinander. Stehen die drei einfach hintereinander,
   endet der Fuß dort, wo der Inhalt endet — bei einer kurzen Seite also
   mitten im Fenster, mit einer großen leeren Fläche darunter.

   `:has(> .fuss)` greift nur, wenn die Seite diesem Gerüst folgt. Die
   Anmeldeseite (Layout „leer", ohne Fuß) bleibt dadurch unangetastet —
   dort zentrieren die Themes ihre Karte selbst.

   Bewusst im KERN und nicht nur in `themes/standard`: Jedes App-Theme
   bringt sein eigenes `theme.css` mit und müsste den Fix sonst neu
   erfinden. Genau das ist passiert — in 1.8.3 saß er nur im Standard-
   Theme, und in einer App mit eigenem Theme hing der Fuß weiter. */
body:where(:has(> .fuss)){
  min-height:100vh;
  display:flex;
  flex-direction:column;
}
/* flex:1 0 auto — der Inhalt nimmt den freien Platz ein und schiebt den
   Fuß nach unten, schrumpft aber nie unter seine eigene Höhe (0 = kein
   shrink), damit auf langen Seiten nichts gestaucht wird.

   width:100% ist PFLICHT, nicht Kosmetik: `.inhalt` trägt in praktisch
   jedem Theme `max-width` + `margin:0 auto`. Sobald `body` ein Flex-
   Container ist, unterbinden auto-Margins in der QUERachse das Strecken
   (`align-items:stretch`) — das Element fällt dann auf seine INHALTS-
   breite zurück. Im normalen Blockfluss passiert das nicht, deshalb
   fällt es beim Umstellen auf Flex leicht durch: In 1.8.4 schrumpfte
   `.inhalt` dadurch von 1180 px auf 246 px, ein Kachel-Raster
   (`repeat(auto-fit,minmax(190px,1fr))`) von fünf Spalten auf eine.
   Mit width:100% + max-width verhält es sich wieder wie im Blockfluss. */
body:where(:has(> .fuss)) > :where(.inhalt){
  flex:1 0 auto;
  width:100%;
}
/* Auf dem Handy meint 100vh das Fenster OHNE eingeblendete Adressleiste —
   die Seite wäre dann etwas zu hoch. 100dvh misst den sichtbaren Teil. */
@supports (min-height:100dvh){
  body:where(:has(> .fuss)){ min-height:100dvh; }
}

/* ── Grundstock ──────────────────────────────────────────────────────
   Ab 1.9.0. Hier steht ausschließlich, was Browser-Vorgaben NEUTRALISIERT
   — nichts Gestalterisches. Grund: Ein App-Theme ersetzt `themes/standard`
   vollständig und erbt nichts davon. Alles, was nur dort stand, musste
   jedes Theme neu erfinden; vergaß es eins, sah die App kaputt aus.

   Farben, Abstände und Schriften bleiben Sache des Themes. Der Browser
   färbt Rollbalken, Zahlenfelder und Datumswähler von selbst passend,
   sobald das Theme `color-scheme: light` bzw. `dark` setzt — dafür
   braucht es kein eigenes CSS. */

/* Maße rechnen mit Rand und Innenabstand — sonst sprengt jedes Feld mit
   Innenabstand seine Spalte. Stand bisher nur im Standard-Theme. */
*, *::before, *::after{ box-sizing:border-box; }

/* Formularelemente erben die Schrift der Seite. Ohne das setzt der Browser
   seine eigene (meist 13,33 px Arial) — mitten in einer Oberfläche, die
   überall sonst die Theme-Schrift nutzt.

   BEWUSST nur Familie und Größe, NICHT die Kurzform `font:inherit`: Die
   setzt auch die Zeilenhöhe mit. Ein Knopf, dem das Theme nur `font-size`
   gibt, behielte dann die geerbte Zeilenhöhe (1.5 statt `normal`) und
   würde spürbar höher — gemessen wuchs eine lange Seite dadurch um 5 px.
   Farbe bleibt ebenfalls außen vor: Feldfarben hängen am Theme, ein
   `color:inherit` könnte helle Schrift auf hellem Feld erzeugen. */
:where(input, select, textarea, button){ font-family:inherit; font-size:inherit; }

/* Die kleinen Auf-/Ab-Pfeile an Zahlenfeldern zeichnet der Browser in
   seiner eigenen Optik: hell, klobig, mit eigener Trennlinie. In einem
   dunklen Design sieht das nach Fehler aus, und das Feld wird unnötig
   breit. Sie sind reine Zugabe — verstellen geht weiterhin mit den
   Pfeiltasten, dem Mausrad und der Tastatur. */
:where(input[type="number"]){ appearance:textfield; -moz-appearance:textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button{ -webkit-appearance:none; appearance:none; margin:0; }

/* Medien sprengen nie das Layout — ein zu großes Bild schiebt sonst die
   ganze Seite seitlich auf und erzeugt eine waagerechte Bildlaufleiste. */
:where(img, svg, video, canvas){ max-width:100%; }

/* Sichtbarer Fokus für Tastaturbedienung. `:focus-visible` erscheint nur
   bei Tastatur, nicht beim Mausklick. `currentColor` passt sich der
   Textfarbe des Themes an, ohne eine eigene Farbe vorzugeben. */
:where(:focus-visible){ outline:2px solid currentColor; outline-offset:2px; }

/* ── Menü-Knopf: der Grundzustand ────────────────────────────────────
   Den Knopf (☰) liefert der Kern (`Seite::navigation`), und `app.js`
   klappt damit das Menü auf. Ob er ÜBERHAUPT sichtbar ist und ob das
   Menü eingeklappt wird, stand bis 1.10.0 nur in `themes/standard` — ein
   App-Theme bekam also ein Bedienelement, das dauerhaft sichtbar und
   wirkungslos war. Man merkt so etwas schlecht, weil nichts fehlt,
   sondern etwas zu viel da ist.

   Hier steht deshalb nur die FUNKTION: wann der Knopf erscheint und dass
   `.nav.offen` das Menü zeigt. Aussehen (Farbe, Rahmen, Größe, Anordnung
   der Einträge) bleibt vollständig beim Theme.

   Der Umschaltpunkt 820px ist eine Vorgabe. Ein Theme mit eigener Grenze
   setzt seine eigene Media-Query — sie kommt später im Bündel und gewinnt;
   für den Bereich dazwischen dort `display:none` bzw. `display:flex`
   ausdrücklich setzen.

   ACHTUNG bei der Gewichtung: Das Ein-/Ausklappen steht hier BEWUSST nicht
   in `:where()`. Ein Theme setzt typischerweise `.nav{display:flex}` — mit
   `:where()` (Gewicht 0) käme der Kern dagegen nicht an, das Menü bliebe im
   schmalen Fenster ausgeklappt und der Knopf sinnlos (genau so gemessen).
   `.nav:not(.offen)` wiegt eine Klasse mehr und gewinnt. Ein Theme, das es
   anders will, überschreibt es mit `.kopf .nav{…}`. Beim reinen Aussehen
   (`.nav-schalter` im Ruhezustand) bleibt es bei `:where()`.

   WER DIE RICHTUNG DREHT, MUSS DIE AUSRICHTUNG MITDREHEN: Ein Theme setzt für
   die waagerechte Leiste fast immer `.nav{align-items:center}` — völlig richtig.
   Klappt der Kern dieselbe Leiste zur Spalte um, zentriert genau diese Regel die
   Einträge plötzlich WAAGERECHT und lässt sie auf Textbreite schrumpfen: ein
   schmaler, mittiger Stapel statt einer Liste. Deshalb gehören `align-items` und
   `flex-basis` hier dazu — sonst ist die Funktion nur halb hergestellt. Gemessen
   in der Energie-Zentrale (Theme „orbit"), Fenster 390 px.

   Die Mindestgröße des Knopfes ist ebenfalls Funktion, nicht Optik: Ohne sie war
   die Tap-Fläche 18 × 23 px — zu klein zum Treffen. Aussehen (Rahmen, Farbe,
   Schrift) bleibt beim Theme, deshalb per `:where()`. */
:where(.nav-schalter){ display:none; min-width:40px; min-height:40px; }

@media (max-width:820px){
  .nav-schalter{ display:block; }
  .nav:not(.offen){ display:none; }
  .nav.offen{ display:flex; flex-direction:column; align-items:stretch; flex-basis:100%; }
}

/* Dasselbe für die erzwungene Ansicht (Fuß-Umschalter Computer/Tablet/Handy):
   Dort zählt nicht die Fensterbreite, sondern die Wahl des Benutzers. */
body.geraet-handy .nav-schalter, body.geraet-tablet .nav-schalter{ display:block; }
body.geraet-handy .nav:not(.offen), body.geraet-tablet .nav:not(.offen){ display:none; }
body.geraet-handy .nav.offen, body.geraet-tablet .nav.offen{
  display:flex; flex-direction:column; align-items:stretch; flex-basis:100%;
}

/* Das aufgeklappte Menü braucht einen HINTERGRUND — sonst liegen die Einträge
   ohne Abgrenzung auf dem Seiteninhalt und es sieht aus, als schwebten sie
   (gemessen: `rgba(0,0,0,0)`, gemeldet als „poppt einfach oberhalb auf").
   Der Kern stellt hier nur die Lesbarkeit sicher; die Farbe kommt aus der
   Theme-Variable, der Rückfall greift nur, wenn ein Theme sie nicht setzt.
   Rundung und Innenabstand sind bewusst minimal — per `:where()` überschreibt
   ein Theme beides mit einer einzigen Regel. */
@media (max-width:820px){
  :where(.nav.offen){
    background:var(--karte, rgba(20,22,28,.97));
    border-radius:10px; padding:8px; gap:2px;
  }
}
:where(body.geraet-handy, body.geraet-tablet) :where(.nav.offen){
  background:var(--karte, rgba(20,22,28,.97));
  border-radius:10px; padding:8px; gap:2px;
}

/* ── Ansichtswahl: darf umbrechen ───────────────────────────────────
   Seit der vierten Position („Automatisch", 1.11.3) passt die Zeile nicht
   mehr in ein schmales Fenster: gemessen 412 px bei 390 px Fensterbreite —
   die Seite bekam dadurch eine WAAGERECHTE Bildlaufleiste. Umbrechen statt
   überstehen; Farben und Abstände bleiben beim Theme. */
:where(.ansicht-wahl){ display:inline-flex; flex-wrap:wrap; justify-content:center; }
:where(.fuss){ flex-wrap:wrap; }

/* ── Erzwungene Ansicht am großen Bildschirm ─────────────────────────
   Wer im Fuß „Handy" oder „Tablet" wählt, will die schmale Darstellung sehen
   — bisher passierte am Desktop fast nichts. Nur OBERHALB des Umschaltpunkts,
   damit sich auf einem echten Handy nichts ändert.

   ⚠️ Das ist eine Annäherung, keine Simulation: Die `@media (max-width:…)`-
   Regeln eines Themes beziehen sich auf das FENSTER, nicht auf diese Breite —
   sie greifen hier also nicht. Wer eine originalgetreue Vorschau will, hängt
   seine Handy-Regeln zusätzlich an `body.geraet-handy` (so macht es
   `themes/standard`). Genau daran liegt es, wenn die Umschaltung in einem
   App-Theme „nichts tut".

   ACHTUNG Gewichtung — hier bewusst OHNE `:where()`: Ein Theme setzt für den
   Inhalt fast immer `.inhalt{max-width:…}` (Gewicht 0,1,0). Mit `:where()`
   käme der Kern mit Gewicht 0,0,1 nicht dagegen an, und die erzwungene Ansicht
   bliebe wirkungslos — genau so gemessen (1180 px trotz „Handy"). Dieselbe
   Falle wie beim Menü in 1.11.3. `body.geraet-handy .inhalt` wiegt 0,2,0 und
   gewinnt; ein Theme überschreibt es mit `body.geraet-handy .kopf .inhalt`
   oder eigener Angabe. */
@media (min-width:821px){
  body.geraet-handy > .kopf,  body.geraet-handy > .inhalt,  body.geraet-handy > .fuss { max-width:430px; margin-inline:auto; }
  body.geraet-tablet > .kopf, body.geraet-tablet > .inhalt, body.geraet-tablet > .fuss{ max-width:834px; margin-inline:auto; }
}

/* ── Fenster (Dialoge): die Seite dahinter darf nicht scrollen ───────
   Solange ein Fenster offen ist, trägt `body` die Klasse `mw-gesperrt`
   (gesetzt von `assets/app.js`, siehe `mwSeiteSperren`). Ohne das scrollt
   das Mausrad über dem abgedunkelten Rand die Seite DARUNTER weg, während
   das Fenster selbst stehen bleibt.

   Damit der Inhalt beim Sperren nicht um die Breite der verschwindenden
   Bildlaufleiste springt, gleicht `app.js` sie mit einem Innenabstand aus —
   und nur dann. `scrollbar-gutter:stable` wäre der kürzere Weg, kostet aber
   DAUERHAFT Platz: gemessen 10 px weniger Inhaltsbreite bei 375 px Fenster,
   auch wenn gar kein Fenster offen ist. */
body.mw-gesperrt{ overflow:hidden; }

/* Und das Fenster muss SELBST scrollen können — sonst ist ein langer Inhalt
   unerreichbar, sobald die Seite dahinter gesperrt ist. Betrifft den Kasten
   im Fenster, nicht den abgedunkelten Hintergrund: Der trägt `aria-modal`
   in aller Regel am inneren Element (`<div class="…-box" role="dialog"
   aria-modal="true">`). Höhe und Aussehen bestimmt weiterhin das Theme. */
:where([aria-modal="true"]){ max-height:calc(100dvh - 2rem); overflow:auto; }
@supports not (max-height:100dvh){
  :where([aria-modal="true"]){ max-height:calc(100vh - 2rem); }
}

/* ── Meldungen (mwToast) und Rückfragen (mwConfirm): Grundzustand ─────
   Beide erzeugt der Kern (`assets/app.js`) — also sorgt der Kern dafür,
   dass sie in JEDEM Theme sichtbar, modal und über der Seite liegen.
   Bis 1.30.0 standen die Regeln nur in den Themes; `themes/admin` hatte
   keine: Meldung und Rückfrage hingen unterhalb der Seite, ohne Abdunklung.

   Gewichtung `div:where(.x)` = 0,0,1 — wie `body:where(…)` oben:
     · jede Theme-Regel mit Klasse/ID (0,1,0 / 1,0,0) gewinnt;
     · gegen einen Theme-Reset `*{margin:0;padding:0}` (0,0,0) gewinnt der
       Kern — sonst hätte ein Theme ohne eigene Regeln ein Fenster ohne
       Innenabstand.
   ⚠️ NUR Eigenschaften, die standard, orbit UND papier selbst setzen.
   Alles darüber hinaus sickert in ein Theme, das es bewusst weglässt
   (papier: kein Schatten am Fenster, kein Weichzeichner).
   ⚠️ Die Tag-Namen hängen am Markup in app.js (div/p/button). */
div:where(#mw-toasts){
  position:fixed; right:20px; bottom:20px; z-index:2000;
  display:flex; flex-direction:column; gap:10px;
  max-width:min(340px, calc(100vw - 40px));
}
div:where(.mw-toast){
  padding:12px 16px; border-radius:10px; font-size:14px;
  background:var(--karte-fest, var(--karte, #fff)); color:var(--text, #1f2d3d);
  border:1px solid var(--rand, #e3e8f0); border-left:4px solid var(--blau, #2563eb);
  box-shadow:0 8px 30px rgba(15,23,42,.16);
  transition:opacity .4s, transform .4s;
}
div:where(.mw-toast-erfolg){ border-left-color:var(--ok, #16a34a); }
div:where(.mw-toast-fehler){ border-left-color:var(--gefahr, #dc2626); color:var(--fehler-text, #b91c1c); }
/* „gespeichert, aber es tut nicht, was du erwartest" — z. B. „Oeffentlich"
   an einer Seite, die Anmeldung verlangt (module/seiten, ab 1.41.1). */
div:where(.mw-toast-warnung){ border-left-color:var(--gelb, #d97706); }
div:where(.mw-toast-weg){ opacity:0; transform:translateY(8px); }

div:where(.mw-modal-hg){
  position:fixed; inset:0; z-index:3000;
  display:flex; align-items:center; justify-content:center;
  background:rgba(15,23,42,.45);
}
div:where(.mw-modal){
  background:var(--karte-fest, var(--karte, #fff)); color:var(--text, #1f2d3d);
  border:1px solid var(--rand, #e3e8f0); border-radius:12px;
  padding:22px 24px; width:calc(100% - 40px); max-width:380px;
}
p:where(.mw-modal-text){ margin:0 0 18px; font-size:15px; }
div:where(.mw-modal-knoepfe){ display:flex; justify-content:flex-end; gap:10px; }
:where(.mw-modal-knoepfe) > button{
  padding:9px 16px; border-radius:8px; border:0;
  font-size:14px; font-weight:600; cursor:pointer; font-family:inherit;
}
button:where(.mw-modal-ja){ background:var(--blau, #2563eb); color:var(--blau-text, #fff); }
button:where(.mw-modal-nein){ background:transparent; border:1px solid var(--rand, #e3e8f0); color:var(--text-leise, #64748b); }
/* Fokusring: der Kern-Ring `currentColor` wäre auf „Ja" (weiße Schrift)
   weiß auf weißem Fenster — unsichtbar. Ein Theme mit eigenem
   `:focus-visible` (orbit, 0,1,0) gewinnt weiterhin. */
button:where(.mw-modal-ja:focus-visible, .mw-modal-nein:focus-visible){
  outline:2px solid var(--blau, #2563eb); outline-offset:2px;
}

/* ── Abzeichen am Menüpunkt und Punkt an der zugeklappten Gruppe ──────
   `Menue::abzeichen()` hängt ein `<span class="nav-abzeichen">` an einen
   Eintrag („Update 1.31.0", künftig die Zahl ungelesener Nachrichten);
   steckt das Abzeichen in einer ZUGEKLAPPTEN Gruppe, setzt `Menue` beim
   Kopf zusätzlich `<span class="nav-punkt">` (Menue.php:192, :334).

   ⚠️ WARUM im Kern und nicht im Theme: Bis 1.30.0 stand die Gestaltung
   nur in `themes/standard` und `themes/orbit`. `themes/papier` hat sie
   NICHT — dort wäre das Abzeichen ein nackter Inline-Span und der leere
   Punkt (kein Text, keine Fläche) vollständig unsichtbar. Und genau
   dorthin kommt der Hinweis nie von allein: Der Updater fasst fremde
   Themes grundsätzlich nicht an (`Aktualisierung.php:24`), ein Nachtrag
   müsste auf jeder Installation von Hand geschehen. Ein Hinweis, den man
   je nach Theme sieht oder nicht sieht, ist kein Hinweis.

   Farben theme-neutral über zwei Variablen mit Rückfall. ⚠️ Beide oder
   keine: Wer nur `--abzeichen-bg` umsetzt, bekommt irgendwann weiße
   Schrift auf hellem Grund. Ein einzelner Farbwert wie `--warnung` taugt
   hier nicht — in `orbit` ist das ein HELLES Amber mit dunkler Schrift,
   in `admin` ein dunkles Ocker mit heller. Der Rückfall #b45309/#fff ist
   der Wert aus `themes/standard` (Kontrast 4,6:1).

   Gewicht 0,0,1 wie der Block darüber: `themes/standard` (0,1,0) und
   `themes/orbit` (0,1,0) behalten ihre eigene Fassung unverändert. */
span:where(.nav-abzeichen){
  display:inline-block; margin-left:6px; padding:1px 7px; border-radius:999px;
  background:var(--abzeichen-bg, #b45309); color:var(--abzeichen-text, #fff);
  font-size:11px; font-weight:600; line-height:1.5; vertical-align:middle;
}
/* Ohne Text ist es nur ein Punkt — ein leeres Oval mit Innenabstand sähe
   aus wie ein Darstellungsfehler.
   ⚠️ `:empty` steht INNERHALB von `:where()`. Außerhalb wöge die Regel
   0,1,1 (eine Pseudoklasse zählt wie eine Klasse) und schlüge dem Theme
   sein eigenes `.nav-abzeichen` aus der Hand — die Spezifitäts-Falle. */
span:where(.nav-abzeichen:empty){
  padding:0; width:8px; height:8px; border-radius:50%; margin-left:5px;
}
span:where(.nav-punkt){
  display:inline-block; width:8px; height:8px; border-radius:50%;
  background:var(--abzeichen-bg, #b45309); margin-left:6px; vertical-align:middle;
}

/* Knopf „App installieren" (ab 1.20.1). Er zeigt sich nur auf Handy/Tablet
   und nur, wenn die Installation wirklich möglich ist — sichtbar gemacht
   wird er von `app.js`. Gestaltung bleibt beim Theme, das hier ist nur ein
   brauchbarer Grundzustand. */
:where(.mw-install) {
    display: inline-flex; align-items: center; gap: 6px;
    margin-left: 10px; padding: 5px 12px;
    border: 1px solid currentColor; border-radius: 999px;
    background: transparent; color: inherit;
    font: inherit; font-size: .92em; cursor: pointer;
}
:where(.mw-install)[hidden] { display: none; }
:where(.mw-install-zeichen) { font-weight: 700; line-height: 1; }

/* ── Bereichsumschalter — GRUNDGERÜST, gehört in den KERN ──────────────
   `Seite::bereichsWahl()` erzeugt diese Leiste in JEDEM Theme. Bisher
   standen ihre Regeln nur in `themes/standard` und `themes/admin` — ein
   App-Theme kannte sie nicht, und dann erschien neben jedem Symbol auch
   noch sein NAME. Genau so gemeldet von Tobias: „die 3 Symbole sind da,
   aber die Schrift ist immer noch da."

   Der Kern erzeugt ein Bedienelement → der Kern muss auch dafür sorgen,
   dass es benutzbar aussieht. Ein Theme darf es danach umfärben (diese
   Datei wird VOR dem Theme geladen), aber es muss nichts mehr wissen.

   Farben kommen aus Variablen mit Rückfall: Wer `--karte-tief` setzt,
   bekommt seine Farbe; wer nicht, bekommt einen brauchbaren Wert. */
.mw-bereiche {
    display: flex; gap: 2px; padding: 3px; margin-left: auto;
    background: var(--karte-tief, #eef2f8); border-radius: 10px;
}
.mw-bereich {
    display: grid; place-items: center;
    width: 34px; height: 30px; border-radius: 8px;
    color: var(--text-leise, #5a6b80); text-decoration: none;
}
/* ⚠️ Der Name wird VERSTECKT, nicht entfernt.
   `display:none` nähme ihn auch Screenreadern weg — dann hieße der Link
   nur noch „Link". Diese Form hält ihn im Dokument, aber aus dem Bild. */
.mw-bereich-text {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
}
.mw-bereich-zeichen { display: block; }
.mw-bereich:hover { background: var(--karte, rgba(255,255,255,.75)); color: var(--text, #1f2d3d); }
/* Bewusst NICHT `a.mw-bereich.aktiv`: Diese Regel steht hinter `:hover`,
   gewinnt also schon durch die Reihenfolge. Mit dem `a` davor wäre sie
   stärker als die Regel eines Themes — der Kern würde das Theme
   überstimmen, und genau andersherum ist es gemeint. */
.mw-bereich.aktiv { background: var(--blau, #2563eb); color: #fff; }
/* Auf schmalen Schirmen bleibt die Leiste, wo sie ist — drei Symbole
   brauchen keine eigene Zeile. Genau dafür sind sie da. */
@media (max-width: 640px) {
    .mw-bereich { width: 32px; height: 28px; }
}



/* Gemeinsame Inhalts-Fläche – EINE Klasse auf allen Karten/Boxen (Theme-Hook: hier ansetzen, dann ziehen alle mit) */
.mw-flaeche{ background:var(--karte, #ffffff); border:1px solid var(--rand, #e3e8f0); border-radius:16px; }

/* Segmentregler (Aus · An · Auto o. Ä.) — generischer Baustein, siehe Seite::segment().
   Gleiche Optik wie die Sprach-/Ansicht-Umschalter, nur wiederverwendbar. */
.mw-segment{
  position:relative;                 /* Bezug für die gleitende Markierung */
  display:inline-flex; padding:3px; gap:2px;
  border:1px solid var(--rand, #e3e8f0); border-radius:999px; background:var(--karte, #ffffff);
}
/* Die blaue Markierung ist ein EIGENES Element und gleitet über die Leiste —
   beim Ziehen folgt sie dem Finger, beim Loslassen rastet sie sanft ein.
   Wird per JS ergänzt; ohne JS bleibt der Hintergrund am aktiven Knopf. */
.mw-segment-pille{
  position:absolute; top:3px; bottom:3px; left:0; width:0;
  border-radius:999px; background:var(--blau, #2563eb);
  box-shadow:0 1px 3px rgba(37,99,235,.35);
  transition:transform .26s cubic-bezier(.34,1.3,.64,1), width .26s ease;
  pointer-events:none; z-index:0;
}
.mw-segment.mw-segment-glatt > button{ position:relative; z-index:1; }
/* Doppelt gemoppelt vermeiden: mit gleitender Pille darf der Knopf selbst KEINEN
   Hintergrund mehr haben (höhere Spezifität, damit die Reihenfolge egal ist). */
.mw-segment.mw-segment-glatt > button.aktiv{ background:transparent; box-shadow:none; }
/* Beim Ziehen wird die Markierung durchscheinend — sie zeigt dann nur, WO man
   gerade ist; gültig wird der Wert erst beim Loslassen. */
.mw-segment.zieht > .mw-segment-pille{ opacity:.55; box-shadow:none; }
.mw-segment.zieht > button.aktiv{ color:var(--blau, #2563eb); }

/* Verzögerung vor dem Melden (data-verzoegerung="1500"): ein dünner Balken läuft
   unten durch und zeigt, dass gleich etwas passiert — man kann es noch abfangen
   (zurück auf die Ausgangsposition oder Escape). */
.mw-segment-uhr{
  position:absolute; left:6px; right:6px; bottom:2px; height:2px;
  border-radius:2px; background:var(--blau, #2563eb); pointer-events:none;
  transform-origin:left center;
  animation-name:mw-segment-uhr-lauf; animation-timing-function:linear; animation-fill-mode:forwards;
}
.mw-segment.wartet > .mw-segment-pille{ opacity:.75; }
@media (prefers-reduced-motion: reduce){ .mw-segment-uhr{ animation:none; transform:scaleX(1); opacity:.5; } }
@media (prefers-reduced-motion: reduce){ .mw-segment-pille{ transition:none; } }
.mw-segment > button{
  padding:6px 14px; border:0; border-radius:999px; background:transparent;
  color:var(--text-leise, #64748b); font:inherit; font-size:13.5px; line-height:1.2;
  cursor:pointer; white-space:nowrap; transition:background .12s, color .12s;
}
.mw-segment > button:hover:not(.aktiv){ color:var(--blau, #2563eb); background:var(--blau-hell, #eff4ff); }
.mw-segment > button.aktiv{ background:var(--blau, #2563eb); color:#fff; box-shadow:0 1px 3px rgba(37,99,235,.35); }
.mw-segment > button:focus-visible{ outline:2px solid var(--blau, #2563eb); outline-offset:2px; }
/* Wischen: der Finger soll den aktiven Knopf schieben, nicht die Seite scrollen */
.mw-segment{ touch-action:none; }
.mw-segment > button{ user-select:none; -webkit-user-select:none; }
.mw-segment.zieht > button{ transition:none; }
.mw-segment.zieht > button.aktiv{ box-shadow:0 2px 8px rgba(37,99,235,.45); }
/* Auf schmalen Schirmen über die volle Breite, damit die Positionen tippbar bleiben */
@media (max-width: 480px){
  .mw-segment{ display:flex; width:100%; }
  .mw-segment > button{ flex:1; text-align:center; padding:8px 6px; }
}

/* ── Öffentliche Startseite ───────────────────────────────────────── */
.mw-start { display: grid; gap: 20px; }
.mw-start-block {
  background: var(--karte, #fff);
  border: 1px solid var(--rand, #e2e8f0);
  border-radius: 14px;
  padding: 56px 40px;
  text-align: center;
}
.mw-start-block h1 { font-size: 32px; margin: 0 0 12px; line-height: 1.2; }
.mw-start-text {
  color: var(--text-leise, #64748b); font-size: 17px;
  margin: 0 auto 28px; max-width: 620px;
}
.mw-start-knoepfe { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
/* Knöpfe auf der Startseite nie unterstrichen — sie sind Schaltflächen,
   keine Fließtext-Verweise. */
.mw-start-knoepfe .knopf,
.mw-start-knoepfe .knopf:hover { text-decoration: none; }

@media (max-width: 700px) {
  .mw-start-block { padding: 38px 22px; }
  .mw-start-block h1 { font-size: 25px; }
}
/* ── Kacheln, Schalter (Pillen) und Dashboard-Raster ───────────────────
   Standen bisher NUR im Verwaltungs-Design — dabei erscheinen Kacheln
   auch im ARBEITSBEREICH, also unter dem Theme der App. Ohne diese
   Regeln hat eine Kachel kein Raster, und der Schiebeschalter zeigt
   weder Bahn noch Knopf. Fast alles hier ist Struktur; die zwei festen
   Farben sind bewusst neutral. */


/* ── Kachelraster ──────────────────────────────────────────────────── */
.mw-dashboard {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  align-items: start;
}
.mw-dash-spalte { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.mw-kachel { padding: 0; overflow: hidden; position: relative; }
.mw-kachel + .mw-kachel { margin-top: 0; }

.mw-kachel-kopf {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--rand, #e3e8f0);
  background: linear-gradient(#fbfcfe, #f6f8fc);
}
.mw-kachel-titel { font-size: 15px; font-weight: 650; margin: 0; flex: 1 1 auto; }
.mw-kachel-inhalt { padding: 16px; }
.mw-kachel-inhalt > :first-child { margin-top: 0; }
.mw-kachel-inhalt > :last-child { margin-bottom: 0; }

/* Das Zahnrad — der kürzeste Weg von der Kachel in ihre Einstellungen.
   Bleibt blass, bis man die Kachel berührt: sichtbar genug, um zu wissen,
   dass es da ist, leise genug, um nicht zu stören. */
.mw-kachel-zahn {
  background: none; border: 0; cursor: pointer;
  color: var(--text-leise, #64748b); opacity: .45;
  font-size: 15px; line-height: 1;
  padding: 6px; border-radius: 6px;
  flex: 0 0 auto;
}
.mw-kachel:hover .mw-kachel-zahn { opacity: 1; }
.mw-kachel-zahn:hover { background: #eef2f9; color: var(--blau, #2563eb); }
.mw-kachel-zahn:focus-visible { opacity: 1; outline: 2px solid var(--blau, #2563eb); outline-offset: 1px; }

/* Kachel ohne Überschrift: kein Kopfbalken, das Zahnrad schwebt in der Ecke. */
.mw-kachel-ohne-kopf > .mw-kachel-zahn {
  position: absolute; top: 8px; right: 8px; z-index: 2;
}
.mw-kachel-ohne-kopf > .mw-kachel-inhalt { padding-right: 44px; }

/* „+ Kachel hinzufügen" — zeigt, dass hier noch etwas hinkommen kann. */
.mw-kachel-neu-zeile { margin-top: 18px; }
.mw-kachel-neu {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 20px;
  border: 2px dashed #c3d0e4;
  border-radius: var(--radius, 16px);
  color: var(--text-leise, #64748b);
  text-decoration: none;
  background: rgba(255,255,255,.5);
}
.mw-kachel-neu:hover { border-color: var(--blau, #2563eb); color: var(--blau, #2563eb); background: #fff; }
.mw-kachel-neu-plus {
  display: grid; place-items: center;
  width: 28px; height: 28px; border-radius: 8px;
  background: #e3ebf7; color: var(--blau, #2563eb); font-size: 18px; font-weight: 700;
}
.mw-kachel-neu:hover .mw-kachel-neu-plus { background: var(--blau, #2563eb); color: #fff; }

/* ── Schiebeschalter („Pille") ──────────────────────────────────────
   Nachgebaut nach Joomlas `switcher`: graue Bahn, bei „an" grün, der
   runde Knopf wandert. Darunter liegt eine echte Checkbox — sie wird
   ganz normal abgeschickt und ist tastaturbedienbar.
   Der Zustand ist damit auf einen Blick zu sehen; ein Häkchen muss man
   lesen, und bei zwanzig Schaltern untereinander liest man es nicht. */
.mw-pille {
  display: flex; align-items: center; gap: 11px;
  cursor: pointer; user-select: none;
}
.mw-pille input {
  position: absolute; opacity: 0; width: 0; height: 0;   /* da, aber unsichtbar */
}
.mw-pille-bahn {
  position: relative; flex: 0 0 auto;
  width: 46px; height: 26px;
  background: #cbd5e1;
  border-radius: 999px;
  transition: background .18s ease;
}
.mw-pille-knopf {
  position: absolute; top: 3px; left: 3px;
  width: 20px; height: 20px;
  background: #fff; border-radius: 50%;
  box-shadow: 0 1px 3px rgba(16,29,46,.3);
  transition: transform .18s ease;
}
.mw-pille input:checked ~ .mw-pille-bahn            { background: var(--gruen, #2563eb); }
.mw-pille input:checked ~ .mw-pille-bahn .mw-pille-knopf { transform: translateX(20px); }
/* Tastatur: der Fokusring gehört sichtbar an die Bahn, nicht an die
   unsichtbare Checkbox — sonst weiß niemand, wo er gerade steht. */
.mw-pille input:focus-visible ~ .mw-pille-bahn {
  outline: 2px solid var(--blau, #2563eb); outline-offset: 2px;
}

/* Ja/Nein daneben — genau eines ist sichtbar. */
.mw-pille-wort { flex: 0 0 auto; min-width: 34px; font-size: 13px; color: var(--text-leise, #64748b); }
.mw-pille-an   { display: none; }
.mw-pille input:checked ~ .mw-pille-wort .mw-pille-aus { display: none; }
.mw-pille input:checked ~ .mw-pille-wort .mw-pille-an  { display: inline; color: var(--gruen, #2563eb); font-weight: 600; }

/* ── Schmale Bildschirme ───────────────────────────────────────────── */
@media (max-width: 1100px) {
  .mw-dashboard { grid-template-columns: minmax(0, 1fr); }
}
/* ── Menü-Zeichen ──────────────────────────────────────────────────────
   `Menue::baue()` gibt vor jedem Eintrag ein Zeichen aus und kapselt die
   Beschriftung in `.nav-text`. Nur so kann ein Theme die Beschriftung
   ausblenden und die Leiste schmal machen, statt sie hinter einem
   Klappmenü verschwinden zu lassen (Wunsch von Tobias, 23.08.).

   Hier steht nur, was das ZEICHEN SELBST ausmacht — wo die Navigation
   sitzt und wann der Text weicht, entscheidet weiterhin das Theme. */
/* ⚠️ ZEICHEN SIND STANDARDMÄSSIG AUS — sie ersetzen die Beschriftung,
   sie begleiten sie nicht.
   In 1.23.7 standen sie IMMER neben dem Text. In einer Kopfzeilen-
   Navigation mit App-Theme sah das falsch aus; Tobias an der
   Energie-Zentrale: *„die Icons sollen natürlich nur erscheinen, wenn
   kein Platz mehr ist für die Schrift … das sieht sehr komisch aus."*
   Er hat recht: Ein Zeichen NEBEN dem Wort trägt nichts bei, es macht
   die Zeile nur breiter. Sinn hat es erst, wenn das Wort weichen muss.

   Ein Theme schaltet sie deshalb dort ein, wo es `.nav-text` ausblendet —
   und nur dort. Beides gehört zusammen; wer eins ohne das andere setzt,
   bekommt entweder doppelte Information oder gar keine. */
.nav-zeichen {
    display: none;
    flex: 0 0 auto;
    width: 18px; height: 18px;
    /* Für den Fall, dass ein Theme sie einblendet: `inline-block`, NICHT
       `block`. In einer Kopfzeilen-Navigation ist der Link oft kein
       Flex-Container — mit `block` rutscht die Beschriftung darunter und
       der Menüpunkt wird doppelt so hoch. */
    vertical-align: -0.22em;
}
/* Rückfall für Module ohne bekanntes Zeichen: der Anfangsbuchstabe.
   Bewusst dieselbe Grundfläche wie ein SVG, damit nichts springt.
   ⚠️ Rahmen statt Füllung: Mit `background: currentColor` hätte der
   Buchstabe dieselbe Farbe wie seine Fläche und wäre unsichtbar. So
   nehmen Rahmen UND Buchstabe die Textfarbe an — in jedem Theme. */
/* ⚠️ HIER STEHT BEWUSST KEIN `display`.
   Mit `display:grid` hätte diese Regel das `display:none` von
   `.nav-zeichen` überschrieben — gleiche Spezifität, aber später in der
   Datei. Der Buchstabe wäre also SICHTBAR geblieben, obwohl Zeichen aus
   sein sollen: genau der Fehler, den 1.23.8 beheben will, nur für Module
   ohne bekanntes Zeichen. Gemessen, nicht überlegt.
   Die Zentrierung setzt das Theme dort, wo es die Zeichen einblendet. */
.nav-zeichen-buchstabe {
    place-items: center;
    border-radius: 5px;
    border: 1.5px solid currentColor;
    font-size: 10px; font-weight: 700; line-height: 1;
}

/* Trennlinie im Menü (Menue::trenner) und der Schnellzugriff „+". */
.nav-trenner {
    height: 1px; margin: 7px 12px;
    background: currentColor; opacity: .22;
}
/* Link und „+" in EINER Zeile — das „+" bleibt rechts am Rand. */
.nav-zeile { display: flex; align-items: center; gap: 2px; }
.nav-zeile > a:first-child { flex: 1 1 auto; min-width: 0; }
.nav-schnell {
    flex: 0 0 auto; display: inline-grid; place-items: center;
    width: 26px; height: 26px; margin-left: 4px;
    border-radius: 6px; text-decoration: none;
    font-size: 16px; line-height: 1; opacity: .75;
}
.nav-schnell:hover { opacity: 1; background: rgba(127,127,127,.25); }

/* ====================================================================
   themes/orbit/theme.css — Design „Orbit"

   Idee: eine Leitstelle. Dunkler Raum, darin schweben ruhige Tafeln aus
   Milchglas; dahinter dreht sich langsam eine Weltkugel aus Drahtgitter.
   Die Zahlen sind der Hauptdarsteller — deshalb liegen alle Messwerte in
   einer Schreibmaschinenschrift mit gleich breiten Ziffern. Dadurch
   stehen Nachkommastellen untereinander und nichts zappelt, wenn sich
   ein Wert im Sekundentakt ändert.

   Zurückhaltung ist Absicht: EIN kräftiger Akzent (Türkis), sonst ruhige
   Blaugrautöne. Farbe bedeutet hier etwas — Grün/Gelb/Rot sind für
   Zustände reserviert, nicht für Dekoration.

   Aufbau
     1  Farben, Schrift, Maße
     2  Grundlagen
     3  Hintergrund (Kugel, Sterne, Schleier)
     4  Kopf und Navigation
     5  Inhalt, Überschriften
     6  Tafeln und Kacheln
     7  Knöpfe
     8  Formularfelder
     9  Tabellen
    10  Hinweise und Dialoge
    11  Segmentregler, Sprach- und Ansichtswahl
    12  Diagramme
    13  Geräte-Ansichten, Barrierefreiheit
   ==================================================================== */

/* ---------------------------------------------------------------- 1 */
:root{
  /* Höhe der Kopfleiste. Vorgabe für den Fall, dass das Skript (noch) nicht
     gelaufen ist; theme.js misst sie und schreibt den echten Wert hierher.
     Fenster und Überlagerungen halten sich daran, damit sie unter der
     Leiste bleiben statt über sie hinweg. */
  --kopf-hoehe:60px;

  /* Grund: sehr dunkles Blauschwarz — nicht Schwarz, das wirkt tot */
  --tief:#04070E;
  --bg:#070C16;

  /* Tafeln liegen als Milchglas über dem Hintergrund */
  --karte:rgba(14,22,38,.72);
  --karte-fest:#0E1626;          /* wo Transparenz stört (Menüs, Dialoge) */
  --rand:#1E2C48;
  --rand-hell:#2A3C5E;

  /* Schrift: kühles Weiß, gedämpftes Blaugrau. Beide mit Blaustich —
     ein neutrales Grau sähe hier schmutzig aus. */
  --text:#E9EFFA;
  --text-leise:#8598B8;

  /* EIN Akzent: Türkis. Steht für Energie und hebt sich von den
     Zustandsfarben ab, die Grün/Gelb/Rot belegen. */
  --blau:#39E0C4; --blau-dunkel:#21C3A8; --blau-hell:rgba(57,224,196,.12);
  --blau-text:#03231E;                        /* Schrift auf Türkis */
  --akzent:#39E0C4;                           /* Alias für die Module */
  --gruen:#39E0C4; --gruen-dunkel:#21C3A8; --mint:#39E0C4;

  /* Zustände */
  --ok:#35D68C;
  --warnung:#F5B544;
  --gefahr:#FF6161;
  --fehler-bg:rgba(255,97,97,.10); --fehler-text:#FF8B8B; --fehler-rand:rgba(255,97,97,.35);
  --code-text:#39E0C4;

  /* Formularfelder */
  --feld-bg:rgba(6,11,20,.72); --feld-text:#E9EFFA; --feld-rand:#253554;

  --font:'Segoe UI',system-ui,-apple-system,'Helvetica Neue',sans-serif;
  /* Messwerte: gleich breite Ziffern, damit nichts springt */
  --font-zahl:ui-monospace,'SF Mono','Cascadia Mono','JetBrains Mono','Roboto Mono',Consolas,monospace;

  --radius:14px;
  --radius-klein:9px;
  --schatten:0 18px 44px rgba(0,0,0,.45);
  --glanz:inset 0 1px 0 rgba(255,255,255,.05);
}

/* ---------------------------------------------------------------- 2 */
*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0; }

html{ background:var(--tief); }

body{
  min-height:100vh;
  background:transparent;                 /* der Hintergrund kommt aus Ebene 3 */
  color:var(--text);
  /* Sagt dem Browser, dass hier ein dunkles Design läuft. Er färbt daraufhin
     seine EIGENEN Bestandteile passend: Bildlaufleisten, Datums- und
     Farbwähler, Auswahlfelder. Ohne diese Zeile bleiben sie hell und wirken
     wie Fremdkörper — nachbauen lassen sie sich nicht. */
  color-scheme:dark;
  font-family:var(--font);
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}

a{ color:var(--blau); text-decoration:none; }
a:hover{ text-decoration:underline; }

::selection{ background:rgba(57,224,196,.28); color:#fff; }

:focus-visible{ outline:2px solid var(--blau); outline-offset:2px; border-radius:4px; }

/* Bildlaufleisten passend einfärben — sonst leuchtet ein heller Balken */
*{ scrollbar-width:thin; scrollbar-color:var(--rand-hell) transparent; }
*::-webkit-scrollbar{ width:10px; height:10px; }
*::-webkit-scrollbar-track{ background:transparent; }
*::-webkit-scrollbar-thumb{ background:var(--rand-hell); border-radius:8px; border:2px solid transparent; background-clip:content-box; }
*::-webkit-scrollbar-thumb:hover{ background:#3A5079; background-clip:content-box; }

/* ---------------------------------------------------------------- 3
   Hintergrund. Liegt fest hinter allem, scrollt nicht mit und nimmt
   keine Klicks an. Der Schleier legt einen Verlauf darüber: oben und
   unten dunkler, damit Kopf- und Fußzeile lesbar bleiben. */
.ob-hintergrund{
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(1200px 800px at 78% 48%, rgba(20,58,74,.30), transparent 62%),
    radial-gradient(900px 700px at 12% 8%, rgba(28,42,86,.28), transparent 60%),
    linear-gradient(180deg,#050A13 0%,#070C16 45%,#04070E 100%);
}
#ob-globus{ position:absolute; inset:0; width:100%; height:100%; display:block; }
.ob-schleier{
  position:absolute; inset:0;
  background:
    linear-gradient(180deg, rgba(4,7,14,.75) 0%, rgba(4,7,14,0) 22%,
                            rgba(4,7,14,0) 72%, rgba(4,7,14,.85) 100%);
}

/* Alles Sichtbare liegt über dem Hintergrund.

   ACHTUNG beim Inhalt: KEIN z-index. `position:relative` allein genügt,
   damit er über dem Hintergrund-Canvas liegt (positionierte Elemente
   stehen über nicht positionierten, und im DOM kommt der Hintergrund
   vorher). Ein z-index würde `.inhalt` dagegen zu einem eigenen
   STAPELKONTEXT machen — und dann bleibt alles darin gefangen. Ein
   Dialog mit `position:fixed; z-index:60` käme so nie über die
   Kopfzeile (z-index 100), egal wie hoch man seinen Wert dreht. Genau
   das war der Fall beim Bearbeiten-Fenster der Miner. */
.kopf,.fuss{ position:relative; z-index:1; }
.inhalt{ position:relative; }

/* ---------------------------------------------------------------- 4 */
.kopf{
  position:sticky; top:0; z-index:100;
  display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:12px 28px;
  background:rgba(7,12,22,.78);
  backdrop-filter:blur(14px) saturate(140%);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  border-bottom:1px solid rgba(57,224,196,.14);
}

.marke{
  display:inline-flex; align-items:center; gap:10px;
  font-weight:700; font-size:17px; letter-spacing:.4px;
  color:var(--text); text-decoration:none;
}
.marke:hover{ text-decoration:none; }
.ob-marke-text{ background:linear-gradient(92deg,#E9EFFA 10%,var(--blau) 95%);
  -webkit-background-clip:text; background-clip:text; color:transparent; }
/* Kleiner Ring als Zeichen — eine Umlaufbahn im Kleinen */
.ob-marke-ring{
  width:16px; height:16px; border-radius:50%; flex:none;
  border:1.5px solid var(--blau); position:relative;
  box-shadow:0 0 12px rgba(57,224,196,.45);
}
.ob-marke-ring::after{
  content:''; position:absolute; top:-2px; left:50%; width:4px; height:4px;
  margin-left:-2px; border-radius:50%; background:var(--blau);
  box-shadow:0 0 8px var(--blau);
}

.nav{ display:flex; gap:4px; align-items:center; }
.nav a,.nav-gruppe-kopf{
  padding:8px 14px; border-radius:var(--radius-klein);
  color:var(--text-leise); text-decoration:none; font-size:14px;
  border:0; background:transparent; font:inherit; font-size:14px; cursor:pointer;
  transition:color .15s ease, background .15s ease;
}
.nav a:hover,.nav-gruppe-kopf:hover{ background:var(--blau-hell); color:var(--blau); text-decoration:none; }
.nav a.aktiv{
  background:var(--blau-hell); color:var(--blau);
  box-shadow:inset 0 0 0 1px rgba(57,224,196,.35);
}
.nav a.aktiv:hover{ background:rgba(57,224,196,.18); color:var(--blau); }

.nav-abmelden{
  padding:8px 14px; border:1px solid var(--rand); border-radius:var(--radius-klein);
  background:transparent; color:var(--text-leise); font-size:14px; cursor:pointer;
  font-family:var(--font); transition:all .15s ease;
}
.nav-abmelden:hover{ background:var(--blau-hell); color:var(--blau); border-color:var(--blau); }

.nav-gruppe{ position:relative; display:flex; align-items:center; }
.nav-kopf{ display:inline-flex; align-items:center; gap:4px; }
.nav-pfeil{ font-size:10px; opacity:.65; }
.nav-auf{
  border:0; background:transparent; color:var(--text-leise); cursor:pointer;
  font-size:11px; line-height:1; padding:7px 6px; border-radius:6px; margin-left:-8px;
}
.nav-auf:hover{ color:var(--blau); background:var(--blau-hell); }
.nav-gruppe.aktiv-pfad > .nav-kopf{ color:var(--blau); }

.nav-unter{
  display:none; position:absolute; top:100%; left:0; z-index:120;
  min-width:200px; padding:6px; margin-top:8px; flex-direction:column; gap:2px;
  background:var(--karte-fest);
  border:1px solid var(--rand); border-radius:12px;
  box-shadow:var(--schatten), var(--glanz);
}
.nav-unter::before{ content:''; position:absolute; left:0; right:0; top:-10px; height:10px; }
.nav-unter a,.nav-unter .nav-gruppe-kopf,.nav-unter .nav-kopf{ width:100%; text-align:left; white-space:nowrap; }
.nav-unter .nav-gruppe{ display:flex; }
.nav-unter .nav-gruppe .nav-kopf{ flex:1; }
.nav-unter .nav-unter{ top:-7px; left:100%; margin:0 0 0 6px; }
.nav-unter .nav-unter::before{ left:-10px; right:auto; top:0; bottom:0; width:10px; height:auto; }
.nav-gruppe.auf > .nav-unter{ display:flex; }
@media (hover:hover) and (pointer:fine){
  .nav-gruppe:hover > .nav-unter,
  .nav-gruppe:focus-within > .nav-unter{ display:flex; }
}

.nav-abzeichen{
  display:inline-block; margin-left:6px; padding:1px 7px; border-radius:999px;
  background:var(--warnung); color:#2A1B00; font-size:11px; font-weight:700; line-height:1.5;
  vertical-align:middle;
}
.nav-abzeichen:empty{ padding:0; width:8px; height:8px; border-radius:50%; margin-left:5px; }
.nav-punkt{
  display:inline-block; width:8px; height:8px; border-radius:50%;
  background:var(--warnung); margin-left:6px; vertical-align:middle;
  box-shadow:0 0 8px rgba(245,181,68,.6);
}

/* ---------------------------------------------------------------- 5 */
.inhalt{ max-width:1180px; margin:0 auto; padding:36px 28px 72px; }

.seiten-titel{
  font-size:27px; font-weight:700; letter-spacing:-.2px;
  margin-bottom:22px; color:var(--text);
  text-wrap:balance;
}
/* Feine Linie unter dem Titel, die nach rechts ausläuft — ordnet die Seite,
   ohne einen harten Strich zu ziehen */
.seiten-titel::after{
  content:''; display:block; width:76px; height:2px; margin-top:10px; border-radius:2px;
  background:linear-gradient(90deg,var(--blau),rgba(57,224,196,0));
}

h2,h3{ font-weight:650; letter-spacing:-.1px; }

/* ---------------------------------------------------------------- 6
   Tafeln. `mw-flaeche` ist der Haken des Frameworks: was diese Klasse
   trägt, sieht überall gleich aus. */
.karte,.mw-flaeche{
  background:var(--karte);
  backdrop-filter:blur(16px) saturate(130%);
  -webkit-backdrop-filter:blur(16px) saturate(130%);
  border:1px solid var(--rand);
  border-radius:var(--radius);
  box-shadow:var(--schatten), var(--glanz);
}
.karte{ padding:20px 22px; }
.karte-gross{ margin-bottom:24px; }
.willkommen{ font-size:17px; color:var(--text-leise); }

.kacheln{ display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:14px; }

.karte-label{
  font-size:11px; letter-spacing:1.1px; text-transform:uppercase;
  color:var(--text-leise); font-weight:600;
}
.karte-wert{
  font-family:var(--font-zahl); font-variant-numeric:tabular-nums;
  font-size:25px; font-weight:600; margin-top:6px; color:var(--text);
  letter-spacing:-.5px;
}
.karte-wert small{ font-size:.55em; font-weight:500; color:var(--text-leise); margin-left:2px; }

/* ---------------------------------------------------------------- 7 */
.knopf{
  padding:10px 20px; border:0; border-radius:var(--radius-klein);
  background:var(--blau); color:var(--blau-text);
  font-size:14.5px; font-weight:650; cursor:pointer; font-family:inherit;
  transition:background .15s ease, box-shadow .15s ease, transform .06s ease;
  box-shadow:0 2px 14px rgba(57,224,196,.22);
}
.knopf:hover{ background:var(--blau-dunkel); box-shadow:0 4px 20px rgba(57,224,196,.34); }
.knopf:active{ transform:translateY(1px); }
.knopf:disabled{ opacity:.45; cursor:not-allowed; box-shadow:none; }
.knopf-leise{
  background:transparent; border:1px solid var(--rand); color:var(--text-leise);
  box-shadow:none;
}
.knopf-leise:hover{ background:var(--blau-hell); border-color:var(--blau); color:var(--blau); box-shadow:none; }
.knopf-gefahr{ background:var(--gefahr); color:#2A0505; box-shadow:0 2px 14px rgba(255,97,97,.25); }
.knopf-gefahr:hover{ background:#E64A4A; }

/* ---------------------------------------------------------------- 8 */
input,select,textarea{
  background:var(--feld-bg); color:var(--feld-text);
  border:1px solid var(--feld-rand); border-radius:var(--radius-klein);
  padding:9px 12px; font-family:inherit; font-size:14px; width:100%;
  transition:border-color .15s ease, box-shadow .15s ease;
}
input:hover,select:hover,textarea:hover{ border-color:var(--rand-hell); }
input:focus,select:focus,textarea:focus{
  outline:none; border-color:var(--blau); box-shadow:0 0 0 3px rgba(57,224,196,.16);
}
/* Zahlenfelder: gleich breite Ziffern — und OHNE die beiden Pfeilchen des
   Browsers. Die zeichnet er in seiner eigenen Optik (hell, klobig, mit
   eigener Trennlinie); in einem dunklen Design sieht das immer nach Fehler
   aus. Bedienen lässt es sich unverändert mit den Pfeiltasten hoch/runter.

   HINWEIS: Ab Kern 1.9.0 steht dasselbe in `assets/grund.css`. Diese Regel
   kann dann ersatzlos raus — solange die App aber auf 1.8.5 läuft, wird sie
   hier gebraucht (nachgesehen: `grund.css` der 1.8.5 kennt sie nicht). */
input[type=number]{
  font-family:var(--font-zahl); font-variant-numeric:tabular-nums;
  appearance:textfield; -moz-appearance:textfield;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{
  -webkit-appearance:none; appearance:none; margin:0;
}
input::placeholder,textarea::placeholder{ color:#54678A; }
input[type=checkbox]{ width:auto; accent-color:var(--blau); }
select{
  appearance:none; -webkit-appearance:none; padding-right:34px;
  background-image:linear-gradient(45deg,transparent 50%,var(--text-leise) 50%),
                   linear-gradient(135deg,var(--text-leise) 50%,transparent 50%);
  background-position:calc(100% - 17px) calc(50% + 1px), calc(100% - 12px) calc(50% + 1px);
  background-size:5px 5px,5px 5px; background-repeat:no-repeat;
}
select option{ background:var(--karte-fest); color:var(--text); }
label{ font-size:13px; }
label > span{ color:var(--text-leise); }

input[type=range]{
  -webkit-appearance:none; appearance:none; padding:0; height:5px; border:0;
  background:linear-gradient(90deg,var(--blau),var(--rand-hell));
  border-radius:999px;
}
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none; width:17px; height:17px; border-radius:50%;
  background:var(--blau); border:2px solid #06121A; cursor:pointer;
  box-shadow:0 0 12px rgba(57,224,196,.6);
}
input[type=range]::-moz-range-thumb{
  width:15px; height:15px; border-radius:50%; background:var(--blau);
  border:2px solid #06121A; cursor:pointer; box-shadow:0 0 12px rgba(57,224,196,.6);
}

/* ---------------------------------------------------------------- 9 */
table{ border-collapse:collapse; width:100%; font-size:13.5px; }
th{
  text-align:left; font-size:11px; letter-spacing:.9px; text-transform:uppercase;
  color:var(--text-leise); font-weight:650;
  padding:10px 12px; border-bottom:1px solid var(--rand);
  white-space:nowrap;
}
td{ padding:10px 12px; border-bottom:1px solid rgba(30,44,72,.55); }
tbody tr:last-child td{ border-bottom:0; }
tbody tr{ transition:background .12s ease; }
tbody tr:hover{ background:rgba(57,224,196,.045); }
/* Zahlen in Tabellen immer gleich breit — sonst tanzen die Spalten */
td.md-num,td.po-num,td.mi-num,.md-r,.po-r{
  font-family:var(--font-zahl); font-variant-numeric:tabular-nums;
}

/* --------------------------------------------------------------- 10 */
#mw-toasts{
  position:fixed; right:20px; bottom:20px; z-index:2000;
  display:flex; flex-direction:column; gap:10px; max-width:360px;
}
.mw-toast{
  padding:12px 16px; border-radius:var(--radius-klein); font-size:14px;
  background:var(--karte-fest); color:var(--text);
  border:1px solid var(--rand); border-left:3px solid var(--blau);
  box-shadow:var(--schatten);
  opacity:1; transform:translateY(0); transition:opacity .4s, transform .4s;
}
.mw-toast-erfolg{ border-left-color:var(--ok); }
.mw-toast-fehler{ border-left-color:var(--gefahr); color:var(--fehler-text); }
.mw-toast-weg{ opacity:0; transform:translateY(8px); }

.mw-modal-hg{
  position:fixed; inset:0; z-index:3000;
  display:flex; align-items:center; justify-content:center;
  background:rgba(3,6,12,.68); backdrop-filter:blur(4px);
}
.mw-modal{
  background:var(--karte-fest); color:var(--text);
  border:1px solid var(--rand); border-radius:var(--radius);
  padding:22px 24px; width:calc(100% - 40px); max-width:400px;
  box-shadow:var(--schatten), var(--glanz);
}
.mw-modal-text{ margin-bottom:18px; font-size:15px; white-space:pre-line; }
.mw-modal-knoepfe{ display:flex; justify-content:flex-end; gap:10px; }
.mw-modal-knoepfe button{
  padding:9px 16px; border-radius:var(--radius-klein); border:0;
  font-size:14px; font-weight:650; cursor:pointer; font-family:var(--font);
}
.mw-modal-ja{ background:var(--blau); color:var(--blau-text); }
.mw-modal-nein{ background:transparent; border:1px solid var(--rand); color:var(--text-leise); }

/* --------------------------------------------------------------- 11 */
.ansicht-wahl{ display:inline-flex; align-items:center; gap:6px; }
.ansicht-wahl button{
  background:transparent; border:1px solid var(--rand); border-radius:7px;
  color:var(--text-leise); font-size:12px; padding:3px 9px; cursor:pointer; font-family:var(--font);
}
.ansicht-wahl button:hover{ color:var(--blau); border-color:var(--blau); }
.ansicht-wahl button.aktiv{ background:var(--blau); color:var(--blau-text); border-color:var(--blau); }

.sprach-wahl,.mw-segment{
  display:inline-flex; align-items:center; padding:3px; gap:2px;
  border:1px solid var(--rand); border-radius:999px;
  background:rgba(6,11,20,.6);
  position:relative;
}
.sprach-wahl button{
  border:0; background:transparent; border-radius:999px;
  color:var(--text-leise); font-size:12px; font-weight:700; letter-spacing:.3px;
  padding:4px 12px; cursor:pointer; font-family:var(--font);
  transition:background .15s ease, color .15s ease;
}
.sprach-wahl button:hover:not(.aktiv){ color:var(--blau); background:var(--blau-hell); }
.sprach-wahl button.aktiv{ background:var(--blau); color:var(--blau-text); }

/* Segmentregler: die gleitende Markierung ist ein eigenes Element (Kern) */
.mw-segment-pille{
  position:absolute; top:3px; bottom:3px; left:0; width:0;
  border-radius:999px; background:var(--blau);
  box-shadow:0 0 16px rgba(57,224,196,.45);
  transition:transform .26s cubic-bezier(.34,1.3,.64,1), width .26s ease;
  pointer-events:none; z-index:0;
}
.mw-segment > button{
  position:relative; z-index:1;
  padding:6px 14px; border:0; border-radius:999px; background:transparent;
  color:var(--text-leise); font:inherit; font-size:13px; line-height:1.2;
  cursor:pointer; white-space:nowrap; transition:color .15s ease;
}
.mw-segment > button:hover:not(.aktiv){ color:var(--blau); }
.mw-segment > button.aktiv{ color:var(--blau-text); font-weight:650; background:transparent; }
.mw-segment.zieht > .mw-segment-pille{ opacity:.55; box-shadow:none; }
.mw-segment.zieht > button.aktiv{ color:var(--blau); }
/* Balken der Verzögerung vor dem Schalten */
.mw-segment-uhr{
  position:absolute; left:6px; right:6px; bottom:2px; height:2px;
  border-radius:2px; background:var(--warnung); pointer-events:none;
  transform-origin:left center;
  animation-name:mw-segment-uhr-lauf; animation-timing-function:linear; animation-fill-mode:forwards;
}
@keyframes mw-segment-uhr-lauf{ from{ transform:scaleX(0); } to{ transform:scaleX(1); } }
.mw-segment.wartet > .mw-segment-pille{ opacity:.75; }

/* --------------------------------------------------------------- 12
   Diagramme. Die Bibliothek bringt einige helle Festfarben mit, die auf
   dunklem Grund blenden würden — hier werden sie zurückgenommen. */
.mw-dg-gitter{ stroke:rgba(42,60,94,.55); }
.mw-dg-achse{ stroke:rgba(58,80,121,.8); }
.mw-dg-tick{ fill:var(--text-leise); font-family:var(--font-zahl); font-size:10.5px; }
.mw-dg-legende{ color:var(--text-leise); font-size:12.5px; }
.mw-dg-tooltip{
  background:var(--karte-fest); color:var(--text);
  border:1px solid var(--rand-hell); border-radius:10px;
  box-shadow:var(--schatten); font-size:12.5px;
}
.mw-dg-tval{ font-family:var(--font-zahl); font-variant-numeric:tabular-nums; }
.mw-dg-fadenkreuz{ stroke:rgba(57,224,196,.5); }
/* Fläche und Linie lassen die Maus durch, damit das Fadenkreuz-Tooltip des
   Kerns überall greift — auch DIREKT AUF der Kurve. Der Kern legt seine
   unsichtbare Fangfläche unter die Serien; ohne dieses `pointer-events:none`
   fängt die gezeichnete Fläche die Maus ab, und der Tooltip erscheint nur
   OBERHALB der Kurve (Tobias' Befund, 28.07.). Gezeichnete Punkte liegen als
   eigene Kreise darüber und behalten ihren Tooltip. Zwischenlösung, bis der
   Kern es selbst setzt — Befund liegt im Briefkasten. */
.mw-dg-area, .mw-dg-line{ pointer-events:none; }
.mw-dg-mitte{ fill:var(--text); font-family:var(--font-zahl); }
.mw-dg-reglerbahn{ stroke:rgba(42,60,94,.8); }
.mw-dg-griff{ filter:drop-shadow(0 0 6px rgba(57,224,196,.65)); }
.mw-dg-kachel-name{ color:var(--text-leise); }
.mw-dg-kachel-wert{ font-family:var(--font-zahl); color:var(--text); }

/* --------------------------------------------------------------- 13 */
.fuss{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center;
  gap:10px 18px; padding:22px 24px;
  color:var(--text-leise); font-size:12.5px;
  border-top:1px solid var(--rand);
  background:rgba(4,7,14,.5);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
}

/* Schmale Schirme: Kopf umbrechen lassen, Ränder enger */
@media (max-width:820px){
  .kopf{ flex-wrap:wrap; padding:10px 16px; }
  .nav{ width:100%; overflow-x:auto; padding-bottom:2px; }
  .inhalt{ padding:24px 16px 56px; }
  .seiten-titel{ font-size:23px; }
}
@media (max-width:480px){
  .mw-segment{ display:flex; width:100%; }
  .mw-segment > button{ flex:1; text-align:center; padding:8px 6px; }
}

/* Weniger Bewegung: alles Wandernde anhalten. Die Kugel hält theme.js an. */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
}

/* Milchglas kostet auf schwachen Geräten Leistung — dort einfarbig füllen */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .karte,.mw-flaeche,.kopf,.fuss{ background:var(--karte-fest); }
}

/* --------------------------------------------------------------- 14
   Nachbesserungen für die KERN-Module.

   Die werden vom Framework ausgeliefert und dürfen hier nicht bearbeitet
   werden — ihre Stile kommen im Bündel NACH dem Theme. Deshalb greifen
   diese Regeln über eine höhere Gewichtung (`body` davor). Betroffen
   sind nur die wenigen Stellen, an denen dort feste helle Farben stehen;
   alles andere arbeitet bereits mit Variablen und zieht von selbst mit. */

/* Einstellungen: Willkommensbox hatte dunkle Schrift auf hellem Grund */
body .ein-willkommen{
  background:var(--blau-hell); border-color:rgba(57,224,196,.28);
  border-left-color:var(--blau); color:var(--text);
}
/* Benutzer: Abzeichen war hellgelb mit brauner Schrift */
body .bv-badge{ background:rgba(245,181,68,.16); color:var(--warnung); }
body .online-ich{ color:var(--ok); }
/* Anmeldeseite: die Karte soll wie alle Tafeln wirken */
body .login-karte,body .login-box{
  backdrop-filter:blur(16px) saturate(130%);
  -webkit-backdrop-filter:blur(16px) saturate(130%);
  box-shadow:var(--schatten), var(--glanz);
}

/* --------------------------------------------------------------- 15
   Messwerte einheitlich in Ziffernbreite setzen. Das ist der Kniff, der
   die ganze Anwendung nach Instrument aussehen lässt: Werte stehen
   untereinander und zucken nicht, wenn sie sich sekündlich ändern.
   Gilt für die Wert-Elemente aller Module (eigene wie Kern). */
.en-kpi-wert,.en-wert,.en-zahl,
.mi-werte b,.mi-sats b,.mi-grenz-marke,
.md-kachel b,.md-sb-werte dd,.md-fan-rpm,.md-hist-kopf,
.po-kachel b,.po-num{
  font-family:var(--font-zahl); font-variant-numeric:tabular-nums;
  letter-spacing:-.3px;
}

/* Aufmerksamkeit lenken: kurz aufleuchten, wenn sich ein Wert ändert.
   Die Module setzen dafür bereits eine Klasse. */
.md-blink,.en-blink{ animation:ob-puls .9s ease-out; }
@keyframes ob-puls{
  0%{ color:var(--blau); text-shadow:0 0 14px rgba(57,224,196,.55); }
  100%{ color:inherit; text-shadow:none; }
}

/* --------------------------------------------------------------- 16
   Seiten mit dem Gerüst „leer" (Anmeldung, Ersteinrichtung). Sie laufen
   nicht durch layout.php — den Hintergrund legt dort theme.js an. Hier
   nur die Anordnung: Inhalt mittig über der Kugel. */
.inhalt-leer{
  position:relative; z-index:1;
  min-height:100vh; display:flex; align-items:center; justify-content:center;
  padding:40px 20px;
}

/* --------------------------------------------------------------- 17
   Schutz für die geteilten Umschalter.

   Kern-Module gestalten teils schlicht `button` innerhalb ihrer Karte
   (z. B. `.auth-karte button` auf der Anmeldeseite). Diese Regel hat
   dieselbe Gewichtung wie `.sprach-wahl button`, steht im Bündel aber
   NACH dem Theme — und gewinnt damit. Folge: der Sprachumschalter sah
   aus wie zwei Absende-Knöpfe, beide gefüllt, ohne erkennbare Auswahl.

   Deshalb hier mit `body` davor eine Stufe höher. Betrifft alle drei
   geteilten Umschalter, damit dasselbe nicht auf anderen Seiten passiert. */
body .sprach-wahl button,
body .ansicht-wahl button{
  background:transparent; color:var(--text-leise);
  border-radius:999px; box-shadow:none; font-weight:700;
  padding:4px 12px; font-size:12px; letter-spacing:.3px;
}
body .ansicht-wahl button{ border:1px solid var(--rand); border-radius:7px; }
body .sprach-wahl button:hover:not(.aktiv),
body .ansicht-wahl button:hover:not(.aktiv){ color:var(--blau); background:var(--blau-hell); }
body .sprach-wahl button.aktiv,
body .ansicht-wahl button.aktiv{
  background:var(--blau); color:var(--blau-text);
  box-shadow:0 0 14px rgba(57,224,196,.35);
}
body .ansicht-wahl button.aktiv{ border-color:var(--blau); }

body .mw-segment > button{ background:transparent; box-shadow:none; }
body .mw-segment > button.aktiv{ background:transparent; color:var(--blau-text); }

/* Quellennachweis der Planetenaufnahmen (CC BY 4.0 — Pflichtangabe).
   Bewusst leise: gehört in die Fußzeile, soll aber nicht ablenken. */
.ob-quelle{ font-size:11.5px; color:#5C6E8C; }
.ob-quelle a{ color:#7C90B0; text-decoration:underline; text-underline-offset:2px; }
.ob-quelle a:hover{ color:var(--blau); }

/* --------------------------------------------------------------- 18
   Lesbarkeit in den KERN-Modulen.

   Diese Dateien liefert das Framework aus und dürfen hier nicht geändert
   werden; ihre Stile stehen im Bündel NACH dem Theme. Deshalb greifen
   die folgenden Regeln über eine höhere Gewichtung (`body` davor).

   Der Anlass war ernst: Das Muster „Hintergrund = Akzentfarbe, Schrift =
   #fff" stammt aus dem hellen Standard-Design, wo der Akzent ein dunkles
   Blau ist. Hier ist der Akzent ein HELLES Türkis — weiße Schrift darauf
   erreicht nur 1,7:1 und ist praktisch unlesbar. Umgekehrt setzen einige
   Module nur den Hintergrund auf ein dunkles Rot und erben die dunkle
   Schriftfarbe des Themes: dunkelbraun auf dunkelrot, 2,5:1. */

body .knopf{ color:var(--blau-text); }
body .knopf-gefahr{  background:var(--gefahr);  color:#2A0505; }
body .knopf-warnung{ background:var(--warnung); color:#2A1B00; }

/* Bestätigungsseite: die Fehlermeldung ist die einzige Rückmeldung der
   Seite und war mit 2,8:1 kaum zu sehen. */
body .auth-fehler{ color:var(--fehler-text); }

/* Rechte-Matrix: der AUS-Zustand war eine hellgraue Pille und leuchtete
   stärker als der EIN-Zustand — „aus" las sich wie „an". */
body .schalter-knopf{ background:var(--rand-hell); }

/* Zustandsfarben aus dem hellen Design nachziehen */
body .stat-ja,body .stat-online{ color:var(--ok); }
body .stat-nein{ color:var(--gefahr); }
body .an-badge{ background:var(--blau); color:var(--blau-text); }
body .ein-willkommen small{ color:var(--text-leise); }

/* --------------------------------------------------------------- 19
   Diagramme.

   `assets/diagramme.css` wird als EIGENE Datei nach dem Bündel geladen
   (Seite.php) — sie gewinnt also gegen Abschnitt 12 dieses Themes. Was
   dort stehen muss, gehört deshalb hierher, mit `body` davor.

   Sichtbarster Fall: der Tooltip erbte `--karte` mit 72 % Deckkraft,
   hängt aber ohne Weichzeichner am Seitenkörper — die Diagrammlinien und
   die Planeten schienen mitten durch das Kästchen hindurch. */
body .mw-dg-tooltip{
  background:var(--karte-fest); color:var(--text);
  border-color:var(--rand-hell); box-shadow:var(--schatten);
}
body .mw-dg-gitter{ stroke:rgba(42,60,94,.55); }
body .mw-dg-achse{ stroke:rgba(58,80,121,.8); }
body .mw-dg-tick{ fill:var(--text-leise); font-family:var(--font-zahl); font-size:10.5px; }
body .mw-dg-legende{ color:var(--text-leise); }
body .mw-dg-tval{ font-family:var(--font-zahl); font-variant-numeric:tabular-nums; }
body .mw-dg-mitte{ fill:var(--text); font-family:var(--font-zahl); }
body .mw-dg-fadenkreuz{ stroke:rgba(57,224,196,.5); }
body .mw-dg-reglerbahn{ stroke:rgba(42,60,94,.8); }

/* ====================================================================
   19b · Musikknopf + sanfter Seitenwechsel
   ==================================================================== */

/* Vier Balken, die im Takt tanzen, solange Musik läuft — ruhig und
   gleich hoch, wenn nicht. Kein Text: das Symbol erklärt sich. */
/* Die Kopfzeile verteilt mit `space-between`. Mit dem Spieler als drittem
   Element rutschte die Navigation in die Mitte — sie gehört aber nach
   rechts. Also schiebt die Navigation selbst, der Knopf schließt an. */
.kopf .nav{ margin-left:auto; }

.ob-musik{
  margin-left:0; flex:0 0 auto;
  display:inline-flex; align-items:flex-end; justify-content:center; gap:3px;
  width:38px; height:34px; padding:0 8px;
  border:1px solid var(--rand); border-radius:999px;
  background:rgba(6,11,20,.6); cursor:pointer;
  transition:border-color .18s ease, background .18s ease;
}
.ob-musik:hover{ border-color:var(--blau); background:rgba(57,224,196,.10); }
.ob-musik:focus-visible{ outline:2px solid var(--blau); outline-offset:2px; }

.ob-musik-noten{ display:flex; align-items:flex-end; gap:3px; height:16px; }
.ob-musik-noten > span{
  width:3px; height:5px; border-radius:2px;
  background:var(--text-leise); transition:background .18s ease;
}
.ob-musik-an .ob-musik-noten > span{ background:var(--blau); }
.ob-musik-an .ob-musik-noten > span{ animation:ob-takt .9s ease-in-out infinite; }
.ob-musik-an .ob-musik-noten > span:nth-child(2){ animation-duration:.72s; animation-delay:.12s; }
.ob-musik-an .ob-musik-noten > span:nth-child(3){ animation-duration:1.05s; animation-delay:.05s; }
.ob-musik-an .ob-musik-noten > span:nth-child(4){ animation-duration:.84s; animation-delay:.2s; }
@keyframes ob-takt{ 0%,100%{ height:5px; } 50%{ height:16px; } }

@media (prefers-reduced-motion: reduce){
  .ob-musik-an .ob-musik-noten > span{ animation:none; height:11px; }
}

/* Während der Inhalt getauscht wird: kurz zurücknehmen, damit der
   Wechsel als Übergang gelesen wird und nicht als Ruckeln. */
main.inhalt{ transition:opacity .16s ease; }
body.ob-wechselt main.inhalt{ opacity:.45; }

/* --------------------------------------------------------------- 20
   BEREICHSUMSCHALTER

   Das Markup kommt seit Kern 1.23.0 zentral aus `Seite::bereichsWahl()`
   und steckt damit in JEDEM Theme — die Gestaltung aber nicht. Ohne die
   Regeln hier standen die drei Links unformatiert und ohne Abstand im
   Kopf ("ÖffentlichArbeitsbereichVerwaltung") und liefen rechts aus dem
   Bild. Genau so sah es aus, bevor dieser Abschnitt entstand.

   Bewusst knapp gepolstert: Die Modulnavigation ist lang (11 Einträge
   plus Sprachwahl und Abmelden). Jedes zusätzliche Pixel Polsterung
   drückt den Umschalter aus der Zeile. */
/* Der Kopf darf umbrechen. Ohne das schob sich der Umschalter bei langer
   Modulnavigation rechts aus dem Bild — bei 1600 px fehlten genau 22 px
   und „Verwaltung" war angeschnitten. Eine feste Breiten-Schwelle wäre
   geraten; so entscheidet der Umbruch sich selbst, sobald es eng wird,
   und stimmt auch bei anderer Schriftgröße oder Zoomstufe. */
.kopf{ flex-wrap:wrap; }

.mw-bereiche{
  display:inline-flex; flex:0 0 auto; gap:2px; padding:3px;
  margin-left:auto;          /* bleibt rechts — auch nach einem Umbruch */
  background:var(--karte-fest); border:1px solid var(--rand);
  border-radius:11px;
}
.mw-bereich{
  padding:5px 11px; border-radius:8px;
  font-size:12.5px; font-weight:600; white-space:nowrap;
  color:var(--text-leise); text-decoration:none;
  transition:background .16s ease, color .16s ease;
}
.mw-bereich:hover{ background:var(--blau-hell); color:var(--text); }

/* `a.mw-bereich.aktiv` statt `.mw-bereich.aktiv`: Die :hover-Regel ist
   gleich spezifisch und würde sonst je nach Reihenfolge gewinnen —
   derselbe Stolperstein wie im Standard-Theme, dort ebenso gelöst. */
a.mw-bereich.aktiv{ background:var(--blau); color:var(--blau-text); }

@media (max-width:1180px){
  /* Ab hier reicht eine Zeile nicht mehr für Marke + Navigation +
     Umschalter. Lieber umbrechen als abschneiden: Der Kopf wird eine
     Zeile höher, der Umschalter bleibt vollständig sichtbar. */
  .kopf{ flex-wrap:wrap; }
  .mw-bereiche{ order:3; width:100%; justify-content:center; }
  .mw-bereich{ flex:1 1 auto; text-align:center; }
}

/* ---- Nachrichten-Seite: leise Knöpfe brauchen eine DECKENDE Fläche ----
   Bitte des Framework-Chats vom 12.09.2026, dort am Bildschirmfoto gemessen:
   Über dem bewegten Hintergrund fallen „Endgültig löschen", „Filter",
   „Aktionen", „Schließen" und der Zeilenknopf auf 1,00–1,90 : 1, sobald ein
   heller Himmelskörper hindurchwandert — praktisch unsichtbar.
   ⚠️ `var(--karte)` reicht NICHT, die ist selbst durchsichtig (gemessen
   2,61 : 1). Deshalb hier bewusst der feste Wert von `--karte-fest`.
   ⚠️ Und: `getComputedStyle` taugt zum Messen nicht — es meldete 6,85 : 1,
   wo das Bild 1,41 : 1 zeigte. Über bewegtem Hintergrund nur am Bild messen. */
#na-seite .knopf-leise,
#na-seite .na-filter { background-color: #0E1626; }

/* ====================================================================
   M&W-Framework  ·  © 2026 Tobias Wachtel — Alle Rechte vorbehalten.
   ====================================================================
   module/login/stil.css — Anmeldung/Ersteinrichtung.
   Design: weiß/blau mit schwarzer Schrift (eigene Vollbildseite). */

/* Vollbild-Hintergrund hell (überschreibt das App-Theme auf der Login-Seite) */
body.seite-leer {
    background: var(--bg, #f4f7fb);
    color: var(--text, #111827);
}

.inhalt-leer {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.auth { width: 100%; max-width: 400px; }

.auth-karte {
    background: var(--karte, #ffffff);
    border: 1px solid var(--rand, #e3e8f0);
    border-top: 4px solid var(--blau, #2563eb);            /* blauer Akzent */
    border-radius: 14px;
    padding: 32px 30px;
    box-shadow: 0 12px 40px rgba(30, 58, 138, .10);
}

.auth-oben {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
}
.auth-marke {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .6px;
    text-transform: uppercase;
    color: var(--blau, #2563eb);               /* blau */
}

.auth-titel {
    font-size: 24px;
    font-weight: 800;
    color: var(--text, #0f172a);               /* (fast) schwarz */
    margin: 0 0 8px;
}

.auth-info {
    font-size: 14px;
    color: var(--text-leise, #475569);
    line-height: 1.55;
    margin: 0 0 22px;
}

.auth-karte form { margin: 0; }

.auth-karte label {
    display: block;
    margin-bottom: 16px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text, #1e293b);
}

.auth-tipp { font-weight: 400; color: var(--text-leise, #64748b); }

.auth-karte input {
    width: 100%;
    margin-top: 6px;
    padding: 11px 13px;
    border: 1px solid var(--feld-rand, var(--rand, #cbd5e1));
    border-radius: 9px;
    background: var(--feld-bg, #fff);
    color: var(--feld-text, var(--text, #111827));
    font-size: 15px;
    font-family: inherit;
    box-sizing: border-box;
}

.auth-karte input:focus {
    outline: none;
    border-color: var(--blau, #2563eb);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .18);
}

/* NUR der Absende-Knopf (Anmelden/Einrichten) — NICHT jeder Knopf in der Karte.
   In der Karte sitzen auch Sprach-Umschalter, „andere Datenbank" und „Verbindung
   testen"; die tragen alle type="button" und behalten dadurch ihren eigenen Stil.
   (Vorher erwischte `.auth-karte button` sie mit — der Sprach-Umschalter sah dann
   aus wie zwei aktive Knöpfe nebeneinander.) */
.auth-karte button:not([type="button"]) {
    width: 100%;
    margin-top: 8px;
    padding: 12px;
    border: 0;
    border-radius: 9px;
    background: var(--blau, #2563eb);           /* blau */
    color: var(--blau-text, #ffffff);
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    font-family: inherit;
}

.auth-karte button:not([type="button"]):hover { background: var(--blau-dunkel, #1d4ed8); }

/* ── Sicherheitsabfrage ───────────────────────────────────────────
   Die Rechenaufgabe steht NEBEN dem Feld, nicht darüber: Sie ist Teil der
   Frage, nicht ihre Überschrift. */
.auth-captcha-aufgabe {
    display: inline-block;
    margin: 6px 8px 0 0;
    padding: 7px 11px;
    border-radius: 8px;
    background: var(--blau-hell, #eff4ff);
    color: var(--code-text, #1e3a8a);
    font-weight: 700;
    font-size: 15px;
    letter-spacing: .5px;
    user-select: none;
}
.auth-karte .auth-captcha input { max-width: 120px; width: auto; display: inline-block; }

/* ⚠️ Spezifitäts-Falle. `[hidden] { display: none }` steht im Stylesheet des
   BROWSERS und wiegt 0-1-0; `.auth-karte label { display: block }` weiter
   oben wiegt 0-1-1 und gewinnt. Ohne diese Zeile wäre der Captcha-Block
   IMMER sichtbar — auch wenn gar keine Aufgabe darin steht. Die id hebt das
   Gewicht auf 1-1-0, damit es in jedem Theme gilt. */
#login-captcha[hidden] { display: none; }

/* Der Weg zur Selbst-Registrierung, unter dem Anmelde-Knopf. Bewusst als
   schlichter Textlink und nicht als zweiter Knopf: Es ist der seltenere
   Weg, und zwei gleich starke Knöpfe nebeneinander lassen niemanden
   erkennen, welcher der gemeinte ist. */
.auth-reg {
    margin: 16px 0 0;
    text-align: center;
    font-size: 13.5px;
}
.auth-reg a {
    color: var(--blau, #2563eb);
    text-decoration: none;
}
.auth-reg a:hover { text-decoration: underline; }

.auth-fehler {
    background: var(--fehler-bg, #fef2f2);
    color: var(--fehler-text, #b91c1c);
    border: 1px solid var(--fehler-rand, #fecaca);
    padding: 10px 12px;
    border-radius: 9px;
    font-size: 13px;
    margin-bottom: 16px;
}

.auth-karte code {
    background: var(--blau-hell, #eff4ff);
    color: var(--code-text, #1e3a8a);
    padding: 2px 6px;
    border-radius: 5px;
    font-size: 13px;
}

/* Datenbank-Schritt der Ersteinrichtung */
.setup-db { text-align: left; margin-bottom: 18px; }
.setup-db-ist {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px; border: 1px solid var(--rand, #e3e8f0); border-radius: 10px;
    background: var(--bg, #f8fafc);
}
.setup-db-punkt { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.setup-db-punkt.ist-ok     { background: #16a34a; }
.setup-db-punkt.ist-fehler { background: #dc2626; }
.setup-db-label { font-size: 11px; text-transform: uppercase; letter-spacing: .4px; color: var(--text-leise, #64748b); }
.setup-db-wert  { font-size: 14px; }
.setup-db-ziel  { color: var(--text-leise, #64748b); font-size: 12.5px; margin-left: 6px; }
.setup-db-wechsel {
    margin-left: auto; background: transparent; border: 0; color: var(--blau, #2563eb);
    font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
}
.setup-db-wechsel:hover { text-decoration: underline; }

.setup-db-wahl { margin-top: 12px; padding: 12px; border: 1px solid var(--rand, #e3e8f0); border-radius: 10px; }
.setup-db-art { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 8px; font-size: 13.5px; line-height: 1.4; cursor: pointer; }
.setup-db-art input { margin-top: 3px; flex: 0 0 auto; }
.setup-db-felder { display: grid; gap: 8px; margin: 10px 0; }
/* Dieselbe Falle wie oben: `display: grid` (0-1-0) schlägt das `[hidden]`
   des Browsers. Ohne diese Zeile standen die Datenbank-Felder der
   Ersteinrichtung auch dann da, wenn „SQLite" gewählt war. */
.setup-db-felder[hidden] { display: none; }
.setup-db-felder label { display: flex; flex-direction: column; gap: 3px; font-size: 12.5px; color: var(--text-leise, #64748b); }
.setup-db-test {
    width: 100%; padding: 9px 14px; border: 0; border-radius: 9px;
    background: var(--blau, #2563eb); color: #fff; font: inherit; font-size: 14px; cursor: pointer;
}
.setup-db-test:hover:not(:disabled) { background: var(--blau-dunkel, #1d4ed8); }
.setup-db-test:disabled { opacity: .6; cursor: default; }
.setup-db-ergebnis { margin-top: 10px; padding: 10px 12px; border-radius: 9px; font-size: 13px; }
.setup-db-ergebnis.ist-ok     { background: #f0fdf4; border: 1px solid #86efac; color: #14532d; }
.setup-db-ergebnis.ist-fehler { background: #fef2f2; border: 1px solid #fca5a5; color: #7f1d1d; }
.setup-db-ergebnis p { margin: 0 0 8px; }
.setup-db-anleitung { font-weight: 600; }
.setup-db-zeilen {
    margin: 0 0 10px; padding: 10px 12px; background: #1e293b; color: #e2e8f0;
    border-radius: 8px; font-family: ui-monospace, monospace; font-size: 12.5px;
    white-space: pre-wrap; word-break: break-word; user-select: all; text-align: left;
}
.auth-fehler-fest { margin: 10px 0 0; padding: 9px 12px; background: #fef2f2; border: 1px solid #fca5a5;
    border-radius: 9px; color: #7f1d1d; font-size: 13px; text-align: left; }

/* Selbstcheck der Server-Voraussetzungen (Ersteinrichtung) */
.auth-voraussetzung {
    background: #fef3c7;
    border: 1px solid #f59e0b;
    border-left: 4px solid #b45309;
    border-radius: 9px;
    padding: 14px 16px;
    color: #7c2d12;
    text-align: left;
}
.auth-vor-kopf  { margin: 0 0 8px; font-size: 14px; font-weight: 600; }
.auth-vor-text  { margin: 8px 0 0; font-size: 13px; line-height: 1.5; }
.auth-vor-befehl {
    margin: 10px 0 0;
    padding: 10px 12px;
    background: #1e293b;
    color: #e2e8f0;
    border-radius: 6px;
    font-family: ui-monospace, monospace;
    font-size: 12.5px;
    white-space: pre-wrap;
    word-break: break-word;
    user-select: all;
}

/* ── Superadmin-Rückweg  *(ab 1.32.0)* ──────────────────────────────────
   ⚠️ `hidden` reicht hier nicht: `.auth-karte form` bekommt oben
   `margin: 0` und das Formular ist ein Block — sichtbar bliebe es nicht,
   aber die ID-Regel steht trotzdem da, weil dieselbe Falle bei den
   Knöpfen schon dreimal zugeschlagen hat (`display:inline-flex` des
   Themes gewinnt gegen das voreingestellte `display:none`). */
#sa-reset-form[hidden] { display: none !important; }

.auth-wechsel { margin: 14px 0 0; text-align: center; }

/* Ein Knopf, der wie ein Link aussieht: Er öffnet nur ein Feld, er führt
   nicht weg. Ein echter Link wäre ein Versprechen auf eine andere Seite. */
.auth-link {
    background: none; border: 0; padding: 0;
    color: var(--blau, #2563eb); font-size: .9rem; cursor: pointer;
    text-decoration: underline;
}
.auth-link:hover { color: var(--blau-dunkel, #1d4ed8); }

/* Die Nebenmasken (Rückweg, Notfall) sitzen unter der Anmeldung und
   heben sich durch eine Trennlinie ab — nicht durch eine eigene Karte:
   Zwei gleich große Karten übereinander sähen aus wie zwei Wege, und der
   obere ist der gewöhnliche. */
.auth-neben {
    margin-top: 16px; padding-top: 16px;
    border-top: 1px solid var(--rand, #e2e8f0);
    text-align: left;
}
.auth-neben h2 { margin: 0 0 6px; font-size: 1rem; }

/* Der Satz zur Superadmin-Adresse in der Ersteinrichtung. Er ist keine
   Erklärung, die man überliest, sondern eine Entscheidung mit Folgen. */
.auth-wichtig {
    padding: 8px 12px; border-radius: 6px;
    background: #fdf3d4; color: #5a4400; border: 1px solid #e6cd7a;
}

/* ── Hinweis zur Verschlüsselung nach der Anmeldung  *(ab 1.43.0)* ─────
   Gelb wie `.auth-wichtig`: Es ist keine Fehlermeldung (die Anmeldung hat
   geklappt), aber eine Nachricht mit Folgen, die man lesen soll, bevor es
   weitergeht. Die id-Regeln für `[hidden]` aus demselben Grund wie beim
   Captcha: Eine Theme-Regel mit `display` gewinnt sonst gegen `hidden`. */
.auth-e2e {
    padding: 12px 14px; border-radius: 9px; margin: 0 0 8px;
    background: #fdf3d4; color: #5a4400; border: 1px solid #e6cd7a;
    font-size: 14px; line-height: 1.5;
}
.auth-e2e p { margin: 0 0 6px; }
#login-e2e[hidden], #login-form[hidden] { display: none !important; }

