/* ==========================================================================
   oeffentlich.css - die geteilte Stildatei der VIER Seiten VOR der Anmeldung
   (3.0.102, Andis Antworten 7:b und 9:b).

   ⛔ WARUM ES DIESE DATEI GIBT, UND WARUM NICHT stil.css.
   `/stil.css` liegt hinter der Token-Schranke: es steht in `Handler.SEITEN`
   und wird nur nach `_auth` ausgeliefert. Die vier Seiten `login`,
   `registrieren`, `passwort-vergessen` und `passwort-neu` tragen KEIN
   `__TOKEN__` - sie werden bewusst oeffentlich ausgeliefert, weil man sie
   erreichen muss, BEVOR man angemeldet ist. Genau deshalb trug jede von ihnen
   bis heute eine EIGENE ABSCHRIFT der Farbtabelle im `<style>`-Block.
   Vier Abschriften derselben Sache laufen auseinander, und sie waren es
   bereits: `--gruen` stand auf dreien als `#4d7c3a` statt der Markenfarbe
   `#5b8c3a` (ΔE76 = 9,59 hell / 7,10 dunkel, Kayas Befund B4). Es ist der
   Haken auf der Erfolgskarte - die erste Farbe, die ein neuer Mensch als
   „geschafft" liest, und sie war nicht unsere.

   ⛔ DIESE DATEI IST UND BLEIBT TOKEN-FREI. Kein `__TOKEN__`, kein `__V__`
   im Dateiinhalt - der Cache-Buster haengt am `<link>` der Seite, nicht hier.
   `Handler._datei` ersetzt Platzhalter ohnehin nur in `.html`.

   ⛔ SIE MUSS UNTER `/oeffentlich.css` OHNE ANMELDUNG ERREICHBAR SEIN.
   Fehlt die Freigabe in `app.py`, antwortet der Server mit einer 302 auf
   `/login`, und der Browser liest eine HTML-Seite als CSS: die vier Seiten
   stehen dann voellig ungestylt da - schwarz auf weiss, ohne Karte, ohne
   Knopffarbe - und das sieht NICHT nach einem Routing-Fehler aus. Genau so
   waren `nav.js`/`ui.js`/`ziel.js` bis 2.2.10 kaputt.
   `tests/test_oeffentlich_css.py` holt die Datei deshalb ueber HTTP und
   prueft ihren Inhaltstyp - nicht ihre Existenz auf der Platte.

   ⚠️ Die rote Linie „stdlib/Vanilla, kein Build" ist nicht beruehrt: das hier
   ist eine statische Datei, keine Werkzeugkette.
   ========================================================================== */

/* --------------------------------------------------------------- Farbtoken
   ⛔ DREI Bloecke, und die Reihenfolge ist die Zusicherung:
     1. `:root`                                   - hell, die Vorgabe
     2. `:root[data-theme=dark]`                  - ausdrueckliche Wahl „Dunkel"
     3. `@media (prefers-color-scheme:dark)` mit `:root:not([data-theme=light])`
                                                  - Systemwunsch, aber NUR wenn
                                                    niemand „Hell" gewaehlt hat
   Damit stimmen alle VIER Zustaende (System hell/dunkel x Wahl hell/dunkel/keine).
   `test_akzent_kontrast.py::test_die_tokenfreien_seiten_tragen_den_tiefen_akzent_selbst`
   misst genau diese vier - ueber eine gerenderte Farbe, nicht ueber
   `getPropertyValue` (ein fehlendes Token gibt dort einen leeren String, und
   „leer != erwartet" faellt zwar, sagt aber nichts darueber, was gemalt wird).

   ⛔ 3.0.96 - `--leise` UND `--akzent-text` stehen hier mit den KORRIGIERTEN
   Werten, und das ist der Grund, warum dieses Paket im selben Sprint liegt wie
   der Kontrast: haette man die 15 Masken hinter der Anmeldung behoben und
   diese vier Seiten mit ihren Abschriften stehen lassen, saehe der zu helle
   Ton genau dort weiter, wo ein neuer Mensch als ERSTES hinschaut.
   Die Begruendung der Werte steht bei `web/stil.css`; hier stehen sie, weil
   diese Seiten `stil.css` nicht laden koennen. Ein Waechter haelt beide
   Dateien aneinander (`test_kontrast_eine_regel.py`), damit die Abschrift
   nicht zum zweiten Mal auseinanderlaeuft. */
:root{
  --grund:#f1f2e4;--karte:#ffffff;--rand:#dcdfca;--text:#2b2d1c;
  --leise:#656850;--akzent:#7f8446;--akzent-text:#656938;
  /* ⛔ 3.35/3.37: dieselbe Angleichung an `brand/colors.css` wie in
     stil.css - #5E6232 statt der erfundenen #6f733d. Diese Datei traegt
     ihre eigene Kopie der Farben, weil die Seiten VOR der Anmeldung
     ohne Token ausgeliefert werden; der Waechter
     `test_die_tokenfreien_seiten_tragen_den_tiefen_akzent_selbst` hat
     genau darauf hingewiesen, als nur stil.css geaendert war. */
  --akzent-tief:#5E6232;--auf-akzent:#ffffff;--rot:#c0492f;--rot-text:#a53f28;
  /* 3.0.102/B4: die Markenfarbe, nicht die abgeschriebene. */
  --gruen:#5b8c3a;
  --radius:14px;
  /* ⚠️ `--ziel-min` steht hier, weil diese Seiten `stil.css` nicht laden. Eine
     geerbte Variable, die es gar nicht gibt, faellt lautlos auf „keine
     min-height" zurueck - genau so kam Befund 6 aus 2.6.6e zustande. */
  --ziel-min:48px}
:root[data-theme=dark]{
  --grund:#181a12;--karte:#22251a;--rand:#373b29;--text:#eceedd;
  --leise:#a7ab8e;--akzent:#a3a874;--akzent-text:#a3a874;
  --akzent-tief:#a3a874;--auf-akzent:#1b1d15;--rot:#d6674e;--rot-text:#f6765a;
  --gruen:#7fb35a}
@media (prefers-color-scheme:dark){
  :root:not([data-theme=light]){
    --grund:#181a12;--karte:#22251a;--rand:#373b29;--text:#eceedd;
    --leise:#a7ab8e;--akzent:#a3a874;--akzent-text:#a3a874;
    --akzent-tief:#a3a874;--auf-akzent:#1b1d15;--rot:#d6674e;--rot-text:#f6765a;
    --gruen:#7fb35a}}

/* ------------------------------------------------------------------ Geruest */
*{box-sizing:border-box}
body{margin:0;min-height:100vh;display:flex;align-items:center;
  justify-content:center;background:var(--grund);color:var(--text);
  font:16px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  padding:1.5rem;-webkit-text-size-adjust:100%}
.karte{background:var(--karte);border:1px solid var(--rand);
  border-radius:var(--radius);padding:1.6rem 1.4rem;width:100%;max-width:22rem}
h1{font-size:1.15rem;margin:0 0 1rem;text-align:center}
p.intro{font-size:.9rem;color:var(--leise);margin:0 0 .4rem}

/* ---------------------------------------------------------------- Wortmarke
   ⛔ 3.0.102/B3 - ZWEI Dateien, eine je Helligkeit. Bis hierher banden alle
   vier Seiten NUR `wordmark.svg` ein, und die traegt dunkle Tinte (`#5E6232`).
   Gemessen gegen die dunklen Gruende:
       #5E6232 auf --karte  #22251a  =  2,426 : 1     (Kayas Zahl)
       #5E6232 auf --grund  #181a12  =  2,735 : 1     (Robins Zahl)
       #ffffff auf --karte  #22251a  = 15,584 : 1
       #ffffff auf --grund  #181a12  = 17,568 : 1
   ⚠️ Die beiden gemeldeten Zahlen unterscheiden sich NICHT durch die Methode
   (gerenderte Pixel gegen deklarierte Fuellfarbe), sondern durch die FLAECHE:
   2,426 ist gegen die Karte gerechnet, 2,735 gegen den Seitengrund. Beide
   stimmen, beide liegen unter 3 : 1 - der Schriftzug war im Dunkelmodus
   praktisch nicht da.
   ⭐ Und das Bauteil dafuer war laengst da: `brand/wordmark-light.svg` liegt
   im Repository und wird in `web/onboarding.html` mit `class="dunkel"` benutzt.
   Es wurde auf den Eingangsseiten nur nie angewandt. Die vier Umschaltregeln
   sind woertlich die aus `stil.css` - nur `display:inline` statt `block`, weil
   `.marke` hier ueber `text-align:center` zentriert.
   ⚠️ Warum kein Bestandswaechter das gefunden hat: `tests/kontrastmessung.py`
   misst TEXT im DOM. Ein Logo ist ein Bild und liegt ausserhalb seiner
   Reichweite. `test_wortmarke_dunkel.py` schliesst genau diese Luecke. */
.marke{text-align:center;margin-bottom:1.2rem}
.marke img{height:2.1rem;max-width:100%}
.marke .dunkel{display:none}
@media (prefers-color-scheme:dark){
  :root:not([data-theme=light]) .marke .hell{display:none}
  :root:not([data-theme=light]) .marke .dunkel{display:inline}}
:root[data-theme=light] .marke .hell{display:inline}
:root[data-theme=light] .marke .dunkel{display:none}
:root[data-theme=dark] .marke .hell{display:none}
:root[data-theme=dark] .marke .dunkel{display:inline}

/* ------------------------------------------------------------------ Felder */
label{display:block;font-size:.8rem;color:var(--leise);margin:.9rem 0 .25rem}
/* Gemessen ohne min-height: 42,4 px - das Projekt misst sich an 48 (2.6.6e/6).
   Der erste Bildschirm der App waere damit der einzige, der das Mass verfehlt.
   ⛔ `:not([type=checkbox])` statt einer spaeteren Ausnahme fuer `.merken`:
   ein `min-height` von 48 px schluege dort die 1,15rem des Kaestchens (es steht
   in derselben Kaskade weiter unten, aber `height` verliert gegen
   `min-height`) - und „ein globaler Fix plus eine lokale Ausnahme ergibt keinen
   Fix" ist die Lehre aus 2.6.6. Das Fingerziel des Haekchens ist ohnehin das
   ganze `<label class="merken">`, nicht das Kaestchen.
   ⚠️ Bis 3.0.102 stand diese Ausnahme NUR in `login.html`; die drei anderen
   Seiten trugen das schlichte `input{...}`. Dass daraus kein Fehler wurde, lag
   allein daran, dass sie kein Kaestchen haben - also an ihrem Inhalt, nicht an
   ihrer Regel. In der geteilten Datei gilt jetzt ueberall die tragfaehige. */
input:not([type=checkbox]){width:100%;padding:.7rem;font-size:1rem;
  background:var(--grund);color:var(--text);border:1px solid var(--rand);
  border-radius:9px;font-family:inherit;min-height:var(--ziel-min)}
input:focus{outline:2px solid var(--akzent);outline-offset:1px}

/* ------------------------------------------------------------------ Knoepfe
   ⛔ `border-color` traegt denselben Ton wie die Flaeche. Wer nur `background`
   umstellt, bekommt einen 1 px hellen Saum aus dem alten Akzent um jeden Knopf,
   und KEIN Kontrastwaechter meldet das: ein Rand traegt keinen Text (3.0.51). */
button{font:inherit;width:100%;margin-top:1.2rem;padding:.8rem 1rem;
  min-height:2.9rem;border-radius:10px;border:1px solid var(--akzent-tief);
  background:var(--akzent-tief);color:var(--auf-akzent);font-weight:600;
  cursor:pointer}
button:disabled{opacity:.6;cursor:default}

/* ------------------------------------------------------------------- Texte */
/* ⛔ 3.0.96 / Junos Befund 0.4: die Fehlerzeile stand in `--rot` und mass
   dunkel **4,385 : 1** - AA verfehlt, ausgerechnet in der Box, die seit
   3.0.104 den Abweisungssatz traegt.
   ⛔ **Rot liegt im RAND, die Aussage traegt das WORT in `--text`.** Das ist
   woertlich `.gfehlerzeile` aus 3.0.89/B2 - dieselbe Zahl, dieselbe Ursache,
   dieselbe Antwort, nur zwei Masken weiter. Damit ist die Kontrastfrage hier
   gar nicht mehr gestellt: `--text` traegt auf `--karte` nachgemessen
   **14,048 : 1** hell und **13,239 : 1** dunkel (dieselben Zahlen, die Vera
   an der Abweisungsbox gemessen hat); der Rand braucht als Bauteil nur 3 : 1.
   ⚠️ Hier stand als Punkt 1 *„Der Ton ist --rot-text"* - und zwei Zeilen
   darunter (richtig) das Gegenteil. Gebaut war immer das Zweite; Vera hat den
   Widerspruch gefunden (V-10). `--rot-text` steht in dieser Datei nur noch als
   WERT, in keiner Regel - das ist Absicht und kein Rest: ein Kommentar, der
   eine Farbe behauptet, die die Regel daneben nicht setzt, kostet den
   naechsten Leser eine Suche.
   ⚠️ Junos Begruendung geht ueber den Kontrast hinaus, und sie ist der Grund,
   warum hier nicht nur der Ton getauscht wurde: *Rot ist eine BEHAUPTUNG* -
   „du hast etwas falsch gemacht". Der Mensch, der die Freigabe-Abweisung
   liest, hat alles richtig gemacht; sein Passwort stimmt. Eine Farbe ohne
   Bedeutung ist dieselbe Klasse Fehler wie eine Farbangabe ohne Kontrastwert.
   ⛔ `:not(:empty)` fuer den Rand: die Box steht IMMER im DOM (mit
   `min-height`, damit die Karte beim Erscheinen einer Meldung nicht springt).
   Ohne die Bedingung staende dort dauerhaft ein herrenloser roter Strich -
   dieselbe Bauform wie `.warum:empty{display:none}` aus 2.6.6. */
.fehler{color:var(--text);font-size:.9rem;margin-top:.9rem;min-height:1.2em;
  text-align:center}
.fehler:not(:empty){text-align:left;border-left:3px solid var(--rot);
  padding-left:.55rem}
.hinweis{font-size:.82rem;color:var(--leise);margin-top:.3rem;text-align:center}
.feldhinweis{font-size:.78rem;color:var(--leise);margin:.3rem 0 0}
.wechsel{text-align:center;font-size:.9rem;margin-top:1.1rem;color:var(--leise)}
/* 3.0.96: `--akzent-text`, nicht `--akzent`. Der kraeftige Ton traegt als
   SCHRIFT auf Weiss nur 3,969 : 1 und auf dem Seitengrund 3,508 : 1. */
.wechsel a{color:var(--akzent-text);font-weight:600}

/* ------------------------------------------------- Erfolgskarte / Anmeldung */
.erfolg{text-align:center}
.erfolg .haken{font-size:2.4rem;color:var(--gruen);line-height:1}
.erfolg p{margin:.9rem 0}
/* ⛔ Veras V-5: die Adresse stand als `.feldhinweis` (.78rem = 12,48 px) und
   war damit die KLEINSTE Schrift der Karte - kleiner als das
   Kleingedruckte darunter (`.hinweis`, .82rem). Sie ist ab jetzt der
   Schluessel des Nutzers; Junos Entwurf nennt 14,4 px, und genau daran
   misst der Waechter. Dieselbe Bauform wie der Befund eine Zeile hoeher:
   *die Aussage der Seite stand im Kleingedruckten.* */
.fertigadresse{font-size:.9rem;color:var(--text);margin:.9rem 0}
.merken{display:flex;align-items:center;gap:.5rem;margin-top:1rem;font-size:.9rem;
  color:var(--text);cursor:pointer}
.merken input{width:1.15rem;height:1.15rem;margin:0;flex:0 0 auto;
  accent-color:var(--akzent)}
.vergessen{display:block;text-align:center;font-size:.85rem;margin-top:.9rem}
.vergessen a{color:var(--leise)}
/* Zweiter Schritt der Anmeldung (2.3.1) */
.codefeld{letter-spacing:.35em;text-align:center;font-size:1.35rem;
  font-variant-numeric:tabular-nums}
.erklaerung{font-size:.9rem;color:var(--leise);margin:.2rem 0 .6rem;
  text-align:center}
/* ⛔ HIER STAND `padding:0; min-height:0` - und damit Befund 6 aus 2.6.6e in
   neuer Verkleidung, acht Zeilen unter dem Kommentar, der woertlich davor
   warnt. Gemessen von Vera: **20,4 px** fuer „Zurück zur Anmeldung", 40,8 px
   fuer den Wiederherstellungs-Knopf - beide unter `--ziel-min: 48px`.
   *Ein globaler Fix plus eine lokale Ausnahme ergibt keinen Fix.*
   ⛔ Und warum es niemand gemerkt hat, ist der teurere Teil: `test_lesbarkeit`
   fragte, ob eine Seite `/stil.css` laedt. Diese vier laden seit 3.0.102
   `/oeffentlich.css` - der Waechter sah sie also weiterhin nicht, und seine
   Begruendung (*„die Pre-Auth-Seiten kennen --ziel-min gar nicht"*) war bis
   zu diesem Paket wahr und ist seither falsch. Eine Begruendung, die ihre
   Lage ueberlebt hat, haelt den Waechter von genau den Seiten fern, die ein
   neuer Mensch zuerst sieht. Der Waechter fragt jetzt, ob die Seite
   `--ziel-min` ueberhaupt KENNT - egal, aus welcher Datei.
   ⚠️ `flex` statt `block`, damit der Text in den 48 px mittig sitzt; die
   Unterstreichung liegt weiter nur unter den Woertern, nicht unter der
   ganzen Zeile. */
.zurueck{display:flex;align-items:center;justify-content:center;
  text-align:center;font-size:.85rem;margin-top:1.1rem;
  color:var(--leise);background:none;border:0;width:100%;cursor:pointer;
  text-decoration:underline;padding:.4rem;min-height:var(--ziel-min)}

/* --------------------------------------------------------------- [hidden]
   ⛔ MUSS GANZ UNTEN STEHEN UND MUSS `!important` TRAGEN. `[hidden]` ist eine
   Angabe des Browsers mit der Staerke eines Elementselektors und verliert
   gegen JEDEN Klassenselektor, der `display` setzt - hier gegen
   `.vergessen{display:block}`. `stil.css` traegt dieselbe Zeile aus demselben
   Grund am Dateiende; diese Seiten laden `stil.css` nicht und saehen sie nie.
   ⚠️ Es ist kein Vorratsbau: `web/login.html` blendet mit `hidden` die beiden
   falschen Auswege der Freigabe-Abweisung aus (3.0.104). Ohne diese Zeile
   blieben sie sichtbar - und der Fehler saehe aus wie ein vergessener
   JavaScript-Aufruf, nicht wie eine verlorene Kaskade. */
[hidden]{display:none !important}
