/* PXL CMS — Admin-Oberflaeche.
   Handgeschrieben, fertig ausgeliefert, kein Build-Step (Abschnitt B).
   Ziel der Gestaltung: ruhig, gross genug zum Lesen, klare Trennung von
   «Speichern» und «Veroeffentlichen» (R.2).

   ================================================================
   DIE MARKE: PXL-Gruen #50C878 — und warum sie NICHT auf den Knoepfen sitzt
   ================================================================

   #50C878 erreicht als Schrift auf Weiss 2.13 und mit weisser Schrift darauf
   ebenfalls 2.13. Beides ist unter 4.5, ein gruener Hauptknopf mit weisser
   Schrift waere also unlesbar. Mit dunkler Schrift DARAUF sind es 7.93.
   Daraus folgt die Aufteilung, fuer die sich Lorin entschieden hat:

     #50C878 markiert ZUSTAND — aktiver Navigationspunkt, ausgewaehlt, Fokus,
     die Marke in der Seitenleiste, «live/veroeffentlicht».
     HANDLUNGEN sind neutral: der Hauptknopf dunkel gefuellt mit weisser
     Schrift, die Nebenhandlung nur mit Rand, Links unterstrichen und dunkel.

   Damit tragen Farbe und Rang zwei verschiedene Aussagen, statt sich zu
   ueberlagern. Vorher hiess die gefaerbte Flaeche an 38 Stellen zehn
   verschiedene Dinge — «Veroeffentlichen», «Speichern», «Neu» und «dieser
   Filter ist gerade aktiv». Verworfen wurde die naheliegende Variante «Gruen
   auf den Hauptknopf und dafuer abdunkeln»: Dann ist die Marke ueberall und
   sagt nichts mehr, und die Unterscheidung Speichern/Veroeffentlichen (R.2)
   haengt wieder allein am Wort.

   KOLLISION Gruen = Marke UND Gruen = veroeffentlicht: bewusst dieselbe Farbe,
   weil es dieselbe Aussage ist («das hier ist live/aktiv»). Auseinander
   gehalten wird sie ueber die FORM, nicht ueber den Farbton:
     — Zustand einer Sache: Pille, gefuellt (.marke--live) oder Rand + leichte
       Flaeche (.zustandsmarke). Traegt immer ein Wort.
     — Ergebnis einer Handlung (Meldung): breiter linker Balken, eigenes
       Zeichen (✓ ! ✕ i) vor dem Text, eigene Farbfamilie.
     — Sprachleiste: Punktform (Scheibe/Ring/gestrichelt) plus Wort.
   Deshalb bleiben --erfolg/--warnung/--fehler eigene Toene und werden NICHT
   auf die Marke gezogen: «Gespeichert» und «Diese Seite ist live» sind zwei
   Aussagen, und ein Leser, der nur die Farbe sieht, soll sie nicht verwechseln.

   ---------------- Nachgerechnete Paare, beide Modi ----------------
   (Formel: WCAG 2.x relative Luminanz. Text 4.5, Grosstext und
    Bedienelement-Raender 3.0. Die Reihenfolge ist dieselbe wie in
    GestaltungTest::paare() — Zeile fuer Zeile vergleichbar. Wer eine Farbe
    aendert, rechnet die Spalte nach und schreibt die Zahl hier hin; ein
    Kommentar mit den Zahlen von vorgestern ist schlimmer als keiner, weil
    ihm der Naechste glaubt.)

      hell  dunkel  min   Paar
     16.86   14.87  4.5   --text            auf --flaeche
     15.33   15.83  4.5   --text            auf --grund
     16.02   12.63  4.5   --text            auf --flaeche-2
      5.63    6.80  4.5   --text-leise      auf --flaeche
      5.12    7.24  4.5   --text-leise      auf --grund
      5.35    5.77  4.5   --text-leise      auf --flaeche-2
      7.93    8.87  4.5   --akzent-schrift  auf --akzent          Schrift AUF Gruen
      6.98    11.02  4.5   --akzent-dunkel   auf --flaeche         gruene Schrift
      6.35   11.73  4.5   --akzent-dunkel   auf --grund
      6.63    9.36  4.5   --akzent-dunkel   auf --flaeche-2
      6.30    8.63  4.5   --akzent-dunkel   auf --akzent-leicht   aktiver Navipunkt
     15.23    11.64  4.5   --text            auf --akzent-leicht
      3.74    4.30  3.0   --fokus           auf --flaeche
      3.40    4.58  3.0   --fokus           auf --grund
      3.55    3.65  3.0   --fokus           auf --flaeche-2
      3.38    3.36  3.0   --fokus           auf --akzent-leicht   Fokus auf dem aktiven Punkt
     15.91   15.83  4.5   --knopf-haupt-schrift auf --knopf-haupt
     11.71   11.41  4.5   --knopf-haupt-schrift auf --knopf-haupt-hover
     13.03   10.67  4.5   --text            auf --knopf-neben     Nebenknopf, gefuellt
     11.64    9.15  4.5   --text            auf --knopf-neben-hover
      5.57    5.23  4.5   --fehler          auf --knopf-neben     .knopf--gefahr erbt sie
      3.43    2.41  3.0*  --linie-stark     auf --flaeche         Feldrand
      3.12    2.56  3.0*  --linie-stark     auf --grund
      3.26    2.04  3.0*  --linie-stark     auf --flaeche-2
      3.43    4.68  3.0   --linie-stark     auf --flaeche         bei prefers-contrast: more
      3.43    4.68  3.0   --diagramm-linie  auf --flaeche         Kacheln, Gitter, Ringsegment
      3.12    4.98  3.0   --diagramm-linie  auf --grund
      3.26    3.97  3.0   --diagramm-linie  auf --flaeche-2

   * BEWUSSTE ABWEICHUNG von SC 1.4.11, dunkler Modus, auf Lorins Entscheidung:
     «schreiben eine bewusste Abweichung von 1.4.11 in die README». Sie steht
     dort unter «Bewusste Abweichungen von der Spezifikation», Punkt 9, mit
     Zahlen, Folgen und dem Weg zurueck. Unter `prefers-contrast: more` gilt
     wieder der volle Wert — wer mehr Kontrast braucht, bekommt ihn vom System.

     DER NEBENKNOPF HAT SEIT DEM 28.08.2026 GAR KEINEN RAND MEHR (Lorin: «alle
     secondary buttons ausgefuellt ohne Border, anstatt nur eine helle Border»).
     Damit gilt dieselbe Abweichung dort in BEIDEN Modi, und sie ist groesser:
     Die Fuellung traegt 1.18 bis 1.48 statt der 3.0 (unten bei den Trennungen).
     Eine Fuellung mit 3.0 waere #959595 hell und #646464 dunkel — ein mittleres
     Grau, schwerer als der gruene Hauptknopf; die Rangfolge stuende auf dem
     Kopf. Getragen wird die Erkennbarkeit deshalb von der Fuellung (geprueft
     gegen alle drei Untergruende), von der Schrift mit 13.03/10.67 und vom
     Fokusring mit 3.74/4.30. `prefers-contrast: more` gibt den Rand zurueck.
      6.51    9.91  4.5   --erfolg          auf --flaeche
      5.76    7.75  4.5   --erfolg          auf --erfolg-flaeche
      6.33    8.12  4.5   --warnung         auf --flaeche
      5.76    6.57  4.5   --warnung         auf --warnung-flaeche
      7.21    7.30  4.5   --fehler          auf --flaeche
      6.28    6.04  4.5   --fehler          auf --fehler-flaeche

   Dazu die TRENNUNGEN: kein Kontrastkriterium aus WCAG, aber die Frage, ob
   eine Flaeche auf ihrem Untergrund ueberhaupt zu sehen ist. Eine Karte, die
   dieselbe Helligkeit hat wie der Grund, ist keine Karte mehr.

      hell  dunkel  min   Flaeche auf Untergrund
      1.10    1.06  1.08  --flaeche         auf --grund
      1.18    1.48  1.15  --knopf-neben     auf --grund           der randlose Nebenknopf
      1.29    1.39  1.15  --knopf-neben     auf --flaeche
      1.23    1.18  1.15  --knopf-neben     auf --flaeche-2       der knappste Fall
      1.12    1.17  1.08  --knopf-neben-hover auf --knopf-neben
      1.54    1.57  1.30  --rand-gesperrt   auf --flaeche         Rand eines gesperrten Feldes
     16.86   16.25  4.5   --feld-text       auf --feld-flaeche    Schrift im bedienbaren Feld
      5.63    2.71  4.5*  --feld-platzhalter auf --feld-flaeche   Platzhalter — dunkel BEWUSST darunter
      3.43    1.39  3.0*  --feld-rand       auf --flaeche         Feldrand — dunkel BEWUSST darunter
      1.00    1.09  1.08  --feld-flaeche    auf --flaeche         (hell identisch: kein eigener Ton)
                          (und ausdruecklich WENIGER als --linie-stark mit 3.43 / 2.41:
                           «einfach eine Outline die weniger Kontrast hat als die normale».
                           SC 1.4.11 nimmt inaktive Bedienelemente aus.)
      1.11    1.28  1.08  --akzent-leicht   auf --flaeche
      1.13    1.28  1.08  --erfolg-flaeche  auf --flaeche
      1.10    1.24  1.08  --warnung-flaeche auf --flaeche
      1.15    1.21  1.08  --fehler-flaeche  auf --flaeche

   --flaeche-2 steht bewusst NICHT in dieser Liste: hell sind es nur 1.05, und
   das ist Absicht — der Streifen liegt ueber einer ganzen Tabellenzeile, nicht
   als Fleck mitten im Text, und eine sichtbare Kante zwischen Weiss und
   Fast-Weiss waere lauter als die Tabelle.

   --------- Heller Modus: warum die Marke nicht auf den Knoepfen sitzt -------

   --linie-stark war #cfcbc2 und damit 1.62 gegen Weiss. Solange die farbige
   Flaeche den Hauptknopf trug, fiel das nicht auf; jetzt IST der Rand das
   Kennzeichen der Nebenhandlung und des Eingabefeldes, also muss er die 3.0
   aus SC 1.4.11 halten. --linie (Haarlinie zwischen Zeilen) bleibt hell: sie
   trennt, sie kennzeichnet nichts.

   #50C878 selbst hat gegen Weiss nur 2.13. Es steht deshalb nie allein fuer
   eine Aussage: als Flaeche des aktiven Navipunkts unter gruener, fetter
   Schrift, als Fuellung mit dunkler Schrift darauf. Der Fokusring nimmt
   --fokus (dieselbe Farbe abgedunkelt, 6.98) — ein Ring in 2.13 waere auf
   Weiss nicht zu sehen, und der Fokus ist die eine Markierung, die niemand
   uebersehen darf.

   ------------------- Dunkler Modus: Lorins zwei Werte ----------------------

   --grund #111112 und --flaeche #18181A sind von Lorin vorgegeben und nicht
   verhandelbar: «Hintergrund ist der Dunkle und dann Karten und Nav und
   Sidebar sind der hellere Ton.» Sie loesen die alten #16161a/#1f1f24 ab.

   Die beiden liegen 1.06 auseinander — noch knapper als die alten mit 1.10.
   Das ist keine Nachlaessigkeit, sondern die Folge der Vorgabe, und es
   VERSCHIEBT eine Zustaendigkeit: Die Karte hebt sich nicht mehr durch ihre
   Flaeche vom Grund ab, sie wird durch ihren RAND zur Karte (--linie, 1.81 auf
   dem Grund). Solange --flaeche und --grund so nah beieinander liegen, ist
   --linie tragend und nicht Zierde — wer sie schwaecht, loest die Karten auf.

   Eine erste Fassung dieses Blocks stand auf --flaeche #28282C (1.29 zum
   Grund), weil ich den Wert falsch verstanden hatte; Lorin hat auf #18181A
   korrigiert. Die Zahlen der Tabelle oben sind daraufhin komplett neu
   gerechnet, 18 Zeilen haben sich geaendert. Deshalb steht hier auch, WOHER
   eine Zahl kommt: Ein Kommentar, der die Werte einer verworfenen Fassung
   nennt, ist schlimmer als keiner.

   Gepruft wird das nicht mehr ueber «die Flaeche muss sich abheben» — dieser
   Test war mit 1.06 rot, obwohl die Karte tadellos zu sehen ist. Er fragt jetzt
   nach der Kante und laesst offen, ob Flaeche oder Rand sie traegt:
   GestaltungTest::testDieKarteIstAmRandOderAnDerFlaecheZuErkennen.

   Die abgeleiteten Toene haengen an diesen zwei Werten, und JEDER von ihnen
   wurde neu gerechnet, nicht umgerechnet:

     --flaeche-2 #26262b   Hover und Tabellenstreifen. 1.18 auf der Flaeche —
                           vorher 1.09, der Streifen war fast nicht zu sehen.
     --linie #28282C       Haarlinie, von Lorin vorgegeben. 1.21 auf der
                           Flaeche, 1.29 auf dem Grund. Sie ist das Einzige, was
                           eine Karte als Karte zeigt, weil --flaeche und
                           --grund nur 1.06 auseinanderliegen (siehe oben) — der
                           Kartentest haelt damit ueber den Rand, nicht ueber
                           die Flaeche.

                           Eine Zwischenfassung stand auf #3f3f47 (1.81 auf dem
                           Grund), also deutlich kraeftiger; Lorin hat auf
                           #28282C korrigiert. Die Folge ist sichtbar und hier
                           festgehalten, damit sie niemand fuer einen Fehler
                           haelt: --flaeche-2 #26262b und diese Linie liegen
                           1.03 auseinander, sind also praktisch dieselbe Farbe.
                           In einer UEBERFAHRENEN Tabellenzeile verschwinden die
                           Zeilenraender daher in der Hover-Flaeche.

                           Verworfen: --flaeche-2 nachdunkeln, damit die Linie
                           sich abhebt. Nachgerechnet bringt das fast nichts —
                           bei #1f1f22 waeren es 1.12 statt 1.03 —, weil in
                           diesem sehr dunklen Band alles eng beieinanderliegt.
                           Fuer 0.09 die Hover-Flaeche unsichtbarer zu machen
                           (1.08 statt 1.18 auf der Karte) ist der schlechtere
                           Tausch.
     --linie-stark #55555f Knopf- und Feldrand. 2.41 / 2.56 / 2.04 — und damit
                           UNTER den 3.0 aus SC 1.4.11. Die Abweichung ist
                           Lorins Entscheidung nach drei Runden: #82828f (4.68),
                           dann #74747f (3.84), beide Male «diese hellen weissen
                           Linien sind mir noch immer zu hell», dann «schreiben
                           eine bewusste Abweichung von 1.4.11 in die README».

                           #74747f war das Dunkelste OHNE Abweichung: Das Feld
                           hat keine eigene Flaeche — gemessen ist der Grund
                           eines Textfeldes rgb(24,24,26), also --flaeche, genau
                           wie die Karte darunter. Der Rand ist damit das
                           Einzige, woran es als Feld zu erkennen ist. Auch eine
                           eingesenkte Feldflaeche loest das nicht: #101012 liegt
                           mit 1.07 auf der Karte.

                           WAS DIE ABWEICHUNG TRAEGT (ausfuehrlich in der README):
                           jedes Feld hat eine sichtbare Beschriftung, der
                           Fokusring haelt seine 3.0, und `prefers-contrast: more`
                           stellt #82828f wieder her. Nicht dunkler als das: Bei
                           #4a4a54 sind es 1.72 auf --flaeche-2, und dort steht
                           das Feld in einer ueberfahrenen Zeile — ein Rand, den
                           auch ein gutes Auge auf einem guten Schirm sucht.

     --diagramm-linie      Derselbe Grauton, den --linie-stark vorher hatte
     #8f8a80 / #82828f     (3.43 / 4.68), fuer alles, was DATEN traegt: die
                           gefuellten Kacheln im Verlauf, das Nulllinien- und
                           Lueckenzeichen der Diagramme, das Ringsegment
                           «Tablet», das Tendenzband.

                           Er bleibt bei 3.0, und das ist der Grund, warum die
                           Abweichung oben zu vertreten ist: Ein Rand ist Chrom
                           — daneben stehen Beschriftung, Fokus und Inhalt. Eine
                           Kachel IST die Zahl. Wer sie nicht sieht, liest die
                           Zahl nicht, und es gibt nichts, was einspringt.
     --akzent-leicht #153224  Die Flaeche des aktiven Zustands. UNVERAENDERT,
                           und das ist eine zurueckgenommene Aenderung: In der
                           Fassung auf --flaeche #28282C lag dieser Ton mit 1.06
                           darauf, der aktive Navipunkt waere unsichtbar
                           geworden, und er wurde auf #1d4a34 gehoben. Auf
                           Lorins #18181A sind es 1.28 — die Schwelle 1.08 ist
                           gehalten, die Anhebung also unnoetig. Und sie war ein
                           Verlust: #153224 traegt --akzent-dunkel mit 8.63,
                           #1d4a34 nur mit 6.27. Wer eine Flaeche aufhellt, um
                           sie sichtbar zu machen, bezahlt mit der Lesbarkeit
                           der Schrift darauf — auf diesem Grund war der Preis
                           nicht faellig.
     --akzent-schrift, --knopf-haupt-schrift #111112  Beide waren #16161a, also
                           der alte Grund. Sie folgen ihm auf den neuen.
     --erfolg-flaeche #1b3126, --warnung-flaeche #34281a, --fehler-flaeche
                           #3a2220  Ebenfalls UNVERAENDERT, aus demselben Grund.
                           Auf #28282C lagen sie mit 1.06 / 1.02 / 1.00 auf der
                           Karte — eine Meldung ohne Meldungsflaeche — und waren
                           auf #384741 / #493e34 / #463738 gehoben. Auf #18181A
                           sind es 1.28 / 1.24 / 1.21, und die alten tragen ihre
                           Schrift mit 7.75 / 6.57 / 6.04 statt 5.47 / 4.76 /
                           4.64. Beim Fehler ist das der Unterschied zwischen
                           bequem und knapp: 4.64 liegt 0.14 ueber der
                           Schwelle.

   Der Hauptknopf dreht im dunklen Modus die Rollen: dunkel auf dunkel waere
   kein Knopf mehr, also traegt er die helle Textfarbe als Flaeche.

   DIE DIFF-FLAECHEN bleiben, wie sie sind — halbdurchsichtig, und genau
   deshalb muessen sie nicht mit: rgba(…, .22) ueber --flaeche #18181A ergibt
   #2f4138 / #483130 / #443728, also 1.63 / 1.48 / 1.54 gegen die Karte und
   9.11 / 10.02 / 9.66 fuer --text darauf. Eine Deckung rechnet sich mit ihrem
   Untergrund mit, ein Tokenwert nicht — deshalb prueft
   GestaltungTest::testDieDiffFlaechenTragenTextUeberDerKarte die MISCHUNG.

   DER SCHATTEN tut in diesem Modus fast nichts mehr, und das ist ausgerechnet:
   rgba(0,0,0,.4) ueber --grund #111112 ergibt #0a0a0b — 1.05, unsichtbar.
   Ueber --flaeche #18181A ergibt er #0e0e10, also 1.09 — auch das ist an der
   Grenze des Wahrnehmbaren.

   Damit fiel die Begruendung, mit der er in der Fassung auf #28282C stehen
   blieb: dort ergab er ueber der Karte 1.21 und war bei .block--zieht wirklich
   zu sehen. Auf #18181A sind es 1.09. Er BLEIBT trotzdem, aber der Grund ist
   jetzt ein anderer und ein schwaecherer: Ein gezogener Block braucht ein
   Zeichen, dass er ueber der Seite haengt, und er hat neben dem Schatten nur
   noch seinen Rand. Ihn hier auf `none` zu setzen waere ehrlicher als eine
   Wirkung zu behaupten, die 1.09 nicht hat — aber es waere das Wegnehmen des
   einzigen zweiten Zeichens, und ein Zeichen mehr, das kaum wirkt, ist besser
   als ein Zeichen weniger.

   Wer den gezogenen Block ueberarbeitet, hat hier die offene Frage: Ein
   deutlicherer Rand oder eine Vergroesserung waeren die tragfaehigeren Mittel,
   und dann darf der Schatten im dunklen Modus weg. Die Karte auf dem Grund
   braucht ihn ohnehin nicht — sie traegt ihre Trennung ueber --linie
   (1.81 auf dem Grund), nicht ueber --flaeche/--grund (1.06).

   tests/Unit/GestaltungTest.php liest diese Tokenwerte aus der Datei und
   rechnet die Paare nach. Wer hier eine Farbe aendert und die Schwelle reisst,
   bekommt einen roten Test — nicht eine Oberflaeche, die niemand mehr liest. */

:root {
  --grund: #f5f4f1;
  --flaeche: #ffffff;
  --flaeche-2: #faf9f7;
  --linie: #e3e0da;
  --linie-stark: #8f8a80;
  /* Der Grauton der Diagramme — siehe den Block oben. Im hellen Modus derselbe
     Wert wie der Rand: Dort ist nichts abgesenkt, die Linien sind dunkel auf
     hell und waren nie das Problem. */
  --diagramm-linie: #8f8a80;
  --text: #1e1d1a;
  --text-leise: #6b675f;
  /* Die Marke. Nur Flaeche und Markierung, immer mit dunkler Schrift darauf. */
  --akzent: #50C878;
  /* Dieselbe Farbe abgedunkelt: fuer Schrift und tragende Raender auf Hell. */
  --akzent-dunkel: #17663f;
  --akzent-leicht: #e8f7ee;
  /* Was auf einer Flaeche in --akzent lesbar ist. Nie #fff. */
  --akzent-schrift: #1e1d1a;
  /* Der Fokusring. Eigener Ton und nicht --akzent-dunkel: Er muss 3.0 halten
     und daneben so leise sein, dass ein Formular beim Durchtabben nicht
     aufblitzt. Siehe die Begruendung bei :focus-visible. */
  --fokus: #3d9464;
  /* Die Haupthandlung: neutral, damit die Marke der Zustand bleibt. */
  --knopf-haupt: #50C878;
  --knopf-haupt-hover: #43b96b;
  --knopf-haupt-schrift: #14261c;

  /* Die Flaeche des Nebenknopfs. Sie ERSETZT seinen Rand (Lorins Entscheidung:
     «alle secondary buttons ausgefuellt ohne Border, anstatt nur eine helle
     Border») und traegt damit allein, dass dort ein Bedienelement ist. Deshalb
     ist sie kraeftiger gewaehlt als die zarten Hinterlegungen weiter unten:
     1.18 auf dem Grund, 1.29 auf der Karte, 1.23 auf dem Zeilenstreifen — und
     die schwaechste dieser drei ist die, die zaehlt. */
  /* Der Rand eines gesperrten Feldes: 1.54 auf der Karte, also klar unter den
     3.43 des normalen Randes — «weniger Kontrast als die normale» (Lorin). */
  --rand-gesperrt: #d4d0c8;

  /* Das bedienbare Feld. Im hellen Modus dieselben Werte wie bisher: Lorins
     Vorgabe nennt dunkle Farben, und die gelten dort, wo sie gemeint sind. */
  --feld-flaeche: #ffffff;
  --feld-rand: #8f8a80;
  --feld-text: #1e1d1a;
  --feld-platzhalter: #6b675f;

  --knopf-neben: #e5e2db;
  --knopf-neben-hover: #dbd6cc;
  --warnung: #8a5300;
  --warnung-flaeche: #fdf3e2;
  --fehler: #a12d21;
  --fehler-flaeche: #fbeceb;
  --erfolg: #1c6b3f;
  --erfolg-flaeche: #e8f4ec;
  /* Die Hinterlegungen im Versionsvergleich. Sie standen als rgba() mitten im
     Stylesheet und waeren bei einem Markenwechsel liegen geblieben. */
  --plus-flaeche: rgba(28, 107, 63, .18);
  --minus-flaeche: rgba(161, 45, 33, .18);
  --geaendert-flaeche: rgba(138, 83, 0, .22);
  --radius: 10px;
  --radius-klein: 6px;
  --schatten: 0 1px 2px rgba(28, 27, 24, .06), 0 4px 12px rgba(28, 27, 24, .04);
  --seitenleiste: 15rem;
  /* Stand vorher nur als Ersatzwert hinter dem Komma und war damit nirgends
     definiert. Ein Ersatzwert, der die eigentliche Angabe ist, ist eine Angabe,
     die niemand findet — und die kein Projekt ueberschreiben kann. */
  --schrift-fest: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  /* Kleinste Trefferflaeche fuer ein Bedienelement mit dem Finger. */
  --griff: 2.75rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Die zwei Werte kommen von Lorin. Alles darunter ist daraus gerechnet;
       die Zahlen stehen im Kommentar ueber diesem Block. */
    --grund: #111112;
    --flaeche: #18181A;
    --flaeche-2: #26262b;
    --linie: #28282C;
    --linie-stark: #55555f;
    --diagramm-linie: #82828f;
    --text: #ecebe8;
    --text-leise: #a3a09a;
    --akzent: #50C878;
    --akzent-dunkel: #7ce0a4;
    --akzent-leicht: #153224;
    --akzent-schrift: #111112;
    --fokus: #3c8c5a;
    --knopf-haupt: #50C878;
    --knopf-haupt-hover: #43b96b;
    --knopf-haupt-schrift: #14261c;

    /* 1.48 auf dem Grund, 1.39 auf der Karte, 1.18 auf dem Zeilenstreifen.
       #2b2b31 waere naeher an Lorins Vorlage gewesen, lag aber mit 1.07 auf
       --flaeche-2 (#26262b) — ein Knopf in einer ueberfahrenen Tabellenzeile
       waere dort verschwunden. */
    /* 1.57 auf der Karte, gegen 2.41 beim normalen Rand. */
    --rand-gesperrt: #3a3a42;

    /* Lorins Werte für ein bedienbares Feld. Gerechnet:
         Schrift #ffffff auf #202023      16.25   (min 4.5)   ✓
         Fläche  #202023 auf der Karte     1.09   (min 1.08)  ✓ knapp
         Rand    #323239 auf der Karte     1.39   (min 3.0)   ✗ bewusst
         Platzhalter #636365 auf #202023   2.71   (min 4.5)   ✗ bewusst
       Die zwei Abweichungen stehen in der README, Punkt 9c. */
    --feld-flaeche: #202023;
    --feld-rand: #323239;
    --feld-text: #ffffff;
    --feld-platzhalter: #636365;

    --knopf-neben: #323239;
    --knopf-neben-hover: #3c3c45;
    --warnung: #e0a458;
    --warnung-flaeche: #34281a;
    --fehler: #f08a7e;
    --fehler-flaeche: #3a2220;
    --erfolg: #7fd3a1;
    --erfolg-flaeche: #1b3126;
    /* Halbdurchsichtig und deshalb unveraendert: sie rechnen sich mit dem
       Untergrund mit. Die Werte ueber --flaeche stehen im Kommentar oben. */
    --plus-flaeche: rgba(127, 211, 161, .22);
    --minus-flaeche: rgba(240, 138, 126, .22);
    --geaendert-flaeche: rgba(224, 164, 88, .22);
    --schatten: 0 1px 2px rgba(0, 0, 0, .4);
  }
}

/* WER MEHR KONTRAST BRAUCHT, BEKOMMT IHN. `--linie-stark` liegt im dunklen
   Modus mit 2.41 unter den 3.0 aus SC 1.4.11 — eine bewusste Abweichung
   (README, «Bewusste Abweichungen», Punkt 9a). Hier steht ihr Gegenstueck: Meldet
   das System «mehr Kontrast», gilt wieder #82828f mit 4.68 / 4.98 / 3.97.

   Diese Anfrage kommt von einer Einstellung des Betriebssystems (Windows:
   Kontrastdesigns, macOS: «Kontrast erhoehen») und nicht von einem Schalter im
   Admin. Genau deshalb ist sie hier der richtige Ort: Wer die Einstellung
   gesetzt hat, hat die Entscheidung schon getroffen, und zwar fuer alle
   Programme. Ein eigener Schalter waere eine zweite Stelle, an der dasselbe
   entschieden wird — und die Redaktion muesste ihn erst finden.

   Nur der dunkle Modus: Im hellen ist der Rand nicht abgesenkt. */
@media (prefers-color-scheme: dark) and (prefers-contrast: more) {
  :root { --linie-stark: #82828f; }
}

/* Und der Rand des Nebenknopfs kommt zurueck — in BEIDEN Modi.
   Seit die Nebenknoepfe gefuellt und randlos sind, traegt ihre Flaeche allein,
   dass dort ein Bedienelement ist: 1.18 bis 1.48, nicht die 3.0 aus SC 1.4.11.
   Eine Flaeche, die 3.0 haelt, waere ein mittleres Grau und schwerer als der
   gruene Hauptknopf — die Gestaltung will das nicht, und Lorin hat es so
   entschieden.

   Wer dem System «mehr Kontrast» gesagt hat, hat etwas anderes entschieden.
   Dann steht der Rand wieder da: --linie-stark haelt hell 3.43 und dunkel 4.68
   (dort greift der Block darueber). Die Fuellung bleibt — beides zusammen ist
   deutlicher als eines davon, und die Knoepfe springen nicht um. */
@media (prefers-contrast: more) {
  .knopf, .block__werkzeug { border-color: var(--linie-stark); }

  /* Der Hauptknopf behaelt seinen eigenen Rand: Seine Flaeche haelt 3.0 von
     selbst, und ein grauer Rand um Gruen waere hier nur Unruhe. */
  .knopf--haupt { border-color: var(--knopf-haupt); }
  .knopf--haupt:hover { border-color: var(--knopf-haupt-hover); }
  .knopf--zweit { border-color: var(--akzent-dunkel); }
  .knopf--gefahr, .block__werkzeug--gefahr { border-color: var(--fehler); }
  .knopf--text { border-color: transparent; }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-size: 16px;
  line-height: 1.55;
  color: var(--text);
  background: var(--grund);
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5rem; font-weight: 600; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 1rem; }
/* Links neutral dunkel und unterstrichen. Der Unterstrich ist das Kennzeichen,
   nicht die Farbe — ein Link, den nur ein Farbton von Text unterscheidet, ist
   fuer einen Teil der Leserinnen kein Link. Die Marke bleibt dem Zustand. */
a {
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}
a:hover { color: var(--text); text-decoration-thickness: 2px; }

/* DER FOKUSRING. Zwei Pixel und ein eigener, gedaempfter Gruenton — Lorins
   Befund zur ersten Fassung: «die kontrastreiche Outline noch zu kontrastreich,
   mache die subtiler».

   Vorher: 3px in --fokus, das im Dunkeln die Marke selbst war (#50C878, 8.34 auf
   der Karte) und im Hellen die gruene Schrift (#17663f, 6.98 auf Weiss). Damit
   sprang der Ring beim Durchtabben durch ein Formular wie eine Warnung an.
   Jetzt (gerechnet, hell / dunkel):

     auf --flaeche         3.74 / 4.30    vorher 6.98 / 8.34
     auf --grund           3.40 / 4.58
     auf --flaeche-2       3.55 / 3.65
     auf --akzent-leicht   3.38 / 3.36    der knappste Fall

   Der Boden ist 3.0 aus SC 1.4.11, und darunter geht es nicht: Der Ring ist die
   einzige Markierung, auf die jemand angewiesen ist, der die Maus nicht
   benutzt. Die 3.36 auf der gruenen Flaeche des aktiven Navipunkts ist die
   engste Stelle — wer die Palette anfasst, prueft sie zuerst.

   Zwei Pixel und nicht einer: Ein 1px-Ring erfuellt die Mindestflaeche aus
   SC 2.4.13 nicht, und auf einem Bildschirm mit doppelter Pixeldichte ist er
   eine Haarlinie. Der Abstand von 2px bleibt: Ohne ihn verschmilzt der Ring mit
   dem Feldrand, und dann sieht man ihn nur noch an der Farbe. */
:focus-visible {
  outline: 2px solid var(--fokus);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Der Griff, mit dem admin.css an ein Symbol aus icon() kommt — die Klasse
   setzt Support\Icons. Die SVGs bringen width/height="1em" und
   fill="currentColor" schon als Attribute mit; hier steht nur, was ein Symbol im
   Textfluss braucht. Die Seitenleiste setzt ihre eigene Groesse, und zwar ueber
   `.nav-punkt svg` — als Element und nicht ueber diese Klasse, damit die Leiste
   nicht daran haengt, wie die Klasse heisst. */
.symbol { flex: none; vertical-align: -.15em; }

/* Nur fuer Screenreader — Beschriftungen, die sichtbar redundant waeren. */
.nur-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.sprung {
  position: absolute;
  left: -999px;
  top: .5rem;
  background: var(--flaeche);
  padding: .6rem 1rem;
  border-radius: var(--radius-klein);
  z-index: 100;
}
.sprung:focus { left: .5rem; }

/* ---------------------------------------------------------------- Gerüst */

.huelle { display: flex; min-height: 100vh; }

.seitenleiste {
  width: var(--seitenleiste);
  flex: 0 0 var(--seitenleiste);
  background: var(--flaeche);
  border-right: 1px solid var(--linie);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

/* Der Markenblock IST der Weg zur Uebersicht.
   Lorins Entscheidung: «da man auf das Logo klicken kann und auf die Übersicht
   kommt» — der Punkt «Übersicht» faellt dafuer aus der Liste. Drei Dinge muessen
   deshalb hier stehen und nicht nur im Template:

   1. ER MUSS ALS LINK ZU ERKENNEN SEIN. Vorher war der Block eine Ueberschrift
      und sah auch danach aus. Das Kennzeichen ist der Unterstrich am
      Projektnamen — dieselbe Regel wie bei jedem anderen Link im Admin (siehe
      `a { text-decoration: underline }` oben). Verworfen: nur ein Hover-Effekt.
      Ein Link, den man erst beim Ueberfahren erkennt, ist mit dem Finger und
      mit der Tastatur kein Link.
   2. AUF DER UEBERSICHT TRAEGT ER aria-current UND DIE AKTIVE FLAECHE. Sonst
      zeigt die Leiste auf dem Dashboard keinen aktiven Punkt — derselbe Fehler
      wie frueher beim Benutzerkreis, wo jemand sich fuer aus der Verwaltung
      herausgefallen hielt.
   3. Die Beschriftung sagt, wohin er fuehrt. «PXL Demo AG» allein sagt es
      nicht; der Zusatz steht in einem .nur-sr HINTER dem sichtbaren Text, damit
      der sichtbare Text im zugaenglichen Namen enthalten bleibt (SC 2.5.3).
      Verworfen: aria-label — das haette den sichtbaren Text ersetzt.

   Die gruene Zeile «WEBSITE-VERWALTUNG» nimmt --akzent-dunkel (6.98 hell /
   9.13 dunkel auf der Flaeche); #50C878 selbst haette als Schrift auf Weiss
   2.13. Auf der aktiven Flaeche sind es 6.30 / 6.27. */
.seitenleiste__marke {
  display: block;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--linie);
  font-weight: 600;
  font-size: .95rem;
  color: var(--text);
  text-decoration: none;
}
.seitenleiste__marke:hover { background: var(--flaeche-2); color: var(--text); }
.seitenleiste__marke[aria-current="page"] { background: var(--akzent-leicht); }

.seitenleiste__marke small {
  display: block;
  font-weight: 600;
  color: var(--akzent-dunkel);
  font-size: .75rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* Kein Unterstrich, und etwas groesser als die Zeile darueber (Lorins
   Aenderung). Damit ist der Markenblock die eine begruendete Ausnahme von der
   Hausregel «jeder Link ist unterstrichen»: Er ist kein Link IM Text, er ist
   das Logo — und ein Logo, das zur Startseite fuehrt, ist die aelteste
   Konvention des Web. Wer hier den Unterstrich wieder einsetzt, macht aus dem
   Logo eine Textstelle.

   Dass er anklickbar ist, tragen weiterhin zwei Zeichen: die Flaeche beim
   Ueberfahren und der Mauszeiger. Fuer einen Screenreader steht es im
   .nur-sr-Zusatz «– Zur Übersicht» ausgeschrieben — der ist deshalb nicht
   Zierde, sondern seit dieser Aenderung die einzige nicht-optische Auskunft
   darueber, wohin der Block fuehrt. */
.seitenleiste__marke-name {
  display: block;
  font-size: 1.05rem;
  line-height: 1.25;
}
.seitenleiste__marke[aria-current="page"] .seitenleiste__marke-name { color: var(--akzent-dunkel); }

/* Die Punkte stehen enger als vorher (Lorins Entwurf) und jeder traegt seine
   eigene, abgerundete Flaeche. Der Innenabstand wandert deshalb von der Nav auf
   den Punkt: Laege er weiter auf der Nav, ginge die Flaeche von Rand zu Rand
   und waere keine Pille, sondern ein Balken. */
.seitenleiste__nav {
  flex: 1;
  overflow-y: auto;
  padding: .5rem .6rem;
  display: flex;
  flex-direction: column;
  gap: .1rem;
}

.nav-gruppe {
  padding: .85rem .65rem .25rem;
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-leise);
}

.nav-punkt {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .3rem .65rem;
  border-radius: var(--radius-klein);
  color: var(--text);
  text-decoration: none;
  font-size: .93rem;
  line-height: 1.35;
}
.nav-punkt:hover { background: var(--flaeche-2); color: var(--text); }

/* Das Icon ist Beiwerk NEBEN einer Beschriftung, nicht ihr Ersatz: icon()
   liefert es mit aria-hidden, die Farbe kommt ueber currentColor mit, und die
   Groesse entscheidet die Leiste. Angesprochen als Element und nicht ueber eine
   Klasse — welche Klasse icon() setzt, ist Sache von icon(). */
.nav-punkt svg {
  width: 1.25em;
  height: 1.25em;
  flex: none;
}

/* Der aktive Zustand: abgerundete Flaeche, gruene Schrift, gruenes Icon
   (Lorins Entwurf). Er haengt NICHT an der Farbe allein — die Flaeche wechselt,
   die Schrift wird fett, und aria-current sagt es beim Vorlesen. Gemessen:
   --akzent-dunkel auf --akzent-leicht 6.30 hell / 6.27 dunkel.

   Der Hover traegt AUCH eine Flaeche, deshalb muessen die zwei sich mehr als in
   der Helligkeit unterscheiden: Hover ist neutral (--flaeche-2, Schrift bleibt
   --text), aktiv ist gruen (--akzent-leicht, Schrift --akzent-dunkel, fett).
   --akzent-leicht gegen --flaeche-2: 1.05 hell / 1.19 dunkel — als einziger
   Unterschied waere das zu wenig, mit Farbton, Schriftfarbe und Fettung
   zusammen ist es eindeutig.

   VORHER war das Kennzeichen ein 4-px-Randstreifen links in #50C878. Die
   Begruendung damals: #50C878 hat gegen Weiss nur 2.13 und darf nicht allein
   stehen. Sie gilt weiter — nur traegt jetzt die Flaeche die Aussage und
   #50C878 kommt als Schriftfarbe gar nicht mehr vor (dafuer gibt es
   --akzent-dunkel). Der Streifen faellt, weil er waagerecht — in der schmalen,
   rollenden Leiste — jedes Mal ein anderer Rand sein musste und beim naechsten
   Umbau in einem der zwei Zustaende vergessen wird. Die Pille sieht in beiden
   Richtungen gleich aus.

   Die Regel steht NACH :hover: beide haben dieselbe Gewichtung
   (Klasse + Attribut bzw. Klasse + Pseudoklasse), also entscheidet die
   Reihenfolge. Der aktive Punkt soll aktiv bleiben, wenn die Maus darueber
   liegt — «du bist hier» ist die wichtigere Auskunft. */
.nav-punkt[aria-current="page"] {
  background: var(--akzent-leicht);
  color: var(--akzent-dunkel);
  font-weight: 600;
}

/* Enger heisst nicht kleiner zum Antippen. Der Punkt ist jetzt rund 30 px hoch
   (0.93rem × 1.35 Zeilenhoehe + 2 × 0.3rem) — mit der Maus genug, mit dem
   Finger nicht. Am ZEIGEGERAET und nicht an der Fensterbreite: Ein Tablet im
   Querformat ist breit UND wird angetippt, und genau dort stand die Leiste
   bisher senkrecht mit Punkten unter 44 px. --griff sind die 2.75rem = 44 px,
   die im Haus schon fuer Blockwerkzeuge und Zeitspannen gelten. */
@media (pointer: coarse) {
  .seitenleiste__nav { gap: .2rem; }
  .nav-punkt { min-height: var(--griff); }
}

/* Konto und sein Menue stehen NEBENEINANDER, Name und Rolle untereinander.
   Vorher lag der Abmelden-Knopf als breite Flaeche unter dem Namen: Abmelden
   ist die seltenste Handlung im ganzen Admin und hatte die auffaelligste
   Flaeche in der Leiste. Jetzt liegt sie im Menue, einen Klick entfernt. */
.seitenleiste__fuss {
  border-top: 1px solid var(--linie);
  padding: .75rem 1rem;
  display: flex;
  align-items: center;
  gap: .25rem;
}
.seitenleiste__fuss .benutzer { flex: 1 1 auto; min-width: 0; }

.benutzer {
  display: flex;
  align-items: center;
  gap: .6rem;
  text-decoration: none;
  color: var(--text);
  padding: .35rem;
  border-radius: var(--radius-klein);
}
.benutzer { text-decoration: none; }
.benutzer:hover { background: var(--flaeche-2); }

/* Der Benutzerkreis ist der Weg zum Profil, also ein Navigationspunkt wie die
   anderen — und muss deshalb dieselbe Zustandsmarkierung bekommen. Ohne sie
   stand jemand im Profil vor einer Leiste ohne aktiven Punkt und hielt sich fuer
   aus der Verwaltung herausgefallen. */
.benutzer[aria-current="page"] {
  background: var(--akzent-leicht);
  box-shadow: inset 3px 0 0 var(--akzent);
}
.benutzer[aria-current="page"] .benutzer__name { font-weight: 600; }

.benutzer__kreis {
  width: 2rem; height: 2rem;
  border-radius: 50%;
  background: var(--akzent-leicht);
  color: var(--akzent-dunkel);
  display: grid;
  place-items: center;
  font-size: .78rem;
  font-weight: 600;
  flex: none;
}
/* Untereinander, und ein langer Name wird gekuerzt statt das Menue
   hinauszudruecken. min-width: 0 gehoert dazu — ohne das ignoriert ein
   Flex-Kind seine eigene Kuerzung und waechst trotzdem. */
.benutzer__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.benutzer__name {
  font-size: .88rem;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.benutzer__rolle { font-size: .74rem; color: var(--text-leise); }

/* ---------------------------------------------------------------- Kontomenue

   Das Dreieck, das ein <summary> von sich aus mitbringt, muss weg: Der Traeger
   ist hier die Punktreihe. list-style UND ::-webkit-details-marker, weil die
   beiden Browserfamilien es verschieden loesen. */
.kontomenue { position: relative; flex: none; }

/* KEIN display auf dem <summary>.
   Ein <summary> ist fuer Screenreader ein Knopf mit Auf-/Zu-Zustand — aber nur,
   solange sein display der Vorgabewert `list-item` bleibt. Mit `display: grid`
   verliert es diese Rolle: im Accessibility-Baum stand danach «generic "Menü zum
   Konto"» statt «button, collapsed». Nachgemessen mit read_page, nachdem ich
   genau das gebaut hatte.
   Deshalb wird hier nicht das summary zum Raster, sondern die Punktreihe
   absolut in seine Mitte gestellt. Dasselbe Ergebnis, ohne die Rolle zu
   opfern. */
.kontomenue__knopf {
  list-style: none;
  position: relative;
  width: 2rem; height: 2rem;
  border-radius: var(--radius-klein);
  cursor: pointer;
  color: var(--text-leise);
}
.kontomenue__knopf::-webkit-details-marker { display: none; }
.kontomenue__knopf:hover { background: var(--flaeche-2); color: var(--text); }
.kontomenue[open] .kontomenue__knopf { background: var(--flaeche-2); color: var(--text); }

/* Drei Punkte aus Rand-Schatten statt aus einem Schriftzeichen: ein Glyph wie
   «⋮» faellt je nach Schrift anders aus und fehlt in manchen ganz. */
.kontomenue__punkte {
  position: absolute;
  top: 50%; left: 50%;
  margin: -1.5px 0 0 -1.5px;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 -5px 0 currentColor, 0 5px 0 currentColor;
}

/* Nach OBEN, weil das Menue am unteren Rand der Leiste sitzt — nach unten
   waere es ausserhalb des Fensters. */
.kontomenue__tafel {
  position: absolute;
  bottom: calc(100% + .35rem);
  right: 0;
  min-width: 11rem;
  z-index: 30;
  display: flex;
  flex-direction: column;
  padding: .3rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgb(0 0 0 / .18);
}

.kontomenue__punkt {
  font: inherit;
  font-size: .88rem;
  text-align: left;
  padding: .45rem .55rem;
  border: 0;
  border-radius: var(--radius-klein);
  background: none;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  width: 100%;
}
.kontomenue__punkt:hover { background: var(--flaeche-2); }

.inhalt { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.15rem 1.75rem;
  border-bottom: 1px solid var(--linie);
  background: var(--flaeche);
  flex-wrap: wrap;
}
.kopf h1 { margin: 0; }

/* flex-wrap fehlte. Alle Kinder tragen white-space: nowrap, der Bereich konnte
   also nicht schmaler werden als seine Summe (im Editor gemessen: 448 px) — bei
   390 px Fensterbreite scrollte die ganze Seite waagrecht, und «Vorschau» lag
   ausserhalb. R.2 verlangt, dass Lesen und kleine Korrekturen mobil gehen. */
.kopf__aktionen {
  display: flex;
  gap: .5rem;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Ein Satz, der zu einem Knopf in der Kopfzeile gehoert: eigene Zeile unter der
   Reihe, damit er beim Knopf steht und nicht in der Seitenspalte. */
.kopf__hinweis {
  flex-basis: 100%;
  margin: 0;
  text-align: right;
  max-width: 30rem;
  margin-left: auto;
}

.hauptteil { padding: 1.75rem; max-width: 68rem; width: 100%; }

/* ---------------------------------------------------------------- Bausteine */

.karte {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  margin-bottom: 1.25rem;
}
.karte__kopf {
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--linie);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}
.karte__kopf h2 { margin: 0; }
.karte__rumpf { padding: 1.25rem; }
.karte__rumpf > :last-child { margin-bottom: 0; }

/* ================================================================ Kopf und Weg

   Lorin hat einen Bildschirm entworfen und dazu gesagt, das uebrige UI wirke
   «als waeren nur ungestylte HTML Elemente aufeinander getuermt». Der Entwurf
   bringt vier Dinge, die genau das beheben, und sie stehen hier als Bausteine,
   weil sie danach auf jeden Bildschirm sollen: ein Kopf mit Zurueck-Knopf, ein
   Weg (Brotkrumen), Listen als aufklappbare Karten statt einer Tabelle, und
   eine Seitenspalte fuer Zahlen und Handlungen. */

.kopf__zeile {
  display: flex;
  align-items: center;
  gap: .75rem;
  min-width: 0;
}

/* Gefuellt und nicht nur umrandet (Lorins Sollbild): Auf der Flaeche der
   Kopfleiste war ein Kreis mit Haarlinie kaum zu sehen. Die Fuellung ist die
   zweite Flaeche — dieselbe, die jeden Hover im Admin traegt —, damit der
   Knopf ohne eigene Farbe auskommt und trotzdem als Flaeche liest.

   Rund, damit er nicht mit den rechteckigen Knoepfen rechts verwechselt wird:
   Er fuehrt weg von hier, die anderen tun etwas hier. */
.kopf__zurueck {
  flex: none;
  width: 2.1rem; height: 2.1rem;
  display: grid;
  place-items: center;
  background: var(--flaeche-2);
  border: 1px solid var(--linie);
  border-radius: 50%;
  color: var(--text-leise);
  text-decoration: none;
  font-size: 1.05rem;
  line-height: 1;
}
.kopf__zurueck:hover {
  background: var(--linie);
  color: var(--text);
  border-color: var(--linie-stark);
}

/* Der Weg. Als <nav> mit einer Liste und nicht als Kette von Links mit «>»
   dazwischen: Ein Screenreader kuendigt damit «Navigation, 3 Elemente» an,
   statt drei Links ohne Zusammenhang zu lesen. Das Zeichen zwischen den
   Stufen kommt aus CSS und ist aria-hidden, weil «grösser als» vorgelesen
   sinnlos ist. */
/* flex-basis ist weg: Die Brotkrumen sind kein Kind der Kopfleiste mehr,
   sondern das erste Element des Hauptteils. Der Abstand nach unten trennt sie
   vom Inhalt, nach oben braucht es keinen — die Kopfleiste hat ihren eigenen
   Innenabstand und eine Trennlinie. */
.brotkrumen {
  margin: 0 0 1.25rem;
  font-size: .82rem;
}
.brotkrumen ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .15rem .45rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.brotkrumen li { display: flex; align-items: center; gap: .45rem; }
.brotkrumen li + li::before {
  /* Das Zeichen steht als ZEICHEN da und nicht als CSS-Escape. «A»
     wurde bei der Bearbeitung als oktale Sequenz gelesen — in der Datei
     landeten U+0083 und ein «A», und auf dem Bildschirm stand ein
     Kaestchen mit einem A daneben. Ein Escape, das durch drei Werkzeuge
     muss, ist ein Escape zu viel. */
  content: '›';
  color: var(--text-leise);
  opacity: .7;
}
.brotkrumen a { color: var(--text-leise); text-decoration: none; }
.brotkrumen a:hover { color: var(--text); text-decoration: underline; }
/* Die letzte Stufe ist kein Link — sie ist die Seite, auf der man steht. */
.brotkrumen [aria-current="page"] { color: var(--text); }

/* ---------------------------------------------------------------- Zwei Spalten

   Inhalt links, Zahlen und Handlungen rechts. Die Seitenspalte ist ein <aside>
   und steht im Markup NACH dem Inhalt: Wer mit der Tastatur oder einem
   Screenreader arbeitet, will die Liste zuerst, nicht die Kennzahlen. Optisch
   steht sie trotzdem rechts daneben — dafuer ist ein Raster da. */
.spalten {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 19rem;
  gap: 1.25rem;
  align-items: start;
}
.spalten__inhalt { min-width: 0; }
.spalten__seite { display: flex; flex-direction: column; gap: 1.25rem; }
.spalten__seite .karte { margin-bottom: 0; }

/* Unter 66rem wird aus zwei Spalten eine: Bei 19rem Seitenspalte bleiben dem
   Inhalt sonst weniger als 30rem, und die Liste bricht in jeder Zeile um. */
@media (max-width: 66rem) {
  .spalten { grid-template-columns: minmax(0, 1fr); }
}

/* Ein Bildschirm mit Seitenspalte braucht mehr Breite als die 68rem, die fuer
   eine Textspalte richtig sind. */
.hauptteil--breit { max-width: 84rem; }

/* ---------------------------------------------------------------- Kennzahlen

   Die Zahlen der Seitenspalte. Rechtsbuendig und mit gleichlaufenden Ziffern,
   damit die Spalte eine Spalte ist: Mit proportionalen Ziffern sitzt die 1
   enger als die 8 und die Zahlen wackeln. */
.kennzahlen { display: flex; flex-direction: column; gap: 0; }
.kennzahl {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--linie);
}
.kennzahl:last-child { border-bottom: 0; padding-bottom: 0; }
.kennzahl:first-child { padding-top: 0; }
.kennzahl__name { color: var(--text-leise); font-size: .88rem; }
.kennzahl__wert {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}
/* Eine Zahl, die eine Handlung nahelegt, traegt die Marke — aber nur, wenn sie
   nicht null ist. Eine gruene Null waere ein Alarm ohne Anlass. */
.kennzahl__wert--achtung { color: var(--akzent-dunkel); }

/* ---------------------------------------------------------------- Handlungen */
.handlungen { display: flex; flex-direction: column; gap: .5rem; align-items: stretch; }
.handlungen .knopf { justify-content: center; width: 100%; }
.handlungen__hinweis { margin: .25rem 0 0; font-size: .8rem; color: var(--text-leise); }

/* ---------------------------------------------------------------- Eintragsliste

   Aus der Tabelle werden Karten, die sich AN DER STELLE aufklappen. Lorins
   Entwurf zeigt das, und es ist mehr als Aussehen: Wer zwanzig Eingaenge
   durchsieht, brauchte vorher vierzig Seitenwechsel — hinein, zurueck, hinein.

   Als <details> und nicht als eigenes Skriptwerkzeug, aus demselben Grund wie
   beim Seitenbaum und beim Kontomenue: Es klappt ohne JavaScript auf, es ist
   mit der Tastatur bedienbar, und Screenreader kuendigen es als «Aufklappen,
   zugeklappt» an. Ein nachgebauter Umschalter waere ohne Skript ein toter
   Streifen — und die Nachricht darin unerreichbar.

   Die Einzelseite BLEIBT (forms.entry). Ein aufgeklappter Bereich hat keine
   eigene Adresse: weiterschicken, ausdrucken oder als Lesezeichen ablegen
   liesse sich ein Eingang sonst nicht mehr. Im aufgeklappten Rumpf steht
   deshalb ein Verweis darauf. */
.eintraege { display: flex; flex-direction: column; gap: .5rem; margin-bottom: 1.25rem; }

.eintrag {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  /* Der gruene Streifen der ungelesenen Zeile ersetzt keine Angabe, er
     wiederholt sie: Das Wort «neu» steht daneben. Farbe allein ist fuer rund
     jeden zwoelften Mann kein Unterschied. */
  border-left: 3px solid transparent;
}
.eintrag[data-neu] { border-left-color: var(--akzent); }
/* KEIN anderer Rahmen beim Aufklappen. Erst stand hier
   «border-color: var(--linie-stark)» — der Rand, der sonst
   Eingabefelder kennzeichnet. Um eine aufgeklappte Karte gezogen sah er wie
   ein Fehlerrahmen aus. Dass die Karte offen ist, sagt schon ihr Inhalt. */

.eintrag__kopf {
  list-style: none;
  cursor: pointer;
  padding: .7rem 1rem;
}
.eintrag__kopf::-webkit-details-marker { display: none; }
.eintrag__kopf:hover { background: var(--flaeche-2); }
.eintrag[open] .eintrag__kopf { background: var(--flaeche-2); }

/* Das Raster sitzt in einem SPAN im summary und nicht am summary selbst: Ein
   <summary> mit eigenem display verliert in manchen Browsern seine Rolle als
   Aufklapp-Schaltflaeche, und die ist hier die ganze Bedienung. */
.eintrag__zeile {
  display: grid;
  /* Eine Spalte weniger als vorher: Das Aufklappzeichen ist weg. */
  grid-template-columns: 5.5rem minmax(9rem, auto) minmax(0, 1fr) auto;
  align-items: center;
  gap: .25rem 1rem;
}

/* Eine Eintragszeile OHNE Spaltenraster: Hauptsache links, ein Wort rechts.
   Gebraucht im Papierkorb, wo es keine vier vergleichbaren Angaben gibt — nur
   den Titel und, wann er geloescht wurde. Vier Spalten fuer zwei Werte machen
   aus dem Raster eine Behauptung. */
.eintrag__zeile--einfach {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.eintrag__zeile--einfach .eintrag__wer { flex: 1 1 auto; }
/* Der Vorschautext darf hier umbrechen: Er traegt Slug UND Zeitpunkt, und
   abgeschnitten fehlte die Haelfte der Auskunft. */
.eintrag__zeile--einfach .eintrag__vorschau {
  display: block;
  white-space: normal;
  font-size: .82rem;
  overflow: visible;
}

/* Gleichlaufende Ziffern, damit die Datumsspalte eine Spalte bleibt. */
.eintrag__datum {
  font-variant-numeric: tabular-nums;
  font-size: .82rem;
  letter-spacing: .02em;
  color: var(--text-leise);
  white-space: nowrap;
}
.eintrag__wer { min-width: 0; }
.eintrag__name { font-weight: 600; }
/* Die Adresse in der Marke, weil sie das Anklickbare ist — im aufgeklappten
   Rumpf ist sie ein echter mailto-Link. In der Zeile nicht: Ein Link IM
   summary wuerde beim Klick das Mailprogramm oeffnen, statt aufzuklappen. */
.eintrag__mail { color: var(--akzent-dunkel); font-size: .9rem; }
.eintrag__vorschau {
  color: var(--text-leise);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* Hier stand ein Plus, das sich beim Aufklappen zum Minus drehte. Lorin will
   es nicht: «es geht auch ohne». Es geht auch ohne, weil die Bedienbarkeit
   nicht daran hing — <details> kuendigt sich fuer Screenreader selbst als
   «Aufklappen, zugeklappt» an, der Mauszeiger zeigt die Hand, und die ganze
   Zeile ist die Flaeche. Was das Zeichen leistete, war eine Einladung; was es
   kostete, war eine Spalte in jeder Zeile. */

/* ------- der aufgeklappte Rumpf ------- */
/* Felder WAAGRECHT oben, Nachricht ueber die ganze Breite darunter (Lorins
   zweites Sollbild). Vorher standen die Felder in einer Spalte links und die
   Nachricht rechts daneben — bei vier kurzen Feldern und einem langen Text war
   die linke Spalte nach vier Zeilen fertig und die rechte lief weiter, also
   eine hohe schmale Textspalte neben viel Leerraum. Waagrecht braucht die
   Nachricht die ganze Breite und liest sich in normal langen Zeilen. */
.eintrag__rumpf {
  padding: 1rem 1rem 1.1rem;
  border-top: 1px solid var(--linie);
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
@media (max-width: 46rem) {
  .eintrag__zeile { grid-template-columns: 5.5rem minmax(0, 1fr) auto; }
  .eintrag__vorschau { display: none; }
}

/* Beschriftung ueber dem Wert, nicht daneben: Bei «E-Mail» neben einer langen
   Adresse bleibt fuer die Adresse nichts uebrig, und sie ist das Wichtige.
   In der waagrechten Reihe umbrechen die Felder, wenn sie nicht passen — ein
   Zustimmungsfeld traegt seinen ganzen Einwilligungssatz als Beschriftung und
   braucht dann eine eigene Zeile. */
.eintrag__felder {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .9rem 2rem;
}
.eintrag__feld { min-width: 0; max-width: 22rem; }
.eintrag__feld dt {
  font-size: .78rem;
  color: var(--text-leise);
  margin-bottom: .1rem;
}
.eintrag__feld dd { margin: 0; overflow-wrap: anywhere; }
.eintrag__feld a { color: var(--akzent-dunkel); }

.eintrag__nachricht { min-width: 0; }
.eintrag__nachricht > p { margin: 0; white-space: pre-line; overflow-wrap: anywhere; }
/* Dieselbe Form wie eine Feldbeschriftung, aber kein dt: Die Nachricht steht
   ausserhalb der Definitionsliste, weil sie die zweite SPALTE ist. */
.eintrag__nachricht-label {
  font-size: .78rem;
  color: var(--text-leise);
  margin: 0 0 .1rem;
}

.eintrag__handlungen {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  align-items: center;
  padding-top: .15rem;
}

/* ---------------------------------------------------------------- Icon-Knopf

   Lorins Entwurf: Statt «Als gelesen | Als eigene Seite | Datum» eine Reihe
   Icons, und beim Ueberfahren sagt ein Tooltip, was sie tun.

   Drei Dinge, die ein Icon-Knopf ohne Wort braucht, damit er kein Raetsel ist:

   1. Einen NAMEN fuer alles, was nicht sieht. Das Icon ist aria-hidden, der
      Name steht in einem .nur-sr — nicht in einem aria-label, damit er auch bei
      abgeschaltetem CSS und in der Vorlesereihenfolge dort steht, wo er
      hingehoert.
   2. Den Tooltip AUCH bei Tastaturfokus, nicht nur beim Ueberfahren. Wer mit
      der Tastatur arbeitet, faehrt mit keiner Maus darueber, und ein Hinweis,
      den nur die Maus zeigt, existiert fuer diese Person nicht.
   3. Eine Flaeche von mindestens 44 px auf dem Tablet. Ein 20-px-Icon ist mit
      dem Finger nicht zu treffen.

   Der Tooltip kommt aus data-hinweis und NICHT aus dem title-Attribut: Ein
   title erscheint erst nach einer Sekunde, ist nicht gestaltbar und wird auf
   dem Tablet gar nicht angezeigt. Er ist aria-hidden, weil der Name schon im
   .nur-sr steht — sonst liest ein Screenreader beides. */
.iconknopf {
  position: relative;
  flex: none;
  width: 2.1rem; height: 2.1rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-klein);
  background: none;
  color: var(--text-leise);
  cursor: pointer;
  font: inherit;
  text-decoration: none;
}
.iconknopf:hover,
.iconknopf:focus-visible {
  background: var(--flaeche-2);
  border-color: var(--linie);
  color: var(--text);
}
/* Der Papierkorb ist unwiderruflicher als die anderen — nicht in der Farbe der
   Ruhe, aber beim Ueberfahren. Immer rot waere ein Daueralarm in jeder Zeile. */
.iconknopf--fort:hover,
.iconknopf--fort:focus-visible { color: var(--fehler); border-color: var(--fehler); }

.iconknopf__hinweis {
  position: absolute;
  bottom: calc(100% + .3rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  padding: .3rem .5rem;
  border-radius: var(--radius-klein);
  background: var(--text);
  color: var(--grund);
  font-size: .78rem;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .12s linear;
}
.iconknopf:hover .iconknopf__hinweis,
.iconknopf:focus-visible .iconknopf__hinweis { opacity: 1; visibility: visible; }

/* Auf grobem Zeigegeraet kein Tooltip: Er erschiene beim Antippen gleichzeitig
   mit der Handlung, die er erklaeren soll. Dort traegt die Flaeche die Groesse. */
@media (pointer: coarse) {
  .iconknopf { width: 2.75rem; height: 2.75rem; }
  .iconknopf__hinweis { display: none; }
}

/* Die Zaehlung ueber der Liste. Sie beantwortet die Frage, die man beim
   Blaettern hat — «wie viel ist es ueberhaupt» —, und stand vorher nur klein
   in der Blaetterung am Ende. */
.zaehlung {
  margin: 0;
  font-size: .95rem;
  color: var(--text-leise);
}
.zaehlung strong { color: var(--text); font-variant-numeric: tabular-nums; }

/* ================================================================ Bausteine II

   Lorin hat sechs Entwuerfe fremder Oberflaechen als Vorlage mitgeschickt und
   dazu gesagt, das uebrige Admin sei «recht langweilig, als waeren nur
   ungestylte HTML Elemente aufeinander getuermt». Was die sechs gemeinsam
   haben, steht hier als Bausteine — einmal gebaut, damit die restlichen
   Bildschirme sie benutzen und nicht jeder seine eigene Fassung erfindet.

   Alles arbeitet mit den vorhandenen Token. Kein neuer Farbwert, keine neue
   Abhaengigkeit, kein Skript ausser dort, wo es ausdruecklich steht. */

/* ---------------------------------------------------------------- Kartenkopf

   Icon in einem weichen Quadrat, Titel, darunter ein Satz, der sagt, wozu die
   Karte da ist. Der Satz ist der Unterschied zwischen einer Ueberschrift und
   einer Auskunft: «Form Information» allein sagt nichts, «Ein neues Projekt
   anlegen, um die Arbeit des Teams zu ordnen» schon. */
/* KAPUTT GEWESEN, und Lorin hat es auf dem Bildschirm gesehen: «zu viel Platz
   zwischen Icon und Titel, das sieht nicht aus als haettest du das so geplant».
   Der Grund liegt am Elternteil — .karte__kopf ist «justify-content:
   space-between» und hatte bis dahin genau ZWEI Kinder (Titel, Handlung). Mit
   dem Symbol sind es drei, und weil der Textblock nicht wuchs, verteilte
   space-between den ganzen freien Platz zwischen Symbol und Text: Symbol links
   an der Kante, Titel rechts an der Kante, Loch dazwischen.

   Der Textblock nimmt jetzt den Platz («flex: 1»), damit space-between nichts
   mehr zu verteilen hat. Der Abstand ist so gross wie der von der Kante zum
   Symbol — also die waagrechte Polsterung der Kopfzeile, 1.25rem. Das war
   Lorins Vorgabe, und es ist auch das ruhigere Bild: Symbol und Titel stehen
   in gleichem Abstand voneinander wie das Symbol von der Karte. */
.karte__kopf--mit-icon {
  align-items: flex-start;
  gap: 1.25rem;
}
.karte__kopf--mit-icon .karte__kopf-text { flex: 1 1 auto; }
.karte__symbol {
  flex: none;
  width: 2.2rem; height: 2.2rem;
  display: grid;
  place-items: center;
  border-radius: var(--radius-klein);
  background: var(--flaeche-2);
  color: var(--text-leise);
  font-size: 1.1rem;
}
.karte__kopf-text { min-width: 0; }
.karte__kopf-text h2 { margin: 0; }
.karte__unterzeile {
  margin: .2rem 0 0;
  font-size: .88rem;
  color: var(--text-leise);
}

/* ---------------------------------------------------------------- Kartenfuss

   Zustand links, Handlungen rechts, durch eine Linie vom Inhalt getrennt. In
   allen drei Formular-Entwuerfen sitzt die Haupthandlung dort — und nicht oben
   in der Kopfzeile, wo sie im Admin bisher stand. Das ist richtig so: Man
   drueckt sie, wenn man unten angekommen ist. */
.karte__fuss {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  padding: .9rem 1.25rem;
  border-top: 1px solid var(--linie);
  background: var(--flaeche-2);
  border-radius: 0 0 var(--radius) var(--radius);
}
.karte__fuss-handlungen { display: flex; gap: .5rem; flex-wrap: wrap; margin-left: auto; }

/* Der Zustand mit einem Punkt davor, wie «Saved as a draft» im Entwurf. Der
   Punkt ist Zierde, das Wort traegt die Aussage — Farbe allein ist kein
   Unterschied. */
.karte__zustand {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-size: .88rem;
  color: var(--text-leise);
}
.karte__zustand::before {
  content: '';
  width: .5rem; height: .5rem;
  border-radius: 50%;
  background: var(--text-leise);
  flex: none;
}
/* Auch hier --akzent-dunkel: Der Punkt sass mit 2.02 auf dem Kartenfuss und war
   im Hellmodus praktisch nicht zu sehen. Das Wort daneben traegt die Aussage —
   ein Punkt, den man nicht sieht, ist aber auch als Zierde keiner. */
.karte__zustand--offen::before { background: var(--warnung); }
.karte__zustand--live::before { background: var(--akzent-dunkel); }

/* ---------------------------------------------------------------- Chips

   Schlagwoerter und Voreinstellungen. Zwei Arten, und der Unterschied ist die
   Richtung: Ein gesetzter Chip traegt ein ×, ein Vorschlag ein +. Im Entwurf
   stehen beide in derselben Reihe, und das ist gut — man sieht, was schon da ist
   und was man dazunehmen kann. */
.chips { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .6rem;
  border: 1px solid var(--linie);
  border-radius: 999px;
  background: var(--flaeche);
  font-size: .85rem;
  color: var(--text);
  text-decoration: none;
}
.chip--vorschlag { border-style: dashed; color: var(--text-leise); }
.chip--vorschlag:hover { border-style: solid; color: var(--text); background: var(--flaeche-2); }
.chip--gewaehlt {
  border-color: var(--akzent-dunkel);
  background: var(--akzent-leicht);
  color: var(--akzent-dunkel);
}

/* Der Wegnehmen-Knopf im Chip. 1.4rem sind klein — deshalb reicht die
   Klickflaeche mit negativem Rand ueber den sichtbaren Kreis hinaus, sonst
   trifft ein Finger daneben. */
.chip__fort {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.4rem; height: 1.4rem;
  margin: -.3rem -.35rem -.3rem 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--text-leise);
  cursor: pointer;
  font: inherit;
  font-size: .9rem;
  line-height: 1;
}
.chip__fort:hover { background: var(--linie); color: var(--text); }

/* ---------------------------------------------------------------- Ablagefläche

   Gestrichelt, mit Icon, Satz und Nebensatz («JPG, PNG oder PDF, nicht mehr als
   10 MB»). Der Nebensatz gehoert dazu: Was erlaubt ist, erfaehrt man sonst erst
   nach dem Fehlversuch. Die Fassung im Medien-Dialog (.medienwahl__ablage)
   bleibt, wo sie ist — diese hier ist die allgemeine. */
.ablage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
  text-align: center;
  padding: 1.6rem 1.25rem;
  border: 2px dashed var(--linie-stark);
  border-radius: var(--radius);
  background: var(--flaeche-2);
  color: var(--text-leise);
}
.ablage[hidden] { display: none; }
.ablage--aktiv { border-style: solid; border-color: var(--akzent-dunkel); background: var(--akzent-leicht); }
.ablage__symbol { font-size: 1.4rem; }
.ablage__satz { margin: 0; font-weight: 600; color: var(--text); }
.ablage__neben { margin: 0; font-size: .82rem; }

/* ---------------------------------------------------------------- Übersicht

   Die Zusammenfassung in der Seitenspalte: Icon und Beschriftung links, Wert
   rechts. Wie .kennzahl, aber mit Symbol und fuer Text statt fuer Zahlen —
   deshalb bricht der Wert um statt zu ueberlaufen. */
.uebersicht { display: flex; flex-direction: column; }
.uebersicht__zeile {
  display: flex;
  align-items: baseline;
  gap: .75rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--linie);
}
.uebersicht__zeile:first-child { padding-top: 0; }
.uebersicht__zeile:last-child { border-bottom: 0; padding-bottom: 0; }
.uebersicht__name {
  display: flex;
  align-items: center;
  gap: .4rem;
  flex: 0 0 45%;
  font-size: .88rem;
  color: var(--text-leise);
}
.uebersicht__wert { flex: 1 1 auto; text-align: right; overflow-wrap: anywhere; }

/* In der Seitenspalte stehen Beschriftung und Wert UNTEREINANDER. Bei 19rem
   Spaltenbreite bleiben einem Wert neben seiner Beschriftung rund zehn Zeichen,
   und «overflow-wrap: anywhere» machte daraus «admin@demo.loc» / «al» — ein
   mitten im Wort umgebrochener Wert ist keine Auskunft mehr. Was dort steht,
   ist ausserdem oft lang: eine Adresse, ein Pfad, ein Zeitpunkt.

   Im Hauptteil (Editor, schmale Karte) bleiben die zwei Spalten: Dort ist Platz,
   und nebeneinander laesst sich eine Liste senkrecht abfahren. */
.spalten__seite .uebersicht__zeile {
  flex-direction: column;
  align-items: stretch;
  gap: .1rem;
}
.spalten__seite .uebersicht__wert { text-align: left; }
/* Der Satz, der einen Wert in der Uebersicht begruendet. Eigene Zeile unter dem
   Wert und nicht daneben: Manche dieser Saetze sind drei Zeilen lang, und neben
   einem Wert von zwei Zeichen streiten sie mit ihm um den Platz.

   Vorher standen alle diese Saetze in EINEM Absatz unter der Liste. Weil jeder
   von ihnen in resources/lang mit einem Gedankenstrich beginnt, las sich das
   Ergebnis als «— der Rueckfallweg in PHP … — danach wird eine Sicherung …» —
   drei Halbsaetze ohne Anfang. */
.uebersicht__erklaerung {
  display: block;
  margin-top: .15rem;
  font-size: .78rem;
  line-height: 1.45;
  color: var(--text-leise);
  font-weight: 400;
}
/* ---------------------------------------------------------------- Wahlraster

   Eine Auswahl als Karten statt als Liste von Ankreuzfeldern — bei den
   Faehigkeiten eines API-Zugangs: «read» und «preview», jede mit Namen und
   einem Satz, was sie bedeutet.

   Warum das mehr ist als Aussehen: «preview» macht Entwuerfe sichtbar. Wer
   zwischen zwei Rechten waehlt, deren Folge er nicht kennt, braucht sie
   NEBENEINANDER und mit einem Satz dazu — nicht als zwei Kaestchen, deren
   Erklaerung in derselben Zeile weiterlaeuft.

   Gebaut aus echten Ankreuzfeldern: ohne Skript bedienbar, mit der Tastatur wie
   jedes Kaestchen, und die Beschriftung ist die ganze Karte. Das Kaestchen ist
   NICHT display:none — dann waere es aus dem Fokusfluss und mit der Tastatur
   unerreichbar — sondern sichtbar in der Karte, links vom Text. Dass es dasteht,
   ist wichtig: Bei einer Mehrfachwahl muss man sehen, dass man mehrere nehmen
   kann.

   Dieser Baustein stand nach der ersten Runde schon einmal hier und wurde
   wieder entfernt, weil ihn kein Bildschirm benutzte. Jetzt benutzt ihn einer. */
.wahlraster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: .6rem;
  border: 0;
  margin: 0 0 1rem;
  padding: 0;
}
.wahlraster > legend {
  padding: 0;
  margin-bottom: .4rem;
  font-size: .88rem;
  font-weight: 600;
  float: left;
  width: 100%;
}
.wahlkarte {
  display: flex;
  gap: .6rem;
  align-items: flex-start;
  padding: .8rem .9rem;
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  background: var(--flaeche);
  cursor: pointer;
}
.wahlkarte:hover { background: var(--flaeche-2); }
.wahlkarte input { flex: none; margin: .15rem 0 0; }
/* --akzent-dunkel und nicht --akzent: #50C878 auf Weiss sind 2.13, und diese
   Kante zeigt eine Auswahl an — das ist ein Bedienelement und braucht 3.0.
   --akzent-dunkel hat in beiden Modi die Rolle «Gruen, das lesbar sein muss»:
   hell 6.98, dunkel 11.02 gegen die Karte. Die Flaeche darunter bleibt
   --akzent-leicht; sie traegt nichts allein, das Kaestchen ist angekreuzt. */
.wahlkarte:has(input:checked) {
  border-color: var(--akzent-dunkel);
  background: var(--akzent-leicht);
}
.wahlkarte:has(input:focus-visible) { outline: 2px solid var(--fokus); outline-offset: 2px; }
.wahlkarte__text { min-width: 0; }
.wahlkarte__name { display: block; font-weight: 600; font-size: .93rem; }
.wahlkarte__satz { display: block; font-size: .82rem; color: var(--text-leise); margin-top: .1rem; }



/* ---------------------------------------------------------------- Hinweiskasten

   Der Kasten mit dem Info-Icon aus dem sechsten Entwurf. Fuer den Satz, den man
   VOR dem Absenden wissen will — nicht fuer eine Warnung: Die hat ihre eigene
   Meldungsform, und wer beides gleich aussehen laesst, macht aus einer Warnung
   einen Hinweis. */
.hinweiskasten {
  display: flex;
  gap: .6rem;
  padding: .8rem .9rem;
  border-radius: var(--radius-klein);
  background: var(--flaeche-2);
  border: 1px solid var(--linie);
  font-size: .85rem;
  color: var(--text-leise);
}
/* DIE ZWEI SCHALTFLÄCHEN IN DER KARTE «ZUSTAND» (Lorins Layout-Vorgabe).

   `column-reverse` ist der Kern und kein Kniff: Im MARKUP steht «als Entwurf
   speichern» zuerst, damit die Eingabetaste in einem Textfeld sie auslöst und
   nicht «Veröffentlichen» — versehentlich live geht so niemand (R.2). GESEHEN
   werden soll aber die Haupthandlung oben. Beides zusammen geht nur, indem die
   Reihenfolge im Markup und die auf dem Bildschirm auseinanderfallen.

   Die Tastaturreihenfolge folgt dem Markup und nicht dem Bild — das ist hier
   richtig: Wer tabbt, kommt zuerst zum harmloseren der zwei Knöpfe. */
/* EIN GESPERRTES FELD IST EIN UMRISS, KEIN KASTEN (Lorins Vorgabe:
   «deaktivierte Felder sollen nicht so grau sein mit Füllung, einfach eine
   Outline die weniger Kontrast hat als die normale»).

   Gerechnet: Der normale Feldrand (--linie-stark) hält 3.43 hell / 2.41 dunkel.
   Der gesperrte liegt mit 1.54 / 1.57 deutlich darunter und ist trotzdem zu
   sehen — genau die Absicht: Das Feld ist noch da, nur eben nicht für die Hand.
   SC 1.4.11 nimmt inaktive Bedienelemente ausdrücklich aus; sonst wäre «weniger
   Kontrast» gar nicht erlaubt.

   `opacity` auf der ganzen Karte wäre der einfache Weg und der falsche: Sie
   senkt auch den Kontrast der Beschriftungen unter 4.5, und lesen soll man ja,
   was übernommen wird. */
/* Solange das Bild aus dem Hero kommt, wird hier keines gewählt: Das
   Zahlenfeld mit der Media-ID und der Knopf daneben sind dann Zierde. Die
   Vorschau bleibt — sie zeigt, WAS übernommen wird. */
.metadaten--geerbt .seo__bildwahl { display: none; }

/* Die Beschriftung eines gesperrten Feldes wird mitgedämpft (Lorins Vorgabe:
   «die Titel über den Feldern die deaktiviert sind, sollen auch ausgegraut
   sein»). Sonst steht über einem stillgelegten Feld eine Überschrift in voller
   Stärke, und die Karte sieht halb bedienbar aus.

   `:has()` und keine zweite Klasse im Markup: Die Frage ist «hat dieses Feld
   eine gesperrte Eingabe?», und genau das steht hier. Die Beschriftung des
   Hakens selbst bleibt hell — er ist ja bedienbar, und er ist kein `.feld`.

   --text-leise und nicht dunkler: 5.63 hell und 6.80 dunkel auf der Karte. Die
   Beschriftung sagt, WAS dort steht; sie muss lesbar bleiben, auch wenn das
   Feld darunter gerade niemandem gehört. */
.metadaten--geerbt .feld:has(input:disabled) > .feld__label,
.metadaten--geerbt .feld:has(textarea:disabled) > .feld__label,
.metadaten--geerbt .feld:has(select:disabled) > .feld__label {
  color: var(--text-leise);
}

.metadaten--geerbt input:disabled,
.metadaten--geerbt textarea:disabled {
  background: none;
  border-color: var(--rand-gesperrt);
  color: var(--text-leise);
  cursor: not-allowed;
}

.zustand__handlungen {
  display: flex;
  flex-direction: column-reverse;
  gap: .5rem;
  margin-top: 1rem;
}

.hinweiskasten__symbol { flex: none; color: var(--akzent-dunkel); }
.hinweiskasten p { margin: 0; }
.hinweiskasten strong { color: var(--text); }

/* ---------------------------------------------------------------- Zählmarke

   Die Zahl neben einem Gruppentitel, wie «To-do 4» im ersten Entwurf.
   Gleichlaufende Ziffern, damit zwei Marken untereinander gleich breit sind. */
.zahlmarke {
  display: inline-block;
  min-width: 1.5rem;
  padding: .05rem .35rem;
  border-radius: var(--radius-klein);
  background: var(--flaeche-2);
  color: var(--text-leise);
  font-size: .78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.zahlmarke--betont { background: var(--akzent-leicht); color: var(--akzent-dunkel); }

/* ---------------------------------------------------------------- Listenkopf

   Zaehlung links, Sprachwahl rechts, in einer Zeile ueber den Filtern. Vorher
   stand die Sprachwahl als eigene Leiste ganz oben, ueber der Filterkarte, und
   war damit weiter von der Liste entfernt als die Filter — obwohl sie die Liste
   staerker aendert als jeder Filter. */
.listenkopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem 1rem;
  margin-bottom: .9rem;
}
.listenkopf .zaehlung { margin-right: auto; }

/* ---------------------------------------------------------------- Listentabelle

   Die Tabelle bleibt eine Tabelle: Es sind Spalten mit gleichartigen Werten,
   sortierbar, und ein Screenreader liest «Titel, Zeile 3 von 25». Aufklappbare
   Karten waeren hier falsch — anders als bei den Formular-Eingaengen fuehrt
   jede Zeile auf eine eigene Seite, den Editor.

   Was sich aendert, ist die Zeile selbst: Titel mit Gewicht, Adresse klein
   darunter, Handlungen als Icons am Rand. */
.tabelle--liste td { vertical-align: top; }
.tabelle__titel {
  display: inline-block;
  font-weight: 600;
  color: var(--text);
}
a.tabelle__titel:hover { color: var(--akzent-dunkel); }
.tabelle__neben {
  display: block;
  margin-top: .1rem;
  font-size: .8rem;
  color: var(--text-leise);
  overflow-wrap: anywhere;
}

/* Der Sortierlink traegt keine Unterstreichung, sonst sieht jede Kopfzeile aus
   wie ein Satz voller Links. Beim Hover kommt sie, damit man merkt, dass es
   einer ist. */
.tabelle__sortierung { color: inherit; text-decoration: none; }
.tabelle__sortierung:hover { color: var(--akzent-dunkel); text-decoration: underline; }

/* Icon-Knoepfe in einer Tabellenzelle: rechts, in einer Reihe, und die Zelle
   waechst nicht mit. */
.iconreihe { display: flex; gap: .15rem; justify-content: flex-end; }
.tabelle__aktionen { white-space: nowrap; }

/* Ein zweiter Rumpf direkt unter dem ersten braucht die Trennlinie, sonst
   kleben Filter und Inhalt aneinander. */
.karte__rumpf--anschluss { border-top: 1px solid var(--linie); }
/* Zahlenspalten in einer Listentabelle: rechtsbuendig und mit gleichlaufenden
   Ziffern. Erst dann lassen sich zwei Zeilen untereinander vergleichen — und
   genau dafuer stehen Zahlen ueberhaupt in Spalten. */
.tabelle__zahl { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabelle--liste th.tabelle__zahl { text-align: right; }

/* Eine Marke am rechten Rand einer Werklisten-Zeile, vor den Icon-Knoepfen.
   `flex: none`, damit sie nicht schrumpft: Ein umgebrochener Sprachstand waere
   in einer Liste, die man senkrecht abfaehrt, unlesbar. */
.werkliste__marke { flex: none; }
/* Eine Werkliste in einer schmalen Seitenspalte: weniger Innenabstand, kein
   Symbolabstand von .75rem. Bei 19rem Spaltenbreite frisst die normale Fassung
   den Platz, den der Titel braucht. */
.werkliste--eng .werkliste__zeile { padding: .5rem 1.25rem; gap: .5rem; }
.werkliste--eng .werkliste__symbol { font-size: .95rem; }
.werkliste--eng .werkliste__titel { font-weight: 500; font-size: .9rem; }

/* Die Handlungen einer Tabellenzeile in einer Reihe. Vorher waren es bis zu vier
   untereinander gestapelte Formulare, jedes mit eigener Knopfbreite — eine
   Treppe am rechten Rand. Rechtsbuendig, weil die Spalte rechts steht und ein
   linksbuendiger Knopf sonst mitten in der Zelle klebt. */
.zeilenaktionen {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem;
  align-items: center;
  justify-content: flex-end;
}
.zeilenaktionen form { display: contents; }

/* Chips in einer Tabellenzelle duerfen umbrechen, sollen aber nicht die Zeile
   auseinanderziehen. */
.tabelle .chips { max-width: 14rem; }
/* Die Filterleiste steht weiter unten in einem Stück. Hier stand bis zum
   Editor-Umbau die Sonderbehandlung ihres <fieldset> — die Beschriftung sitzt
   jetzt an den Feldern selbst («Zeitraum von», «bis»), und die <legend> ist
   `nur-sr`. */


/* ---------------------------------------------------------------- Werkliste

   «Zuletzt bearbeitet» und «Geplant» auf der Uebersicht: Icon des Inhaltstyps,
   Titel, eine Zeile Umstaende, Zustandsmarke am Rand. Dieselbe Aufteilung wie
   die Zusammenfassungszeilen in den Entwuerfen — und der Grund ist derselbe:
   Man faehrt die Liste senkrecht ab und will an einer festen Stelle sehen, was
   noch Entwurf ist.

   Als <ul> und nicht als Tabelle: Es sind keine Spalten mit gleichartigen
   Werten, es ist eine Liste von Dingen. Ein Screenreader sagt dann «Liste, 6
   Eintraege» statt «Tabelle mit 3 Spalten». */
.werkliste { list-style: none; margin: 0; padding: 0; }
.werkliste__zeile {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .7rem 1.25rem;
  border-top: 1px solid var(--linie);
}
.werkliste__zeile:first-child { border-top: 0; }
.werkliste__zeile:hover { background: var(--flaeche-2); }
.werkliste__symbol { flex: none; color: var(--text-leise); font-size: 1.05rem; }
.werkliste__text { flex: 1 1 auto; min-width: 0; }
.werkliste__titel { display: block; font-weight: 600; color: var(--text); }
a.werkliste__titel:hover { color: var(--akzent-dunkel); }
.werkliste__neben {
  display: block;
  margin-top: .1rem;
  font-size: .8rem;
  color: var(--text-leise);
}

/* ---------------------------------------------------------------- Warnkarte

   `.karte--warnung` gibt es schon (siehe Zwei-Faktor, O.5) und sie ist eine
   GEFUELLTE Karte. Hier steht deshalb nur das Symbol dazu — eine zweite
   Definition der Karte selbst waere ein Widerspruch, den der spaetere Block
   ohnehin gewinnt.

   Das Quadrat traegt --flaeche und nicht --warnung-flaeche: Auf der gefuellten
   Karte waere es sonst dieselbe Farbe wie der Grund und unsichtbar. Gemessen
   hell 1.10 und dunkel 1.24 gegen die Kartenflaeche, das Symbol darauf 6.33
   beziehungsweise 8.12. */
.karte--warnung .karte__symbol { color: var(--warnung); background: var(--flaeche); }
/* ---------------------------------------------------------------- Ordner-Chips

   Die Ordner der Mediathek als Chip-Reihe. Etwas mehr Luft nach unten als eine
   Chip-Reihe im Formular: Darunter folgt die Zaehlung, und die gehoert nicht an
   den letzten Ordner geklebt. */
.chips--ordner { margin-bottom: 1rem; }
.chips--ordner .zahlmarke { margin-left: .15rem; }

/* Die gestrichelte Flaeche ist ein <label> — der Zeiger soll das sagen. */
label.ablage { cursor: pointer; }
label.ablage:hover { border-color: var(--akzent-dunkel); }

/* DER FOKUS LIEGT AM UNSICHTBAREN FELD. Das Dateifeld steht in .nur-sr, damit es
   mit der Tastatur erreichbar bleibt (display:none nimmt es aus dem Fokusfluss).
   Genau deshalb war der Fokus dort aber nicht zu sehen: Man tabbte in ein Feld,
   von dem nichts auf dem Schirm stand — und der naechste Tastendruck oeffnete
   einen Dateidialog, den niemand erwartet hat.
   Der Ring sitzt jetzt an der Flaeche, die die Beschriftung des Feldes ist.
   `:has(+ input:focus-visible)` und nicht `:focus-within`: Die Flaeche ist ein
   label, das Feld steht daneben und nicht darin. */
label.ablage:has(+ input:focus-visible) {
  outline: 2px solid var(--fokus);
  outline-offset: 2px;
  border-color: var(--akzent-dunkel);
}

/* Was gewaehlt wurde. Bewusst OHNE display-Regel: Die Zeile traegt `hidden`,
   solange nichts gewaehlt ist, und jede eigene display-Angabe wuerde die
   Browserregel `[hidden] { display: none }` ueberstimmen — dieselbe Falle, die
   im Medien-Dialog die Reiter aussetzen liess. */
.ablage__gewaehlt {
  margin: .6rem 0 0;
  font-size: .85rem;
  color: var(--text);
  overflow-wrap: anywhere;
}





/* Ein Formular mit fuenf kurzen Feldern ueber die ganze Bildschirmbreite ist
   nicht lesbar: Beschriftung links, Feldende einen Meter weiter rechts. Stand
   vorher als style="max-width:34rem" in den Vorlagen und war damit wirkungslos —
   die CSP aus O.8 kennt kein unsafe-inline, der Browser hat das Attribut
   verworfen und in der Konsole gemeldet. */
.karte--schmal { max-width: 34rem; }

/* Eine Karte ueber der Liste, in der nur ein Satz und ein Knopf stehen. */
.karte__kopf--leise h2 { font-size: 1rem; }

.leise { color: var(--text-leise); }
.klein { font-size: .85rem; }

.raster { display: grid; gap: 1.25rem; }
@media (min-width: 60rem) {
  .raster--zwei { grid-template-columns: 1fr 1fr; }
}

/* ---------------------------------------------------------------- Meldungen */

/* Eine Meldung ist das Ergebnis einer Handlung und kein Zustand einer Sache.
   Damit sie sich von den Zustandsmarken unterscheidet, hat sie eine eigene Form:
   ein breiter Balken links und ein Zeichen vor dem Text. Das Zeichen ist der
   nicht-farbige Traeger — wer Rot und Gruen nicht unterscheidet, liest ✓ gegen ✕
   trotzdem. */
.meldung {
  position: relative;
  border-radius: 0 var(--radius-klein) var(--radius-klein) 0;
  padding: .8rem 1rem .8rem 2.3rem;
  margin-bottom: 1rem;
  border: 1px solid transparent;
  border-left-width: 5px;
  font-size: .93rem;
}

/* Das Zeichen liegt absolut und nicht als Flex-Kind: Eine Meldung enthaelt an
   einigen Stellen mehrere Blockelemente (Fettzeile plus Absatz), und die waeren
   in einem Flexbereich nebeneinander gelandet. */
.meldung::before {
  position: absolute;
  left: .7rem;
  top: .8rem;
  font-weight: 700;
  line-height: 1.3;
}

/* ---------------------------------------------------------------- Meldungen

   Lorins Vorgabe: «absolut oben in der Mitte des Bildschirms, so dass er nach
   einigen Sekunden automatisch wieder verschwindet».

   Der Behaelter laesst Klicks durch (`pointer-events: none`) und nur die
   Meldungen selbst fangen sie. Sonst laege ein unsichtbares Band ueber der
   Kopfzeile, und der Knopf «Neu» waere dort nicht mehr anklickbar, wo eine
   Meldung gerade nicht steht.

   Der z-index liegt ueber allem im Stylesheet (100 an .sprung). Der Medien-
   Dialog ist davon unberuehrt: Er ist ein echtes <dialog> mit showModal() und
   liegt damit in der Top-Layer des Browsers, ueber jedem z-index. Das ist
   richtig so — waehrend ein Dialog offen ist, entsteht keine Meldung. */
.meldungen {
  position: fixed;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  /* 100% und nicht 100vw: Bei «position: fixed» ist 100% die Breite des
     Ansichtsfensters OHNE Rollbalken, 100vw MIT. Gemessen 532 gegen 519 — die
     Meldung waere 13px breiter als der sichtbare Bereich gewesen und haette die
     Seite waagrecht rollbar gemacht. */
  width: min(34rem, calc(100% - 2rem));
  display: flex;
  flex-direction: column;
  gap: .5rem;
  pointer-events: none;
}

.meldung--schwebend {
  pointer-events: auto;
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  box-shadow: var(--schatten);
  /* Der linke Streifen der Meldung bleibt, aber die Ecken sind jetzt auf allen
     Seiten rund: Im Fluss sass die Meldung an der linken Kante des Inhalts und
     durfte dort kantig sein — schwebend hat sie keine Kante, an der sie sitzt. */
  border-radius: var(--radius-klein);
  animation: meldung-herein .18s ease-out;
}
.meldung__text { flex: 1 1 auto; min-width: 0; }

/* Der Schliessen-Knopf. Negative Raender, damit die Klickflaeche ueber den
   sichtbaren Kreis hinausreicht: 1.6rem sind auf einem Telefon knapp. */
.meldung__weg {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.6rem; height: 1.6rem;
  margin: -.2rem -.35rem -.2rem 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  opacity: .65;
  cursor: pointer;
  font: inherit;
  line-height: 1;
}
.meldung__weg:hover, .meldung__weg:focus-visible { opacity: 1; }

/* Beim Gehen: ausblenden und ein Stueck nach oben. Entfernt wird das Element
   danach im Skript — eine Meldung, die nur durchsichtig ist, faengt weiter
   Klicks. */
.meldung--geht {
  opacity: 0;
  transform: translateY(-.4rem);
  transition: opacity .18s ease-in, transform .18s ease-in;
}

@keyframes meldung-herein {
  from { opacity: 0; transform: translateY(-.5rem); }
  to   { opacity: 1; transform: none; }
}

/* Wer Bewegung reduziert haben will, bekommt sie nicht. Die Meldung erscheint
   und verschwindet dann eben ohne Blende — die Auskunft steht so oder so da. */
@media (prefers-reduced-motion: reduce) {
  .meldung--schwebend { animation: none; }
  .meldung--geht { transition: none; }
}

/* Auf dem Telefon oben ueber die ganze Breite: 34rem gibt es dort nicht, und
   eine zentrierte Karte mit 1rem Luft an jeder Seite ist die ganze Breite. */
@media (max-width: 36rem) {
  .meldungen { top: .5rem; }
}

/* Ersetzt zwei style="margin:…"-Attribute in backup/index.twig und
   tokens/index.twig: Die CSP aus O.8 kennt kein unsafe-inline, der Abstand kam
   dort nie an und die Konsole meldete eine Verletzung. */
.meldung > p { margin: .35rem 0 .6rem; }
.meldung > p:last-child { margin-bottom: 0; }
.meldung--erfolg { background: var(--erfolg-flaeche); border-color: var(--erfolg); color: var(--erfolg); }
.meldung--erfolg::before { content: "✓"; }
.meldung--fehler { background: var(--fehler-flaeche); border-color: var(--fehler); color: var(--fehler); }
.meldung--fehler::before { content: "✕"; }
.meldung--warnung { background: var(--warnung-flaeche); border-color: var(--warnung); color: var(--warnung); }
.meldung--warnung::before { content: "!"; }
/* Ein Hinweis ist neutral. Vorher trug er die Akzentfarbe und sah damit aus wie
   eine Erfolgsmeldung — «Gespeichert» und «Uebrigens» sind aber nicht dasselbe. */
.meldung--hinweis, .meldung--info {
  background: var(--flaeche-2);
  border-color: var(--linie-stark);
  color: var(--text);
}
.meldung--hinweis::before, .meldung--info::before { content: "i"; font-style: italic; }

.warnliste { list-style: none; margin: 0; padding: 0; display: grid; gap: .75rem; }
.warnliste li {
  border-left: 3px solid var(--warnung);
  background: var(--warnung-flaeche);
  padding: .75rem 1rem;
  border-radius: 0 var(--radius-klein) var(--radius-klein) 0;
}
.warnliste li.hinweis { border-left-color: var(--akzent); background: var(--akzent-leicht); }
.warnliste strong { display: block; margin-bottom: .15rem; }
.warnliste p { margin: 0; font-size: .88rem; }

/* ---------------------------------------------------------------- Formulare */

.feld { margin-bottom: 1.15rem; }
.feld:last-child { margin-bottom: 0; }

.feld > label, .feld__label {
  display: block;
  font-weight: 500;
  font-size: .9rem;
  margin-bottom: .3rem;
}

.feld__hilfe {
  display: block;
  font-size: .82rem;
  color: var(--text-leise);
  margin-top: .3rem;
}

.feld__fehler {
  display: block;
  font-size: .85rem;
  color: var(--fehler);
  margin-top: .3rem;
  font-weight: 500;
}

/* EIN BEDIENBARES FELD HAT SEINE EIGENEN FARBEN (Lorins Vorgabe, dunkler
   Modus): eigene Fläche, eigener Rand, weisse Schrift, leiser Platzhalter. Im
   hellen Modus zeigen die Token auf das, was vorher galt — die Vorgabe nennt
   dunkle Werte, und ein Feld in #202023 auf weissem Grund wäre ein schwarzes
   Loch.

   Ein GESPERRTES Feld bleibt, wie es war (Lorin: «if they are deactivated, they
   stay as they are now») — deshalb `:not(:disabled)`. So sieht man den
   Unterschied ohne zweite Regel: Das offene Feld hat eine Fläche, das gesperrte
   nur seinen Umriss. */
input[type="text"], input[type="email"], input[type="password"], input[type="search"],
input[type="number"], input[type="url"], input[type="date"], input[type="time"],
input[type="datetime-local"], input[type="tel"], select, textarea {
  width: 100%;
  font: inherit;
  font-size: .95rem;
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  padding: .55rem .7rem;
}

input[type="text"]:not(:disabled), input[type="email"]:not(:disabled),
input[type="password"]:not(:disabled), input[type="search"]:not(:disabled),
input[type="number"]:not(:disabled), input[type="url"]:not(:disabled),
input[type="date"]:not(:disabled), input[type="time"]:not(:disabled),
input[type="datetime-local"]:not(:disabled), input[type="tel"]:not(:disabled),
select:not(:disabled), textarea:not(:disabled) {
  background: var(--feld-flaeche);
  border-color: var(--feld-rand);
  color: var(--feld-text);
}

/* Der Platzhalter ist Text und kein Wert: Er verschwindet beim ersten Zeichen.
   Die Farbe steht in einem eigenen Token, weil sie die einzige ist, die unter
   4.5 liegt — siehe die Tabelle oben. */
input::placeholder, textarea::placeholder { color: var(--feld-platzhalter); opacity: 1; }
textarea { min-height: 7rem; resize: vertical; }
input:disabled, select:disabled, textarea:disabled {
  background: var(--flaeche-2);
  color: var(--text-leise);
}
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: var(--fehler);
}

.wahl { display: flex; align-items: flex-start; gap: .5rem; margin-bottom: .4rem; font-size: .92rem; }
.wahl input { margin-top: .28rem; flex: none; }

/* Der Haken ist GRÜN (Lorins Vorlage zur Metadaten-Karte). `accent-color` färbt
   die native Ankreuzbox — das Häkchen bleibt weiss, die Ecken bleiben die des
   Systems, und Tastatur, Vorlesesoftware und Kontrastdesigns bleiben, wie sie
   sind. Ein nachgebautes Kästchen aus <span> und CSS wäre dieselbe Optik mit
   drei neuen Fehlerquellen.

   Der Zustand hängt nicht an der Farbe: Ein Haken ist da oder nicht. */
input[type="checkbox"], input[type="radio"] { accent-color: var(--knopf-haupt); }

fieldset { border: 0; margin: 0 0 1.25rem; padding: 0; }
legend { font-weight: 600; font-size: .95rem; padding: 0 0 .4rem; }

/* ---------------------------------------------------------------- Feldtypen
   Die Partials unter resources/fields/ verwenden diese Klassen. Ein neuer
   Feldtyp soll ohne neues CSS auskommen — deshalb sind die Bausteine hier
   allgemein gehalten und nicht pro Typ. */

/* Das Formularraster: Felder mit width half/third stehen nebeneinander. */
.felder {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0 1rem;
}
.feld--full  { grid-column: span 6; }
.feld--half  { grid-column: span 6; }
.feld--third { grid-column: span 6; }

@media (min-width: 44rem) {
  .feld--half  { grid-column: span 3; }
  .feld--third { grid-column: span 2; }
}

/* Mehrere Steuerungen in einer Zeile: Präfix/Suffix, Farbwähler, Von/Bis. */
.feld__gruppe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
}
.feld__gruppe > input[type="text"],
.feld__gruppe > input[type="number"],
.feld__gruppe > input[type="url"],
/* date/time/datetime-local fehlten hier, und das war der Grund, warum «Von» und
   «Bis» im Formular-Eingang UNTEREINANDER standen statt nebeneinander: Ohne
   diese Zeile behalten sie die allgemeine Regel «width: 100%», jedes Feld
   belegt damit die ganze Breite der Gruppe, und flex-wrap schickt das zweite in
   die naechste Zeile. Von aussen sah es wie ein Fehler im Umbruch aus. */
.feld__gruppe > input[type="date"],
.feld__gruppe > input[type="time"],
.feld__gruppe > input[type="datetime-local"] { flex: 1 1 8rem; width: auto; }
.feld__gruppe > div { flex: 1 1 10rem; }

/* Ein beschriftetes Teilfeld innerhalb einer Gruppe: «Von» und «Bis» sind zwei
   gleich aussehende Datumsfelder, und ohne sichtbare Beschriftung raet man,
   welches welches ist. Fuer Screenreader war es beschriftet, fuer Augen nicht —
   das ist die Haelfte, die zaehlt, wenn zwei leere «dd.mm.yyyy» nebeneinander
   stehen. */
.feld__teil {
  display: flex;
  flex-direction: column;
  gap: .2rem;
  flex: 1 1 8rem;
  min-width: 0;
}
.feld__teil > label {
  font-size: .8rem;
  color: var(--text-leise);
}
.feld__teil > input { width: 100%; }

.feld__gruppe--vertical { flex-direction: column; align-items: flex-start; gap: .1rem; }
.feld__gruppe--horizontal { flex-direction: row; gap: .25rem 1.25rem; }

.feld__anhang {
  flex: none;
  font-size: .9rem;
  color: var(--text-leise);
  background: var(--flaeche-2);
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  padding: .5rem .6rem;
  white-space: nowrap;
}

/* Ein fieldset im Feld sieht aus wie ein normales Feld, nicht wie ein Kasten. */
.feld fieldset { border: 0; margin: 0; padding: 0; }
.feld legend {
  display: block;
  font-weight: 500;
  font-size: .9rem;
  margin-bottom: .3rem;
  padding: 0;
}

.feld input[type="color"] {
  flex: none;
  width: 2.6rem;
  height: 2.4rem;
  padding: .2rem;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  background: var(--flaeche);
  cursor: pointer;
}

.feld input[type="date"],
.feld input[type="time"],
.feld input[type="datetime-local"] {
  width: 100%;
  font: inherit;
  font-size: .95rem;
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  padding: .5rem .6rem;
}

.feld__code,
.feld__markdown {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-size: .88rem;
  line-height: 1.5;
  tab-size: 2;
}
.feld__code { min-height: 12rem; white-space: pre; overflow-wrap: normal; overflow-x: auto; }

/* Das textarea bleibt für den Fall ohne JavaScript — dann tippt man HTML, und
   es soll lesbar sein. Mit Skript liegt der Editor davor (siehe .richtext). */
.feld__richtext { min-height: 11rem; line-height: 1.6; }

/* DER RICHTEXT-EDITOR (G.5). Werkzeugleiste über einer bearbeitbaren Fläche —
   beides zusammen sieht aus wie ein Feld und ist auch eines: Der Rand liegt an
   der Hülle, nicht an den zwei Teilen.

   Die Fläche trägt denselben Rand wie ein textarea, damit sie im Formular nicht
   aus der Reihe fällt; der Fokusring kommt von :focus-visible wie überall. */
.richtext {
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  background: var(--flaeche);
  overflow: hidden;
}

.richtext__leiste {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem;
  padding: .35rem;
  border-bottom: 1px solid var(--linie);
  background: var(--flaeche-2);
}

.richtext__knopf {
  font: inherit;
  font-size: .85rem;
  font-weight: 600;
  min-width: 2rem;
  height: 2rem;
  padding: 0 .45rem;
  border: 0;
  border-radius: var(--radius-klein);
  background: none;
  color: var(--text);
  cursor: pointer;
}
.richtext__knopf:hover { background: var(--knopf-neben); }

/* Der eingeschaltete Zustand hängt nicht an der Farbe allein: Der Knopf bekommt
   eine Fläche UND aria-pressed. Wer die zwei Grautöne nicht unterscheidet, hört
   «gedrückt». */
.richtext__knopf--an { background: var(--knopf-neben-hover); }

.richtext__flaeche {
  min-height: 9rem;
  padding: .6rem .7rem;
  line-height: 1.6;
  overflow-wrap: break-word;
}
.richtext__flaeche:focus { outline: none; }
.richtext:focus-within { border-color: var(--fokus); }

/* Die Auszeichnung im Editor sieht aus wie das, was sie bedeutet — aber nicht
   wie die Website: Der Editor ist kein Vorschaufenster. Überschriften sind
   deshalb nur abgestuft, nicht gestaltet. */
.richtext__flaeche h2 { font-size: 1.25rem; margin: .8rem 0 .4rem; }
.richtext__flaeche h3 { font-size: 1.1rem; margin: .7rem 0 .35rem; }
.richtext__flaeche h4 { font-size: 1rem; margin: .6rem 0 .3rem; }
.richtext__flaeche p { margin: 0 0 .6rem; }
.richtext__flaeche > :last-child { margin-bottom: 0; }
.richtext__flaeche a { color: var(--akzent-dunkel); }
.richtext__flaeche blockquote {
  margin: .6rem 0;
  padding-left: .8rem;
  border-left: 3px solid var(--linie-stark);
}

/* Der Kippschalter steht weiter unten bei den Schaltflächen — dieselbe Regel
   für alle drei Stellen, an denen er vorkommt: das boolean-Feld mit
   `style: switch`, der Haken in den Metadaten und «In einem neuen Fenster
   öffnen» am Verweis. */

/* ---------------------------------------------------------------- Schaltflächen */

/* Der Nebenknopf ist GEFUELLT und randlos — Lorins Entscheidung: «alle
   secondary buttons ausgefuellt ohne Border, anstatt nur eine helle Border.»

   Der Rand bleibt als `transparent` stehen und wird nicht entfernt: Er zaehlt
   zur Kastenbreite. Ohne ihn waeren alle Nebenknoepfe 2 px kleiner als die
   Hauptknoepfe daneben, und in einer .knopfreihe steht das schief.

   Was der Rand vorher leistete, leistet nun die Flaeche: Sie ist das einzige
   Zeichen dafuer, dass dort ein Bedienelement steht. --knopf-neben ist deshalb
   kraeftiger als jede andere Hinterlegung im Stylesheet, und
   GestaltungTest::testDerNebenknopfIstAnDerFlaecheZuErkennen prueft sie gegen
   ALLE drei Untergruende, auf denen ein Knopf vorkommt.

   Die 3.0 aus SC 1.4.11 erreicht eine so leise Flaeche nicht — dafuer muesste
   sie #959595 (hell) beziehungsweise #646464 (dunkel) sein, also ein mittleres
   Grau, das schwerer wirkt als der gruene Hauptknopf. Die Abweichung steht in
   der Tabelle oben und in der README; unter `prefers-contrast: more` kommt der
   Rand zurueck. */
.knopf {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font: inherit;
  font-size: .92rem;
  font-weight: 500;
  padding: .55rem 1rem;
  border-radius: var(--radius-klein);
  border: 1px solid transparent;
  background: var(--knopf-neben);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
.knopf:hover { background: var(--knopf-neben-hover); color: var(--text); }
/* Ein Knopf ist keine Textstelle: Der Unterstrich der Links gilt hier nicht. */
a.knopf { text-decoration: none; }

/* Der Hauptknopf ist GRUEN, mit dunkler Schrift darauf.
   Lorins Entscheidung, nachdem sein Entwurf einen gruenen «Suche»-Knopf zeigte:
   «Alle Hauptknoepfe gruen.» Eine frueherere Fassung hielt sie neutral dunkel,
   weil #50C878 als SCHRIFTfarbe auf Weiss nur 2.13 hat — das gilt weiter, und
   deshalb steht das Gruen als FLAECHE mit dunkler Schrift darauf: 7.46 hell,
   8.87 dunkel. Der Tokenname --knopf-haupt bleibt, sein Wert ist jetzt die
   Marke; GestaltungTest prueft das Paar unverändert.

   R.2 verlangt trotzdem, dass man den Unterschied zwischen «Speichern» und
   «Veroeffentlichen» SIEHT — und mit «alle gruen» waeren beide gleich. Der
   Unterschied sitzt deshalb weiter im RANG, nur innerhalb derselben Farbe:

     .knopf--haupt   gefuellt gruen   die eine Haupthandlung des Bildschirms
     .knopf--zweit   gruen umrandet   die zweite, gleichrangig gemeinte
     .knopf          neutral gefuellt alles Weitere
     .knopf--text    ohne Flaeche     Abbrechen, Zurueck

   .knopf--zweit bleibt umrandet, obwohl der Nebenknopf jetzt gefuellt ist: Sein
   Rang haengt an der FARBE und nicht an der Fuellung — gruen liest sich vor
   grau, in beide Richtungen. Und eine gruene Fuellung, die dort passen wuerde,
   gibt es nicht: --akzent-leicht liegt mit 1.01 auf dem hellen Seitengrund und
   waere ausserhalb einer Karte unsichtbar.

   Der Rand des Nebenknopfs nimmt --akzent-dunkel und NICHT --akzent: #50C878
   als Rand auf Weiss sind 2.13, ein Bedienelement-Rand braucht 3.0.
   --akzent-dunkel liefert 6.98 hell und 11.02 dunkel. */
.knopf--haupt {
  background: var(--knopf-haupt);
  border-color: var(--knopf-haupt);
  color: var(--knopf-haupt-schrift);
  font-weight: 600;
}
.knopf--haupt:hover {
  background: var(--knopf-haupt-hover);
  border-color: var(--knopf-haupt-hover);
  color: var(--knopf-haupt-schrift);
}

.knopf--zweit {
  background: none;
  border-color: var(--akzent-dunkel);
  color: var(--akzent-dunkel);
  font-weight: 600;
}
.knopf--zweit:hover {
  background: var(--akzent-leicht);
  border-color: var(--akzent-dunkel);
  color: var(--akzent-dunkel);
}

/* Unwiderrufliches sieht anders aus: roter Rand, und zwar immer und doppelt
   stark. Der innere Schatten verdickt den Rand, ohne die Hoehe zu aendern —
   mit border-width: 2px sprangen die Knoepfe in der Reihe auseinander. */
.knopf--gefahr {
  color: var(--fehler);
  border-color: var(--fehler);
  box-shadow: inset 0 0 0 1px var(--fehler);
}
.knopf--gefahr:hover { background: var(--fehler-flaeche); color: var(--fehler); }

/* Der dritte Rang: eine Handlung ohne Gewicht. Sieht aus wie ein Link, weil
   sie einer ist — «Zur Liste» ist kein Knopf, sondern ein Weg zurueck. */
.knopf--text {
  border-color: transparent;
  background: none;
  padding-left: .25rem;
  padding-right: .25rem;
  text-decoration: underline;
  text-underline-offset: 3px;
}
a.knopf--text { text-decoration: underline; }
.knopf--text:hover { background: none; text-decoration-thickness: 2px; }

.knopf--schmal { padding: .35rem .7rem; font-size: .85rem; }
.knopf--breit { width: 100%; justify-content: center; }

.knopfreihe { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }

/* -------- Zustand, der kein Knopf ist

   Vorher trugen «die Sprache, in der die Liste steht» und «der Bereich, den ich
   gerade ansehe» die Klasse des Hauptknopfs. Wer gelernt hat, dass die gefuellte
   Flaeche etwas tut, liest hier eine Auskunft als Schaltflaeche. Der aktive
   Punkt ist deshalb ab jetzt kein Knopf mehr, sondern eine Markierung — und die
   darf die Marke tragen. Er behaelt aria-current; das Wort steht ohnehin drin. */
.zustandsmarke {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font: inherit;
  font-size: .85rem;
  font-weight: 600;
  padding: .35rem .7rem;
  border-radius: var(--radius-klein);
  border: 1px solid var(--akzent);
  background: var(--akzent-leicht);
  color: var(--akzent-dunkel);
  text-decoration: none;
  white-space: nowrap;
}

/* Der gefuellte Punkt davor sagt den Zustand ohne Farbe mit: gefuellt heisst
   «das ist der Stand, den Sie sehen». */
.zustandsmarke::before {
  content: "";
  flex: none;
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--akzent-dunkel);
}

/* ---------------------------------------------------------------- Tabellen */

.tabelle { width: 100%; border-collapse: collapse; font-size: .93rem; }
.tabelle th, .tabelle td {
  text-align: left;
  padding: .7rem 1.25rem;
  border-bottom: 1px solid var(--linie);
  vertical-align: middle;
}
.tabelle th {
  font-size: .78rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-leise);
  font-weight: 600;
}
.tabelle tbody tr:last-child td { border-bottom: 0; }
.tabelle tbody tr:hover { background: var(--flaeche-2); }
.tabelle__aktionen { text-align: right; white-space: nowrap; }

.tabelle-huelle { overflow-x: auto; }

.marke {
  display: inline-block;
  font-size: .74rem;
  font-weight: 600;
  padding: .12rem .5rem;
  border-radius: 999px;
  background: var(--flaeche-2);
  color: var(--text-leise);
  border: 1px solid var(--linie);
}
/* Die Gegenregel zu display: inline-block oben. Sie fehlte, und das Skript,
   das beim Aufklappen die Marke «neu» versteckt (admin.js), haette sie damit
   NICHT versteckt — die Marke waere stehen geblieben, obwohl der Eingang als
   gelesen gemeldet ist. */
.marke[hidden] { display: none; }
.marke--aktiv { background: var(--erfolg-flaeche); color: var(--erfolg); border-color: transparent; }
.marke--eingeladen { background: var(--warnung-flaeche); color: var(--warnung); border-color: transparent; }
.marke--gesperrt { background: var(--fehler-flaeche); color: var(--fehler); border-color: transparent; }

/* «Diese Seite ist live» — die eine Aussage, fuer die Lorin die Marke wollte.
   Gefuellt mit #50C878 und dunkler Schrift darauf (7.93); weisse Schrift waeren
   2.13 und damit unlesbar. Das Wort «Veroeffentlicht» steht daneben, die Farbe
   traegt nichts allein. */
.marke--live {
  background: var(--akzent);
  color: var(--akzent-schrift);
  border-color: transparent;
}

.leer {
  padding: 2.5rem 1.25rem;
  text-align: center;
  color: var(--text-leise);
}

/* ---------------------------------------------------------------- Anmeldung */

.anmeldung {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.anmeldung__karte {
  width: 100%;
  max-width: 25rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  /* Die eine Stelle, an der die Marke schmueckt: eine gruene Kante oben auf der
     Karte. Sie traegt keine Aussage — die Beschriftungen tun das —, also darf sie
     #50C878 direkt nehmen, ohne dass ein Kontrast daran haengt. */
  border-top: 4px solid var(--akzent);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  padding: 2rem;
}
.anmeldung__marke {
  text-align: center;
  margin-bottom: 1.5rem;
}
.anmeldung__marke small {
  display: block;
  color: var(--akzent-dunkel);
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.anmeldung__fuss {
  margin-top: 1.25rem;
  text-align: center;
  font-size: .88rem;
}

/* ---------------------------------------------------------------- Installer */

.pruefliste { list-style: none; margin: 0 0 1.5rem; padding: 0; }
.pruefliste li {
  display: flex;
  gap: .75rem;
  align-items: baseline;
  padding: .55rem 0;
  border-bottom: 1px solid var(--linie);
  font-size: .93rem;
}
.pruefliste li:last-child { border-bottom: 0; }
.pruefliste__zeichen { flex: none; width: 1.4rem; font-weight: 700; }
.pruefliste__zeichen--ja { color: var(--erfolg); }
.pruefliste__zeichen--nein { color: var(--fehler); }
.pruefliste__zeichen--egal { color: var(--warnung); }
.pruefliste__label { flex: 1; }
.pruefliste__wert { color: var(--text-leise); font-size: .85rem; }
.pruefliste__hinweis {
  flex-basis: 100%;
  color: var(--fehler);
  font-size: .85rem;
  padding-left: 2.15rem;
}

.installer { max-width: 44rem; margin: 0 auto; padding: 2.5rem 1.5rem; }

/* ---------------------------------------------------------------- Sitzungen */

.sitzung {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
  padding: .75rem 0;
  border-bottom: 1px solid var(--linie);
  font-size: .9rem;
}
.sitzung:last-child { border-bottom: 0; }
.sitzung__geraet { word-break: break-word; }

/* Der vollstaendige User-Agent. Er bleibt erreichbar, aber er ist nicht die
   Auskunft, an der jemand entscheidet, welche Sitzung er beendet — vier Zeilen
   à 120 Zeichen, die alle gleich anfangen, sind keine Unterscheidung. Deshalb
   klein, fest und aufklappbar; oben steht der lesbare Satz. */
.sitzung__voll { margin-top: .2rem; }
.sitzung__voll summary { cursor: pointer; font-size: .78rem; color: var(--text-leise); }
.sitzung__voll code {
  display: block;
  margin-top: .2rem;
  font-family: var(--schrift-fest);
  font-size: .75rem;
  color: var(--text-leise);
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------- Rechte-Raster */

.rechte { display: grid; gap: 1rem; }
.rechte__bereich {
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  padding: .9rem 1rem;
  background: var(--flaeche-2);
}
.rechte__bereich h3 { margin-bottom: .5rem; font-size: .93rem; }
.rechte__aktionen { display: flex; flex-wrap: wrap; gap: .35rem 1.25rem; }

/* ---------------------------------------------------------------- Mediathek */

.medienraster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: .9rem;
}

.kachel {
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  background: var(--flaeche);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  text-align: left;
  font: inherit;
  padding: 0;
  color: inherit;
  text-decoration: none;
}
.kachel { border-color: var(--linie-stark); text-decoration: none; }
.kachel:hover { border-color: var(--text-leise); }

/* Ausgewaehlt: die Marke am Rahmen — und ein Haken, damit die Auswahl nicht nur
   an der Farbe haengt. */
.kachel[aria-selected="true"] {
  border-color: var(--akzent-dunkel);
  box-shadow: 0 0 0 2px var(--akzent);
}
.kachel[aria-selected="true"] .kachel__fuss::after {
  content: "✓ gewaehlt";
  display: block;
  margin-top: .15rem;
  font-size: .72rem;
  font-weight: 600;
  color: var(--akzent-dunkel);
}

.kachel__bild {
  aspect-ratio: 4 / 3;
  background: var(--flaeche-2);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.kachel__bild img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Fuer Dateien ohne Vorschau: die Endung als Zeichen. Ein PDF und ein DOCX
   sehen als leeres Quadrat gleich aus — die drei Buchstaben sind die einzige
   Unterscheidung, die es in der Kachel gibt. */
.kachel__typ {
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-leise);
}

.kachel__fuss {
  display: block;
  padding: .5rem .6rem .6rem;
  border-top: 1px solid var(--linie);
  min-width: 0;
}

/* Gekuerzt wird HIER und nicht in der Vorlage, damit der volle Name im
   title-Attribut stehen bleibt und beim Suchen mit Strg+F auffindbar ist. */
.kachel__name {
  display: block;
  font-size: .85rem;
  font-weight: 600;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kachel__masse {
  display: block;
  margin-top: .1rem;
  font-size: .75rem;
  color: var(--text-leise);
  font-variant-numeric: tabular-nums;
}
/* ---------------------------------------------------------------- Bildfokus (L.4)

   Ein Klick ins Bild bestimmt, welcher Teil beim Zuschneiden erhalten bleibt.
   Das Bild ist die Klickflaeche, der Punkt sitzt absolut darin — admin.js setzt
   `left` und `top` in Prozent, deshalb braucht der Behaelter `position:
   relative`. Ohne die Regel klebte der Punkt in der linken oberen Ecke der
   Seite, und die Angabe waere zwar gespeichert, aber unsichtbar.

   `[hidden]` braucht .fokus nicht: Der Bereich wird nie versteckt, er steht nur
   dort, wo es ein Rasterbild gibt (`media.isRaster` in der Vorlage). Die
   Ausnahmeliste in VerstecktesVerschwindetTest nennt ihn deshalb ausdruecklich. */
.fokus {
  position: relative;
  display: inline-block;
  max-width: 100%;
  cursor: crosshair;
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  overflow: hidden;
  line-height: 0;
}
.fokus img { display: block; max-width: 100%; height: auto; }

/* Der Punkt: ein Ring, kein voller Kreis. Ueber einem Bild ist eine Farbe nie
   sicher lesbar — der weisse Ring mit dunklem Rand ist auf hellem UND auf
   dunklem Motiv zu sehen, ohne dass ein Kontrastwert daran haengt. */
.fokus__punkt {
  position: absolute;
  width: 1.1rem;
  height: 1.1rem;
  margin: -.55rem 0 0 -.55rem;
  border: 2px solid #ffffff;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, .55);
  pointer-events: none;
}



/* ---------------------------------------------------------------- Medien im Feld */

.medien-vorschau {
  display: flex;
  gap: .75rem;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: .5rem;
}
.medien-vorschau:empty { display: none; }

.medien-vorschau__bild {
  width: 5rem;
  height: 5rem;
  object-fit: cover;
  border-radius: var(--radius-klein);
  border: 1px solid var(--linie);
  background: var(--flaeche-2);
}

/* DIE VORSCHAU MIT DEN ZWEI KNÖPFEN OBEN RECHTS (Lorins Layout-Vorgabe).

   `position: relative` am Behälter und `absolute` an der Knopfreihe: Die Knöpfe
   liegen IM Bild und nicht daneben. Der Behälter ist dafür ein Block und keine
   Zeile mehr — mit `display: flex` und umbrechendem Inhalt stünde die Reihe
   irgendwo.

   Warum die Knöpfe eine eigene Klasse haben und nicht `.knopf` sind: Sie liegen
   auf einem Bild, das jede Farbe haben kann. Deshalb tragen sie eine deckende
   Fläche (--knopf-neben, Schrift darauf 13.03 hell / 10.67 dunkel) und einen
   Schatten, der sie auch von einem gleich hellen Bild abhebt. Ein Knopf mit
   halbdurchsichtigem Grund hätte auf einem hellen Foto keinen berechenbaren
   Kontrast — und «berechenbar» ist hier die Bedingung. */
/* Der Behälter ist so breit wie das BILD und nicht wie die Spalte: Die Knöpfe
   hängen an seiner oberen rechten Ecke, und die lag vorher rechts NEBEN dem Bild
   (Lorin: «the button should be on the image»). `inline-block` lässt ihn auf
   den Inhalt schrumpfen; `max-width: 100%` hält ihn in der Spalte. */
.medien-vorschau--bild {
  position: relative;
  display: inline-block;
  max-width: 100%;
}

.medien-vorschau--bild img {
  display: block;
  max-width: 100%;
  border-radius: var(--radius-klein);
}

.medien-werkzeuge {
  position: absolute;
  top: .4rem;
  right: .4rem;
  display: flex;
  gap: .3rem;
}

.medien-werkzeug {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: var(--radius-klein);
  background: var(--knopf-neben);
  color: var(--text);
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
}
.medien-werkzeug:hover { background: var(--knopf-neben-hover); }

/* Die Trefferfläche ist 32 px und damit unter den 44 px aus der Hausregel. Das
   ist hier vertretbar und nicht vergessen: Beide Handlungen gibt es auch ohne
   diese Knöpfe — die Mediathek ersetzt und entfernt dasselbe Bild, und auf dem
   Handy steht das Feld ohnehin unter dem Bild. Grössere Knöpfe verdeckten das
   Bild, das man gerade beurteilen will. */
@media (pointer: coarse) {
  .medien-werkzeug { width: 2.75rem; height: 2.75rem; }
}

.medien-vorschau__datei {
  font-size: .88rem;
  padding: .4rem .7rem;
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  background: var(--flaeche-2);
}

/* Der Auswahldialog */
dialog.medienwahl {
  width: min(56rem, 92vw);
  max-height: 85vh;
  padding: 0;
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  background: var(--flaeche);
  color: var(--text);
}
dialog.medienwahl::backdrop { background: rgba(0, 0, 0, .5); }

.medienwahl__kopf {
  display: flex;
  gap: .75rem;
  align-items: center;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--linie);
}
.medienwahl__kopf { flex-wrap: wrap; }
.medienwahl__kopf h2 { margin: 0; font-size: 1.05rem; flex: 1 1 12rem; }
.medienwahl__rumpf { padding: 1.25rem; overflow-y: auto; max-height: 62vh; }

/* -------- Hochladen aus dem Dialog (Bereich G2 baut das Markup und das Skript)

   Bis hierher war der Dialog eine Sackgasse: Wer im Editor ein Bild einsetzen
   wollte, das auf seinem Rechner liegt, musste den Editor mit ungespeicherten
   Aenderungen verlassen, in die Mediathek, hochladen, zurueck, das Feld suchen.
   Vier Bildwechsel sind vier solche Runden. Die Klassen hier sind das Gehaeuse
   dafuer; sie setzen nichts voraus, was erst das Skript herstellt. */

/* Die Umschaltung «Mediathek» / «Hochladen». Zwei Zustaende, und der aktive
   traegt die Marke — wie jeder aktive Punkt im Admin. */
.medienwahl__reiter {
  display: flex;
  gap: .25rem;
  flex-wrap: wrap;
  padding: 0 1.25rem;
  border-bottom: 1px solid var(--linie);
}

/* `display: flex` ist eine Autorenregel und schlaegt die eingebaute Regel
   `[hidden] { display: none }` des Browsers. Ohne diese Zeile setzt
   liesUploadAngaben() das Attribut, es wirkt nicht, und das Reiterband steht auch
   dort, wo niemand hochladen darf. Dieselbe Zeile hat die Datei fuer
   __fortschritt, __fehler, .ablage, .reiter__inhalt und fuenf weitere Stellen. */
.medienwahl__reiter[hidden] { display: none; }

.medienwahl__reiter button,
.medienwahl__reiter .medienwahl__reiterknopf {
  font: inherit;
  font-size: .93rem;
  font-weight: 500;
  padding: .55rem .9rem;
  border: 0;
  border-bottom: 3px solid transparent;
  background: none;
  color: var(--text-leise);
  cursor: pointer;
  margin-bottom: -1px;
}
.medienwahl__reiter button:hover { color: var(--text); }
.medienwahl__reiter button[aria-selected="true"],
.medienwahl__reiter [aria-current="true"] {
  color: var(--akzent-dunkel);
  border-bottom-color: var(--akzent);
}

/* Der Reiter «Vom Computer».

   DERSELBE Innenabstand wie die Liste daneben (.medienwahl__rumpf): Beide sind
   Reiterinhalte desselben Dialogs. Vorher hatte der Reiter keinen, und die
   gestrichelte Flaeche lag damit 20px weiter aussen als die Ueberschrift
   darueber — im Bild sah es aus, als sei sie in den Dialog gerutscht.

   Die Flaeche selbst ist jetzt .ablage, dieselbe wie in der Mediathek, samt
   --aktiv, [hidden] und dem Fokus am unsichtbaren Dateifeld. Hier stand eine
   eigene, fast gleiche Fassung (.medienwahl__ablage, 20 Zeilen): zwei Regeln
   fuer eine Sache, und die erste, die man aendert, laesst die andere zurueck.

   Der Reiter braucht keine Gegenregel zu `[hidden]`: Er ist ein Block, und dort
   wirkt das Attribut von selbst. Die alte Flaeche war `display: flex` und
   brauchte sie — siehe .medienwahl__reiter[hidden] gleich oben. */
.medienwahl__rechner { padding: 1.25rem; }

/* Etwas mehr Luft als die .3rem der allgemeinen Regel: Der Satz steht hier
   nicht unter einem Eingabefeld, sondern unter einer 100px hohen Flaeche.

   KEIN eigenes `display`: Die Klasse ist im Skript benannt, und jede
   display-Regel dazu braucht nach VerstecktesVerschwindetTest eine Gegenregel
   fuer `[hidden]` oder einen Eintrag in seiner Ausnahmeliste. Die allgemeine
   Regel bringt `display: block` schon mit. */
.medienwahl__rechner .feld__hilfe { margin-top: .6rem; }

/* Der Fortschritt. <progress> laesst sich nicht ueberall gleich einfaerben,
   deshalb steht die Zahl daneben im Text und nicht nur im Balken. */
.medienwahl__fortschritt {
  display: flex;
  align-items: center;
  gap: .6rem;
  width: 100%;
  font-size: .85rem;
  margin-bottom: .75rem;
}
.medienwahl__fortschritt progress {
  flex: 1;
  height: .55rem;
  accent-color: var(--akzent-dunkel);
}
.medienwahl__fortschritt[hidden] { display: none; }

/* Was schiefging, steht an der Ablagefläche und nicht in einer Meldung am
   Seitenanfang hinter dem Dialog — dort saehe sie niemand. */
.medienwahl__fehler {
  border-left: 5px solid var(--fehler);
  border-radius: 0 var(--radius-klein) var(--radius-klein) 0;
  background: var(--fehler-flaeche);
  color: var(--fehler);
  padding: .7rem .9rem;
  margin-bottom: 1rem;
  font-size: .88rem;
}
.medienwahl__fehler[hidden] { display: none; }
.medienwahl__fehler ul { margin: .3rem 0 0; padding-left: 1.1rem; }

/* ---------------------------------------------------------------- Editor */

.editor { display: grid; gap: 1.25rem; align-items: start; }

/* 21rem und nicht mehr 17rem: In der rechten Spalte stehen seit der Aufteilung
   nach Bereichen (Field::AREAS) die Schemafelder der Einstellungen — bei den
   Seiten sind das das URL-Segment und die SEO-Gruppe mit Titel, Beschreibung,
   Bild und kanonischer Adresse. In 17rem (272px) blieben davon 240px
   Eingabebreite; ein Suchmaschinentitel von 60 Zeichen ist darin nicht zu lesen.

   Nicht breiter: Der Inhalt links traegt Bloecke mit Bildern und Text, und der
   ist das Wichtigere. Bei 21rem bleibt ihm auf 1400px Fenster noch mehr als das
   Doppelte. */
@media (min-width: 62rem) {
  .editor { grid-template-columns: minmax(0, 1fr) 21rem; }
}

.editor__inhalt { min-width: 0; }
.editor__seite { min-width: 0; }
.editor__seite .karte__rumpf { padding: 1rem; }

/* In der schmalen Spalte gibt es keine halben Felder. `width: half` misst am
   FENSTER (@media, nicht @container) und spannt drei von sechs Rasterspalten —
   in 21rem waeren das 9rem breite Eingaben, waehrend daneben Platz frei bleibt.
   Container-Queries waeren der saubere Weg und braeuchten ein `container-type`
   auf jeder Karte; das aendert deren Layoutverhalten an 40 anderen Stellen mit. */
.felder--eng > .feld { grid-column: 1 / -1; }

/* Die Aktionsleiste bleibt sichtbar — bei einem langen Formular sucht man
   «Speichern» sonst am Seitenende. */
.editor__leiste {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: .6rem;
  flex-wrap: wrap;
  align-items: center;
  padding: .9rem 0;
  margin-top: .5rem;
  background: linear-gradient(to bottom, transparent, var(--grund) 35%);
}

/* Der Zustand links, die Handlungen rechts — dieselbe Aufteilung wie im
   Kartenfuss. */
.editor__leiste .karte__zustand { margin-right: auto; }

/* Die Trennlinie sitzt an der UEBERSCHRIFT der Gefahrenzone und nicht an der
   Knopfreihe darunter: Sonst stand die Ueberschrift oberhalb der Linie und
   gehoerte optisch zum Speichern-Bereich, den sie gerade nicht meint. */
.editor__leiste-titel {
  margin: 2rem 0 .75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--linie);
  font-size: 1rem;
  color: var(--text-leise);
}

.editor__leiste--gefahr {
  position: static;
  margin-top: 0;
  padding-top: 0;
  background: none;
}
.editor__leiste--gefahr form { display: inline; }

/* ---------------------------------------------------------------- Reiter */

.reiter {
  display: flex;
  gap: .25rem;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--linie);
  margin-bottom: 1.25rem;
}

.reiter__knopf {
  font: inherit;
  font-size: .93rem;
  font-weight: 500;
  padding: .55rem .9rem;
  border: 0;
  border-bottom: 3px solid transparent;
  background: none;
  color: var(--text-leise);
  cursor: pointer;
  margin-bottom: -1px;
}
.reiter__knopf:hover { color: var(--text); }
.reiter__knopf[aria-selected="true"] {
  color: var(--akzent-dunkel);
  border-bottom-color: var(--akzent);
  border-bottom-width: 3px;
}

/* Dieselben Reiter, aber als LINKS. Wo jeder Bereich eine eigene Adresse hat —
   Eingang, Aussortiert, Papierkorb — sind Links das Richtige: verlinkbar,
   im Verlauf, mit der mittleren Maustaste in einem neuen Reiter zu oeffnen.
   Der aktive traegt aria-current="page" und nicht aria-selected: Er ist kein
   Reiter in einem Widget, er ist die Seite, auf der man steht.

   In der Karte OBEN und nicht darueber: Im Entwurf sitzen Reiter, Zaehlung und
   Filter in einem Kasten, weil sie eine Sache sind — die Auswahl dessen, was in
   der Liste darunter steht. Vorher standen die drei Bereiche als eigenstaendige
   Knopfreihe davor und sahen aus wie drei Handlungen. */
.reiter--wege {
  margin-bottom: 0;
  padding: 0 1.25rem;
  border-bottom: 1px solid var(--linie);
}
.reiter__weg {
  font-size: .93rem;
  font-weight: 500;
  padding: .7rem .9rem;
  border-bottom: 3px solid transparent;
  color: var(--text-leise);
  text-decoration: none;
  margin-bottom: -1px;
  white-space: nowrap;
}
.reiter__weg:hover { color: var(--text); text-decoration: none; }
.reiter__weg[aria-current="page"] {
  color: var(--akzent-dunkel);
  border-bottom-color: var(--akzent);
  font-weight: 600;
}
.reiter__zahl {
  font-variant-numeric: tabular-nums;
  opacity: .75;
  font-weight: 400;
}

/* Die Filterzeile in dieser Karte: kompakt, alles in einer Reihe, mit der
   Handlung am Ende. Die alte .filterleiste ist ein 6-Spalten-Raster fuer
   beschriftete Felder — hier sind die Felder schmal und tragen ihre
   Beschriftung im Platzhalter oder als nur-sr, wie im Entwurf. */
/* DIE FILTERLEISTE — auf allen fünf Bildschirmen gleich gebaut (Lorins
   Vorgabe: «baue es auf allen 5 Seiten gleich»). Sie steht auf dem
   Änderungsprotokoll, in den Einträgen, den Formularen, der Mediathek und den
   Weiterleitungen.

   Zwei Reihen: oben die Filter in gleich breiten Spalten, unten der Zeitraum
   und rechts der Knopf. Vorher war es eine umbrechende Flex-Zeile, in der jedes
   Feld seine Inhaltsbreite bekam — verschieden breite Kästen, deren Umbruch von
   der Fensterbreite abhing, und auf jeder der fünf Seiten sah die Leiste anders
   aus.

   Wo es keinen Zeitraum gibt (Medien, Weiterleitungen, Einträge), steht in der
   unteren Reihe nur der Knopf — rechts, an derselben Stelle wie überall. */
.filterzeile { display: grid; gap: .75rem; }

/* `auto-fit` mit einer Mindestbreite statt fester Spaltenzahl: Auf einem
   schmalen Fenster werden aus vier Spalten zwei und dann eine, ohne dass dafür
   eine zweite Regel nötig ist. */
.filterzeile__oben {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: .75rem;
}

.filterzeile__unten {
  display: flex;
  align-items: flex-end;
  gap: .75rem;
  flex-wrap: wrap;
}

.filterzeile__zeitraum {
  flex: 1 1 22rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .75rem;
  border: 0;
  margin: 0;
  padding: 0;
}

.filterzeile__knoepfe { display: flex; align-items: center; gap: .5rem; margin-left: auto; }

/* Die Felder füllen ihre Spalte: Ein `select`, das sich nach seinem längsten
   Eintrag richtet, sprengt sonst das Raster — und die Spalten stehen wieder
   krumm. */
.filterzeile__feld input,
.filterzeile__feld select { width: 100%; }
.filterzeile__feld { min-width: 0; }
.filterzeile__feld label {
  display: block;
  font-size: .78rem;
  color: var(--text-leise);
  margin-bottom: .15rem;
}

/* Ein Reiter, in dem noch ein Fehler wartet. Die Zahl und das Wort «Fehler»
   stehen im Text — vorher unterschied nur aria-selected die Reiter, und wer den
   ersten korrigierte, erfuhr erst beim naechsten Absenden von einem Fehler in
   einem Reiter, den er nie geoeffnet hatte. */
.reiter__fehler {
  display: inline-block;
  margin-left: .4rem;
  font-size: .78rem;
  font-weight: 600;
  padding: 0 .4rem;
  border-radius: 999px;
  background: var(--fehler-flaeche);
  color: var(--fehler);
  border: 1px solid var(--fehler);
}

/* Die Sammelmeldung ueber den Reitern: wie viele Felder fehlen und wo. */
.fehlerliste { list-style: none; margin: .4rem 0 0; padding: 0; }
.fehlerliste li { margin-bottom: .15rem; }

/* Ohne JavaScript sind alle Reiterinhalte sichtbar — das Formular bleibt
   vollstaendig bedienbar, nur weniger aufgeraeumt. */
.reiter__inhalt[hidden] { display: none; }

/* ---------------------------------------------------------------- Mehrsprachigkeit (K.2)

   Der Zustand einer Sprachfassung darf nicht nur an der Farbe haengen: Wer Rot
   und Gruen nicht unterscheidet, saehe sonst drei gleiche Punkte. Deshalb hat
   jeder Zustand eine eigene FORM — gefuellte Scheibe (steht auf der Website),
   Ring (in Arbeit), gestrichelter Ring (nicht auf der Website) —, daneben steht
   das Wort, und fuer Screenreader ist der Satz in einem .nur-sr
   ausgeschrieben. Drei Traeger fuer dieselbe Aussage; faellt einer aus, bleibt
   sie lesbar.

   Bei «locales.enabled: false» liefert der Controller leere Listen, und keine
   dieser Regeln greift auf irgendetwas. */

/* Flex liegt auf der Leiste UND auf ihrer Liste: Der Editor setzt seine
   Sprachen in ein <ul> (Aufzaehlung, weil sie eine ist), Textbausteine und
   Menues haengen ihre Punkte direkt in das <nav>. Beide brauchen dieselbe
   Anordnung. */
.sprachleiste {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-bottom: 1.25rem;
}

.sprachleiste__liste {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.sprachleiste__anlegen { margin: 0; }

.sprachwahl {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font: inherit;
  font-size: .88rem;
  text-align: left;
  padding: .4rem .75rem;
  border: 1px solid var(--linie);
  border-radius: 999px;
  background: var(--flaeche);
  color: var(--text);
  text-decoration: none;
}

a.sprachwahl:hover,
button.sprachwahl:hover {
  background: var(--flaeche-2);
  border-color: var(--linie-stark);
  color: var(--text);
}

button.sprachwahl { cursor: pointer; }

/* Die aktuelle Fassung ist keine Schaltflaeche, sondern ein Zustand. */
.sprachwahl--aktuell {
  border-color: var(--akzent-dunkel);
  background: var(--akzent-leicht);
  font-weight: 600;
}

/* Gestrichelt, weil dieser Knopf nirgendwohin fuehrt, sondern etwas anlegt. */
.sprachwahl--fehlt {
  border-style: dashed;
  color: var(--text-leise);
}

.sprachwahl__name { font-weight: 500; }
.sprachwahl__wort { font-size: .8rem; color: var(--text-leise); }
.sprachwahl--aktuell .sprachwahl__wort { color: var(--akzent-dunkel); }

.sprachwahl__punkt {
  flex: none;
  width: .7rem;
  height: .7rem;
  border-radius: 999px;
}
.sprachwahl__punkt--scheibe     { background: var(--erfolg); }
.sprachwahl__punkt--ring        { background: transparent; border: 3px solid var(--warnung); }
.sprachwahl__punkt--gestrichelt { background: transparent; border: 2px dashed var(--linie-stark); }

/* Textbausteine und Menues bringen eine einfachere Leiste mit
   (admin/globals/_sprachleiste.twig, admin/menus/_sprachleiste.twig): Dort gibt
   es keinen Entwurf, also nur zwei Zustaende — erfasst und noch nicht erfasst.
   Ihren Zustand tragen sie selbst als Zeichen im Text (● / ○), damit er auch
   ohne CSS zu sehen ist; von hier kommt nur, was sie zur Leiste des Editors
   passend macht.

   Die Farbe sitzt auf dem ersten Kind und nicht auf dem ganzen Punkt: Sonst
   waere die Beschriftung mitgefaerbt, und «Français» in Gruen ist keine
   Auskunft ueber den Zustand, sondern nur bunt. Das koppelt diese Regel an den
   Aufbau der beiden Vorlagen — das Zeichen steht dort zuerst. */
.sprachleiste__punkt {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .88rem;
  padding: .4rem .75rem;
  border: 1px solid var(--linie);
  border-radius: 999px;
  background: var(--flaeche);
  color: var(--text);
  text-decoration: none;
}

a.sprachleiste__punkt:hover {
  background: var(--flaeche-2);
  border-color: var(--linie-stark);
  color: var(--text);
}

.sprachleiste__punkt--aktuell {
  border-color: var(--akzent-dunkel);
  background: var(--akzent-leicht);
  font-weight: 600;
}

.sprachleiste__punkt > span:first-child { font-size: .75rem; line-height: 1; }
.sprachpunkt--gruen > span:first-child { color: var(--erfolg); }
.sprachpunkt--gelb  > span:first-child { color: var(--warnung); }
.sprachpunkt--grau  > span:first-child { color: var(--text-leise); }

/* Die Sprachwahl ueber der Listenansicht — normale Knoepfe, damit sie aussehen
   wie das, was sie sind: Verknuepfungen auf dieselbe Liste in einer anderen
   Sprache. */
.sprachwahl-leiste {
  display: flex;
  align-items: center;
  gap: .4rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

/* Der Stand in einer Tabellen- oder Baumzeile: der Sprachcode als Marke, die
   Form sagt den Zustand, der Satz daneben die Zahl. */
.sprachstand {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
}

.sprachstand__punkte { display: inline-flex; gap: .25rem; }

.sprachstand__punkt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9rem;
  padding: .05rem .3rem;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .03em;
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  background: var(--flaeche-2);
  color: var(--text-leise);
}
.sprachstand__punkt--scheibe {
  background: var(--erfolg-flaeche);
  color: var(--erfolg);
  border-color: transparent;
}
.sprachstand__punkt--ring {
  background: var(--warnung-flaeche);
  color: var(--warnung);
  border-color: transparent;
}
.sprachstand__punkt--gestrichelt {
  background: none;
  border-style: dashed;
  border-color: var(--linie-stark);
}
/* Unterstrichen statt eingefaerbt: Die Farben sind hier schon vergeben. */
.sprachstand__punkt--aktuell {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Ein Feld, dessen Text noch aus der Ausgangssprache stammt.

   Der Hinweis ist eine eigene Rasterzelle ueber dem Feld und keine Huelle
   darum: Ein zusaetzliches Element um das Feld waere selbst eine Rasterzelle,
   und ein halbbreites Feld fiele damit auf ein Sechstel der Breite zusammen. */
.zu-uebersetzen {
  grid-column: span 6;
  display: flex;
  align-items: baseline;
  gap: .5rem;
  flex-wrap: wrap;
  margin: 0 0 .35rem;
  padding: .35rem .55rem;
  border-left: 3px solid var(--warnung);
  border-radius: 0 var(--radius-klein) var(--radius-klein) 0;
  background: var(--warnung-flaeche);
}

.zu-uebersetzen__text { flex: 1 1 14rem; }

/* ---------------------------------------------------------------- Listenansicht */

/* align-items: start und nicht end.
   Mit «end» richtete die Leiste alle Felder an ihrer UNTERKANTE aus. Sobald ein
   Feld hoeher ist als die anderen — das Zeitraum-Feld traegt zwei Eingaben und
   einen Hinweis — standen die drei Beschriftungen auf drei verschiedenen
   Hoehen, und «Suchen» rutschte unter die Mitte des Nachbarn. Oben ausgerichtet
   liegen alle Beschriftungen auf einer Linie, und ein Feld darf wachsen, ohne
   die anderen zu verschieben. */
.filterleiste {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0 1rem;
  align-items: start;
}
.filterleiste .feld { margin-bottom: .9rem; }
.filterleiste__aktionen {
  grid-column: span 6;
  display: flex;
  gap: .5rem;
  padding-bottom: .9rem;
}

.blaetterung {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

/* Die Anweisung stand in einem .nur-sr und war damit unsichtbar; sichtbar war
   nur der Platzhalter, und der verschwindet beim ersten Zeichen. Jetzt steht sie
   als Beschriftung ueber dem Feld und nennt den Titel, den man abtippen soll. */
.endgueltig {
  display: inline-flex;
  flex-direction: column;
  gap: .2rem;
  align-items: flex-start;
  margin-left: .75rem;
  text-align: left;
  vertical-align: top;
}
.endgueltig__zeile { display: flex; gap: .35rem; align-items: center; }
.endgueltig label { font-size: .78rem; color: var(--text-leise); font-weight: 500; }
.endgueltig input[type="text"] { width: 11rem; font-size: .85rem; padding: .35rem .5rem; }

/* ---------------------------------------------------------------- Schmal */

@media (max-width: 52rem) {
  .huelle { flex-direction: column; }
  .seitenleiste {
    width: 100%;
    flex: none;
    height: auto;
    position: static;
    border-right: 0;
    border-bottom: 1px solid var(--linie);
  }
  /* Waagerecht rollend. flex-direction muss ausdruecklich zurueck auf `row`:
     Die Nav ist jetzt auch breit schon ein Flexbereich, nur eben als Spalte. */
  .seitenleiste__nav {
    flex-direction: row;
    overflow-x: auto;
    padding: .35rem .5rem;
    gap: .25rem;
  }
  .nav-gruppe { display: none; }

  /* Antippen: --griff (44 px). Stand vorher nur zufaellig da — 0.6rem Polster
     plus Zeile plus 3px Rand ergaben 45 px, und der Rand faellt jetzt weg.
     Ausdruecklich hingeschrieben, damit die Zahl nicht am naechsten Umbau
     haengt. */
  .nav-punkt {
    min-height: var(--griff);
    padding: .4rem .75rem;
    white-space: nowrap;
  }
  .hauptteil, .kopf { padding: 1.15rem; }

  /* Nebeneinander steht der Fuss jetzt schon von sich aus (Flex, siehe oben) —
     die frueheren grid-template-columns hier waren nach dem Umbau wirkungslos.
     Auf schmalen Schirmen klappt das Menue nach LINKS auf: rechts ist am Rand
     des Fensters kein Platz mehr fuer 11rem. */
  .kontomenue__tafel { right: auto; left: 0; }
  .benutzer[aria-current="page"] { box-shadow: inset 0 -3px 0 var(--akzent); }
}

@media print {
  .seitenleiste, .kopf__aktionen { display: none; }
}

/* ---------------------------------------------------------------- Bloecke (H.3)
   Der Page Builder. Aufgebaut aus denselben Bausteinen wie der Rest des Admin —
   Karte, Feld, Knopf — damit ein Block nicht wie ein Fremdkoerper im Formular
   sitzt. Ohne JavaScript stehen alle Bloecke offen; die Regeln hier setzen
   nichts voraus, was erst das Skript herstellt. */

.bloecke__liste { display: grid; gap: .6rem; margin-bottom: .75rem; }

.block {
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  background: var(--flaeche);
}
.block--fehler { border-color: var(--fehler); }

/* Waehrend des Ziehens haengt der Block ueber der Liste. */
.block--zieht {
  box-shadow: var(--schatten);
  border-color: var(--akzent-dunkel);
  opacity: .85;
}

/* Ausgeblendet heisst: bleibt erhalten, erscheint aber nicht auf der Website. */
.block--aus { border-style: dashed; }
.block--aus .block__auf { opacity: .6; }

.block__streifen {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  padding: .4rem .5rem;
  background: var(--flaeche-2);
  border-radius: var(--radius-klein);
}

.block__griff {
  flex: none;
  font: inherit;
  font-size: 1rem;
  line-height: 1;
  padding: .5rem .35rem;
  border: 0;
  background: none;
  color: var(--text-leise);
  cursor: grab;
  border-radius: var(--radius-klein);
  /* Ohne das scrollt die Seite mit, sobald jemand auf dem Tablet zieht. */
  touch-action: none;
}
.block__griff:hover { color: var(--text); background: var(--flaeche); }
.block--zieht .block__griff { cursor: grabbing; }

/* Der ganze Streifen klappt auf — nicht nur ein kleines Dreieck am Rand. Ein
   Zeichen braucht er trotzdem: Ohne eines sah eine Redaktorin zwei graue Balken
   und nahm an, sie liest eine Aufzaehlung. Der Winkel steht im CSS und nicht im
   Markup, damit er nicht mit dem Blocksymbol um den Platz streitet und beim
   Vorlesen nicht als Text auftaucht — angesagt wird aria-expanded. */
.block__auf {
  flex: 1 1 12rem;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: .6rem;
  font: inherit;
  text-align: left;
  padding: .3rem;
  border: 0;
  background: none;
  color: var(--text);
  cursor: pointer;
}

.block__auf::before {
  content: "";
  flex: none;
  width: .45rem;
  height: .45rem;
  margin: 0 .1rem 0 .15rem;
  border-right: 2px solid var(--text-leise);
  border-bottom: 2px solid var(--text-leise);
  /* zu: der Winkel zeigt nach rechts */
  transform: rotate(-45deg);
  transition: transform .12s ease-out;
}
/* offen: er zeigt nach unten */
.block__auf[aria-expanded="true"]::before { transform: rotate(45deg); }
.block__auf:hover::before { border-color: var(--text); }

@media (prefers-reduced-motion: reduce) {
  .block__auf::before { transition: none; }
}

.block__symbol {
  flex: none;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: var(--radius-klein);
  background: var(--akzent-leicht);
  color: var(--akzent-dunkel);
  display: grid;
  place-items: center;
  font-size: .8rem;
  font-weight: 600;
  text-transform: uppercase;
}

.block__namen { min-width: 0; display: flex; flex-direction: column; }
.block__typ { font-size: .82rem; font-weight: 600; }

/* Der is_title-Wert kann lang sein; er darf den Streifen nicht sprengen. */
.block__titel {
  font-size: .85rem;
  color: var(--text-leise);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.block__titel:empty { display: none; }

.block__marke {
  display: none;
  flex: none;
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--warnung);
  background: var(--warnung-flaeche);
  border-radius: var(--radius-klein);
  padding: .1rem .45rem;
}
.block--aus .block__marke { display: inline-block; }

.block__werkzeuge {
  display: flex;
  align-items: center;
  gap: .35rem .5rem;
  flex-wrap: wrap;
  margin-left: auto;
}

.block__sicht {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: .8rem;
  color: var(--text-leise);
  white-space: nowrap;
  padding: .25rem .4rem;
}

/* «Nach oben», «Kopieren», «Loeschen» am Block: dieselben Nebenknoepfe, also
   dieselbe Gestalt — gefuellt und randlos.

   Der Kommentar davor lautete: «Drei randlose graue Woerter sind kein
   Bedienelement.» Das gilt weiter, und genau darum steht hier eine Flaeche: Sie
   ist immer da, auch auf dem Tablet, wo :hover nie eintritt. Der Rand war der
   frueherere Weg zum selben Ziel. */
.block__werkzeug {
  font: inherit;
  font-size: .8rem;
  padding: .35rem .6rem;
  border: 1px solid transparent;
  border-radius: var(--radius-klein);
  background: var(--knopf-neben);
  color: var(--text);
  cursor: pointer;
}
.block__werkzeug:hover { background: var(--knopf-neben-hover); color: var(--text); }
.block__werkzeug:disabled { opacity: .45; cursor: default; }

/* «Loeschen» sieht ab jetzt auch ohne Hover anders aus als seine Nachbarn und
   steht mit Abstand am Ende der Reihe: 6 px neben «Kopieren» war die
   wahrscheinlichste Fehlgriff-Stelle des ganzen Editors. */
.block__werkzeug--gefahr {
  color: var(--fehler);
  border-color: var(--fehler);
  box-shadow: inset 0 0 0 1px var(--fehler);
  margin-left: .5rem;
}
.block__werkzeug--gefahr:hover { background: var(--fehler-flaeche); color: var(--fehler); }

.block__rumpf { padding: 1rem; border-top: 1px solid var(--linie); }
.block__rumpf[hidden] { display: none; }

.block__einstellungen { margin-top: 1rem; border-top: 1px dashed var(--linie); padding-top: .75rem; }
.block__inhaberin { margin-top: 1rem; border-top: 1px dashed var(--linie); padding-top: .75rem; display: flex; justify-content: flex-end; }

.block__zahnrad {
  font: inherit;
  font-size: .85rem;
  font-weight: 500;
  padding: .3rem .5rem .3rem 0;
  border: 0;
  background: none;
  color: var(--text-leise);
  cursor: pointer;
}
.block__zahnrad:hover { color: var(--text); }
.block__einstellungen fieldset { margin: .5rem 0 0; }
.block__einstellungen fieldset[hidden] { display: none; }

.bloecke__fuss { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }

/* DIE ABLAGE FÜR EINEN NEUEN BLOCK (Lorins Layout-Vorgabe): eine gestrichelte
   Fläche über die ganze Breite, die zeigt, WO der Block landet.

   Gestrichelt und in Akzentfarbe, weil sie kein Behälter ist, sondern ein
   Angebot — dieselbe Sprache wie die Ablagefläche der Mediathek. Der Rand hält
   3.0 (--akzent-dunkel: 6.98 hell, 11.02 dunkel), also mehr als ein
   Bedienelement-Rand braucht.

   Ein <button>, kein <div>: Tastatur, Fokusring und Rolle kommen dann vom
   Browser. Ohne Skript ist er weg (das Skript baut die Blöcke), und dann steht
   dort nichts — besser als ein Knopf, der nichts tut. */
.bloecke__ablage {
  font: inherit;
  font-size: .92rem;
  font-weight: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  width: 100%;
  padding: 1.4rem 1rem;
  border: 2px dashed var(--akzent-dunkel);
  border-radius: var(--radius-klein);
  background: none;
  color: var(--akzent-dunkel);
  cursor: pointer;
}
.bloecke__ablage:hover { background: var(--akzent-leicht); }
.bloecke__ablage-zeichen { font-size: 1.15em; line-height: 1; }

/* DER FESTE BLOCK IST KEIN KASTEN, SONDERN DER ANFANG DER SEITE.

   Lorins Vorgabe: «die Hero ist immer da und auch nicht in einer zweiten Card
   die man zusammenklappen kann, sondern immer dort oben offen». Deshalb hat er
   weder Rahmen noch eigenen Hintergrund: Seine Felder stehen in derselben Reihe
   wie der Titel darüber — ein Block, den man als solchen nicht sieht.

   Der Streifen fehlt im Markup (blocks.twig), nicht bloss in der Anzeige. Hier
   bleibt nur, was die Fläche betrifft. */
.block--fest {
  border: 0;
  background: none;
  border-radius: 0;
}
.block--fest .block__rumpf { padding: 0; border-top: 0; }

/* .knopf setzt display selbst — ohne diese Regel bleibt ein Knopf sichtbar,
   obwohl das Skript ihn auf hidden gesetzt hat. */
.knopf[hidden] { display: none; }

.bloecke__stand { margin-left: auto; }
.bloecke__leer { margin: 0 0 .75rem; }

/* Der Auswahldialog: Vorschaubilder, gruppiert nach category (H.3). */
dialog.bloeckewahl {
  width: min(50rem, 92vw);
  max-height: 85vh;
  padding: 0;
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  background: var(--flaeche);
  color: var(--text);
}
dialog.bloeckewahl::backdrop { background: rgba(0, 0, 0, .5); }

.bloeckewahl__kopf {
  display: flex;
  gap: .75rem;
  align-items: center;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--linie);
}
.bloeckewahl__kopf h2 { margin: 0; font-size: 1.05rem; flex: 1; }
.bloeckewahl__rumpf { padding: 1.25rem; overflow-y: auto; max-height: 68vh; }

.bloeckewahl__gruppe {
  margin: 1.25rem 0 .5rem;
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-leise);
}
.bloeckewahl__rumpf > .bloeckewahl__gruppe:first-child { margin-top: 0; }

.bloeckewahl__raster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: .75rem;
}

.bloeckewahl__karte {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  font: inherit;
  text-align: left;
  padding: .6rem;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  background: var(--flaeche);
  color: var(--text);
  cursor: pointer;
}
.bloeckewahl__karte:hover { border-color: var(--akzent-dunkel); background: var(--akzent-leicht); }
.bloeckewahl__karte:disabled { opacity: .5; cursor: default; }
.bloeckewahl__karte:disabled:hover { border-color: var(--linie-stark); background: var(--flaeche); }

.bloeckewahl__bild {
  width: 100%;
  height: 5rem;
  object-fit: contain;
  border-radius: var(--radius-klein);
  background: var(--flaeche-2);
}
/* Ohne Vorschaubild bleibt der Platz gleich gross — sonst tanzt das Raster. */
.bloeckewahl__bild--leer {
  display: grid;
  place-items: center;
  font-size: 1.6rem;
  font-weight: 600;
  color: var(--text-leise);
  text-transform: uppercase;
}

.bloeckewahl__name { font-size: .9rem; font-weight: 500; }
.bloeckewahl__text { font-size: .8rem; color: var(--text-leise); }

/* Auf einem schmalen Fenster steht der Streifen zweizeilig: oben Griff, Symbol
   und Beschriftung, darunter die Werkzeuge — sonst schrumpft der Titel auf
   nichts zusammen und die Knoepfe rutschen aus dem Bild. */
@media (max-width: 40rem) {
  .block__werkzeuge { margin-left: 0; width: 100%; }
  .block__rumpf { padding: .75rem; }
  .bloecke__stand { margin-left: 0; width: 100%; }

  /* Mit dem Finger bedienbar: 31 px hoch und 6 px Abstand hiess, dass zwischen
     «Kopieren» und «Loeschen» kein Platz fuer eine Fingerspitze war. */
  .block__werkzeug,
  .block__griff,
  .block__sicht {
    min-height: var(--griff);
    padding-top: .5rem;
    padding-bottom: .5rem;
  }
  .block__werkzeuge { gap: .5rem; }
  .block__werkzeug--gefahr { margin-left: auto; }
}

/* -------------------------------------------------- Versionsliste
   Ersetzt zwei style="…"-Attribute in form.twig: Die CSP aus O.8 kennt kein
   unsafe-inline, sie waeren im Browser wirkungslos gewesen. */
.versionsliste { margin: 0; padding-left: 1.1rem; }
.versionsliste__hinweis { margin-top: .6rem; }

/* -------------------------------------------------- Verweise, Gruppen, Wiederholungen
   Die Feldtypen aus G.5 und G.6. Sie teilen sich das Aussehen einer Gruppe:
   ein abgesetzter Rahmen, damit sichtbar ist, was zusammengehoert. */
.verweis, .gruppe, .wiederholung, .seo {
  border: 1px solid var(--linie);
  border-radius: var(--radius, .4rem);
  padding: .8rem 1rem 1rem;
  margin: 0;
}

.verweis > legend, .gruppe > legend, .wiederholung > legend, .seo > legend {
  padding: 0 .4rem;
  font-weight: 600;
}

.verweis__ziel[hidden] { display: none; }

/* DER VERWEIS IST KOMPAKT (Lorins Vorgabe: «Schaltflächen sollen dieses Layout
   haben um sie etwas kompakter zu machen»): Art, Ziel und Beschriftung in einer
   Reihe, der Schalter darunter.

   `auto-fit` mit Mindestbreite wie bei der Filterleiste: Auf einem schmalen
   Fenster werden aus drei Spalten zwei und dann eine. Ein verstecktes Zielfeld
   (`display: none`) belegt keine Spalte — sonst stünde neben «Seite» eine Lücke
   für jede Art, die gerade nicht gewählt ist. */
.verweis__reihe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: .75rem;
  align-items: end;
}
.verweis__reihe > .feld,
.verweis__reihe > .verweis__ziel { margin: 0; min-width: 0; }

/* Luft zwischen der Feldreihe und dem Schalter darunter: Ohne sie klebt er am
   unteren Rand des Auswahlfelds und liest sich wie ein Teil davon. Der Wert ist
   derselbe wie der Abstand INNERHALB der Reihe — dann steht der Schalter so
   weit von den Feldern weg wie die Felder voneinander. */
.verweis__reihe + .wahl { margin-top: .75rem; }
.verweis__reihe select,
.verweis__reihe input { width: 100%; }

/* DER KIPPSCHALTER. Er ersetzt die Ankreuzbox nur an dieser Stelle — eine
   Einstellung, kein Auswahlkästchen.

   Den Zustand trägt die POSITION des Knopfs und nicht die Farbe: Wer die zwei
   Grüntöne nicht unterscheidet, sieht den Knopf trotzdem links oder rechts.
   Gerechnet ist er auch: Knopf auf Schiene 4.35 hell / 4.88 dunkel im Zustand
   «aus», 7.46 in beiden Modi im Zustand «an».

   `appearance: none` und dann alles selbst — mit `forced-colors` fällt der
   Browser auf seine eigene Darstellung zurück, und das ist dort richtig. */
.wahl--switch { align-items: center; gap: .6rem; }

.wahl--switch input {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  width: 2.4rem;
  height: 1.3rem;
  margin: 0;
  border-radius: 999px;
  background: var(--knopf-neben);
  border: 1px solid var(--linie-stark);
  cursor: pointer;
  transition: background .12s ease;
}

.wahl--switch input::after {
  content: "";
  position: absolute;
  top: 50%;
  left: .15rem;
  transform: translateY(-50%);
  width: .9rem;
  height: .9rem;
  border-radius: 50%;
  background: var(--text-leise);
  transition: left .12s ease, background .12s ease;
}

.wahl--switch input:checked {
  background: var(--knopf-haupt);
  border-color: var(--knopf-haupt);
}
.wahl--switch input:checked::after {
  left: calc(100% - 1.05rem);
  background: var(--knopf-haupt-schrift);
}

.wahl--switch input:disabled { cursor: not-allowed; opacity: .6; }

@media (prefers-reduced-motion: reduce) {
  .wahl--switch input,
  .wahl--switch input::after { transition: none; }
}

/* Wer Kontrastdesigns eingestellt hat, bekommt die Ankreuzbox des Systems
   zurück: Ein selbstgebauter Schalter kennt die Farben dieser Designs nicht. */
@media (forced-colors: active) {
  .wahl--switch input { appearance: auto; -webkit-appearance: auto; width: auto; height: auto; }
  .wahl--switch input::after { content: none; }
}

.gruppe__felder, .wiederholung__felder {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1rem;
}

.wiederholung__zeilen { list-style: none; margin: 0 0 .8rem; padding: 0; }

.wiederholung__zeile {
  border: 1px solid var(--linie);
  border-radius: var(--radius, .4rem);
  margin-bottom: .5rem;
  background: var(--flaeche, transparent);
}

.wiederholung__kopf {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .4rem .6rem;
  border-bottom: 1px solid var(--linie);
}

/* Hier stand --leise, und die Variable gab es nie — definiert ist --text-leise.
   Eine Deklaration mit einer unbekannten Variablen ohne Ersatzwert ist ungueltig;
   der Griff rendert dann in voller Textfarbe. Nichts sieht kaputt aus, nur
   flacher: Beiwerk und Inhalt wiegen gleich schwer. Betroffen waren fuenf
   Stellen — Wiederholungsgriff, Menue-Einzug, Menue-Art, Pfadangaben und die
   Blockart im Vergleich. */
.wiederholung__griff { cursor: grab; color: var(--text-leise); }
.wiederholung__titel { flex: 1; font-weight: 500; }

/* Pfeile links gruppiert, Entfernen rechts abgesetzt: «↓» und «✕» standen 4 mm
   auseinander, und der Fehlgriff kostete die ganze Zeile. */
.wiederholung__knoepfe { display: flex; gap: .25rem; align-items: center; }
.wiederholung__weg { margin-left: .9rem; }

/* Auf breiten Bildschirmen steht das Wort, auf schmalen nur das Zeichen mit dem
   aria-label, das ohnehin da ist. Ein Zeichen allein ist im Zweifel nicht das,
   was jemand meint — «Entfernen» ist es. */
.wiederholung__weg-wort { display: none; }
@media (min-width: 44rem) {
  .wiederholung__weg-wort { display: inline; }
}
@media (max-width: 44rem) {
  .wiederholung__knoepfe .knopf { min-height: var(--griff); min-width: 2.4rem; justify-content: center; }
}
.wiederholung__felder { padding: .6rem; }

/* -------------------------------------------------- Seitenbaum (I.1)
   Aufklappen uebernimmt <details>; hier steht nur, wie es aussieht. */
.baum, .baum ul { list-style: none; margin: 0; padding: 0; }
.baum ul { margin-left: 1.2rem; border-left: 1px solid var(--linie); padding-left: .8rem; }

/* Feste Spalten statt einer Flexreihe mit Abstand: Vorher standen Zustandsmarke
   und Uebersetzungsstand in jeder Zeile an einer anderen waagrechten Stelle,
   weil Titel und Pfad verschieden lang sind — und man konnte den Baum nicht
   senkrecht abfahren, um zu sehen, was noch im Entwurf ist. */
.baum__zeile {
  display: grid;
  grid-template-columns: minmax(8rem, 1fr) minmax(0, 13rem) 8.5rem auto auto;
  align-items: baseline;
  gap: .3rem .6rem;
  padding: .35rem .2rem .35rem 1.4rem;
  position: relative;
  cursor: pointer;
  /* Das Dreieck, das <summary> selbst mitbringt, sieht in jedem Browser anders
     aus und wuerde ausserdem eine Rasterzelle beanspruchen. */
  list-style: none;
}
.baum__zeile::-webkit-details-marker { display: none; }

/* Das Aufklappzeichen steht absolut und damit AUSSERHALB des Titel-Links: Als
   ::before am <a> waere es mitunterstrichen und Teil der Klickflaeche des Links,
   der aber gerade nicht aufklappt, sondern die Seite oeffnet. */
.baum__zeile::before {
  content: "";
  position: absolute;
  left: .3rem;
  top: .85em;
  width: .4rem;
  height: .4rem;
  border-right: 2px solid var(--text-leise);
  border-bottom: 2px solid var(--text-leise);
  transform: rotate(-45deg);
}
details[open] > .baum__zeile::before { transform: rotate(45deg); }

/* Ein Blatt hat nichts aufzuklappen — der Zeiger darf nicht behaupten, es gaebe
   etwas zu klicken, und ein Winkel darf nicht Unterseiten versprechen. */
.baum__zeile--blatt { cursor: default; }
.baum__zeile--blatt::before { content: none; }

.baum__namen { display: inline-flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; min-width: 0; }
.baum__titel { font-weight: 500; }
.baum__pfad { font-family: var(--schrift-fest); min-width: 0; overflow-wrap: anywhere; }
.baum__zustand, .baum__sprachen { min-width: 0; }
/* Die Handlungen sitzen in der letzten Zelle und nicht am Zeilenende per
   margin-left:auto: Im Raster verschiebt eine fehlende Zelle sonst die
   ganze Zeile — und fehlen kann sie, weil sie nur dasteht, wer bearbeiten
   darf. Die Zelle bleibt also da, auch wenn sie leer ist. */
.baum__handlungen { align-self: center; }
.baum__handlungen .iconreihe { display: flex; }

@media (max-width: 52rem) {
  /* Auf dem Telefon wird aus dem Raster wieder eine Reihe: vier Spalten auf
     360 px sind vier unlesbare Streifen. */
  .baum__zeile {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .6rem;
  }
}

/* -------------------------------------------------- Menü-Baum (J.2)
   Die Punkte liegen als flache Reihe im Formular, nicht verschachtelt: Eine
   echte Verschachtelung müsste beim Ein- und Ausrücken umgehängt werden, und
   dabei geht die Zuordnung von Feld zu Punkt verloren. Die Tiefe ist deshalb
   eine Klasse, und der Einzug entsteht hier. */
.menue { border: 0; padding: 0; margin: 0; }
.menue > legend { padding: 0; font-weight: 600; }

.menue__liste { display: flex; flex-direction: column; gap: .35rem; }
.menue__leer[hidden] { display: none; }
.menue__fuss { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-top: .8rem; }
.menue__stand { margin-left: auto; }

/* Der Einzug: eine Ebene ist ein Schritt. Mehr als vier Ebenen erlaubt kein
   Menü dieser Art — die Regeln enden deshalb dort, statt ins Leere zu wachsen. */
.menuepunkt--tiefe-1 { margin-left: 1.5rem; }
.menuepunkt--tiefe-2 { margin-left: 3rem; }
.menuepunkt--tiefe-3 { margin-left: 4.5rem; }
.menuepunkt--tiefe-4 { margin-left: 6rem; }

.menuepunkt__einzug { color: var(--text-leise); font-family: var(--schrift-fest); }
.menuepunkt__namen { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; min-width: 0; }
.menuepunkt__label { font-weight: 500; }
.menuepunkt__art { color: var(--text-leise); font-size: .85rem; }
.menuepunkt__werkzeuge { display: flex; gap: .25rem; margin-left: auto; }
.menuepunkt__ziel[hidden] { display: none; }
.menuepunkt--fehler > .menuepunkt__streifen { border-left: 3px solid var(--fehler); }

/* Der Pfad einer Seite in der Auswahl — technisch, deshalb leiser und fest. */
.pfad { font-family: var(--schrift-fest); color: var(--text-leise); font-size: .85rem; }

@media (max-width: 40rem) {
  /* Auf einem schmalen Schirm frisst der Einzug die Beschriftung. Die Tiefe
     zeigt dann der Pfeil im Streifen, nicht der Abstand. */
  .menuepunkt--tiefe-1,
  .menuepunkt--tiefe-2,
  .menuepunkt--tiefe-3,
  .menuepunkt--tiefe-4 { margin-left: .5rem; }

  .menuepunkt__werkzeuge { margin-left: 0; width: 100%; }
  .menue__stand { margin-left: 0; width: 100%; }
}

/* -------------------------------------------------- Versionsvergleich (P.2)
   Zwei Fassungen nebeneinander, Feld für Feld. Auf einem schmalen Schirm
   untereinander — nebeneinander wären zwei Spalten à 15rem unlesbar. */
.vergleich__leiste {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  align-items: flex-end;
  margin-bottom: 1.5rem;
}

.vergleich__wahl { display: flex; flex-direction: column; gap: .25rem; }

.vergleich__spalten {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 1.5rem;
  align-items: start;
}

.vergleich__kopf {
  font-weight: 600;
  padding-bottom: .4rem;
  border-bottom: 1px solid var(--linie);
  position: sticky;
  top: 0;
  background: var(--flaeche, var(--grund));
}

.vergleich__spalte { min-width: 0; }

.vergleich__text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  line-height: 1.7;
}

/* Hinzugefügt und entfernt unterscheiden sich NICHT nur in der Farbe: Rot und
   Grün sind für einen Teil der Leserinnen dasselbe. Der Unterstrich und die
   Durchstreichung tragen dieselbe Aussage ohne Farbe — und beim Vorlesen bleibt
   sie über das <ins>/<del> im Markup erhalten. */
.vergleich__plus,
.vergleich__minus {
  padding: .05em .15em;
  border-radius: 2px;
  text-decoration-thickness: 2px;
}

.vergleich__plus {
  background: var(--plus-flaeche);
  text-decoration: underline;
}

.vergleich__minus {
  background: var(--minus-flaeche);
  text-decoration: line-through;
}

.vergleich__medien { display: flex; gap: 1rem; flex-wrap: wrap; }
.vergleich__medien img { max-width: 14rem; height: auto; border-radius: 4px; }

.vergleich__bloecke { list-style: none; margin: 0; padding: 0; }

.vergleich__bloecke li {
  display: flex;
  gap: .6rem;
  align-items: baseline;
  flex-wrap: wrap;
  padding: .4rem 0;
  border-bottom: 1px solid var(--linie);
}

.vergleich__blockart {
  font-size: .8rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-leise);
  min-width: 7.5rem;
}

.vergleich__blockname { font-weight: 500; }

.marke--geaendert { background: var(--geaendert-flaeche); color: var(--text); }

@media (max-width: 52rem) {
  .vergleich__spalten { grid-template-columns: 1fr; gap: 0; }
  .vergleich__kopf { position: static; margin-top: 1.25rem; }
}

/* ---------------------------------------------------------------- Zwei-Faktor (O.5) */

/* Eine Karte, die eine Warnung traegt, statt einer Meldung darueber: Der Hinweis
   «jetzt notieren» gehoert an die Codes und nicht an den Seitenanfang. */
.karte--warnung {
  border-color: var(--warnung);
  background: var(--warnung-flaeche);
}

.warnung-text { color: var(--warnung); }

/* Mehrere Formulare in einer Aktionsspalte stehen nebeneinander. Als Regel und
   nicht als style-Attribut: Inline-Styles verstossen gegen die CSP aus O.8. */
.tabelle__aktionen form { display: inline-block; }

/* QR-Code und Text nebeneinander, auf dem Telefon untereinander: Wer den Code
   scannt, hat das Telefon in der Hand und liest die Anleitung auf demselben
   Bildschirm, auf dem der Code steht. */
.zweifaktor {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
  align-items: flex-start;
}

.zweifaktor__qr {
  /* Weisser Grund unabhaengig vom Farbschema: Ein QR-Code auf dunklem Grund ist
     invertiert, und ein Teil der Lesegeraete scheitert daran. */
  background: #fff;
  padding: .75rem;
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  line-height: 0;
}

.zweifaktor__qr img { width: 13.75rem; height: 13.75rem; }

.zweifaktor__text { flex: 1 1 16rem; min-width: 0; }

.geheimnis {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 1.05rem;
  letter-spacing: .06em;
  word-break: break-all;
  background: var(--flaeche-2);
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  padding: .35rem .6rem;
  display: inline-block;
}

/* Die Codes stehen in einem Textfeld und nicht in einer Liste: So sind alle acht
   mit einem Griff markiert und kopiert — ohne JavaScript, das die CSP ohnehin
   nur mit Nonce durchliesse. */
.codes__feld {
  width: 100%;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 1.05rem;
  letter-spacing: .08em;
  line-height: 1.8;
  resize: vertical;
  background: var(--flaeche);
  color: var(--text);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  padding: .6rem .8rem;
  margin-bottom: .8rem;
}

/* Papier ist fuer diese acht Codes die realistische Ablage. Beim Drucken bleibt
   deshalb die Karte mit den Codes und sonst nichts. */
@media print {
  .seitenleiste,
  .kopf,
  .sprung,
  .knopfreihe,
  .meldung {
    display: none;
  }

  .karte--warnung { border: 1px solid #000; background: #fff; }
  .codes__feld { border: 0; padding: 0; height: auto; }
  .hauptteil { padding: 0; }
}

/* ---------------------------------------------------------------- Sicherungen (U.4) */

/* Die Kennzahlen der nächtlichen Sicherung als Definitionsliste und nicht als
   Tabelle: Es sind Paare aus Begriff und Zustand, und auf einem Telefon soll
   die Erklärung unter dem Wert stehen dürfen, statt in einer zweiten Spalte
   zu verschwinden. */
.sicherung__daten {
  display: grid;
  grid-template-columns: minmax(9rem, max-content) 1fr;
  gap: .45rem 1.25rem;
  margin: 0;
}

.sicherung__daten dt {
  font-weight: 600;
  color: var(--text-leise);
}

.sicherung__daten dd { margin: 0; }

/* Die Erläuterung hinter dem Wert bricht in die nächste Zeile, statt die
   Spalte zu sprengen. */
.sicherung__daten dd .klein { display: block; }

@media (max-width: 40rem) {
  .sicherung__daten { grid-template-columns: 1fr; gap: .15rem; }
  .sicherung__daten dd { margin-bottom: .6rem; }
}

.sicherung__stand { margin: 0 0 1rem; }

.sicherung__liste {
  margin: .5rem 0 1rem;
  padding-left: 1.2rem;
}

.sicherung__liste li { margin-bottom: .25rem; }

/* Ein Befehl, den jemand kopiert und einfügt. Er darf nicht umbrechen — eine
   umgebrochene Kommandozeile wird falsch kopiert — also scrollt der Kasten. */
.sicherung__befehl {
  overflow-x: auto;
  background: var(--flaeche-2);
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  padding: .7rem .9rem;
  margin: .5rem 0 1rem;
}

.sicherung__befehl code {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: .85rem;
  white-space: pre;
}

/* ---------------------------------------------------------- Statistik (Modul analytics) */

/* Die Statistikseite. Ein neuer Abschnitt am Ende, keine vorhandene Regel
   umgeschrieben.

   FARBEN: Nur Token aus dem Block oben, keine neuen Farbwerte. Die Paare, auf
   denen die Diagramme stehen, sind dort schon nachgerechnet:

     --akzent-dunkel  auf --flaeche    6.98 hell /  9.13 dunkel  Linie, Balkenrand
     --text-leise     auf --flaeche    5.63 hell /  5.63 dunkel  zweite Linie, Achsentext
     --linie-stark    auf --flaeche    3.43 hell /  3.87 dunkel  Nulllinie, Lueckenstreifen
     --akzent-schrift auf --akzent     7.93 hell /  8.87 dunkel  gewaehlte Zeitspanne

   #50C878 selbst hat gegen Weiss nur 2.13 und darf deshalb nie allein eine
   Aussage tragen. Als Datenfarbe steht es in den Balken — aber mit einem Rand in
   --akzent-dunkel, und der Rand ist es, der die 3.0 aus SC 1.4.11 haelt. Im
   dunklen Modus traegt #50C878 mit 6.90 selbst; der Rand bleibt trotzdem, weil
   eine Form, die je Modus verschieden gebaut ist, in einem der beiden Modi beim
   naechsten Umbau vergessen wird.

   GRUEN MARKIERT ZUSTAND (Lorins Entscheidung): Die gewaehlte Zeitspanne ist ein
   Zustand und traegt deshalb die Marke; die Schaltflaeche «Anzeigen» daneben ist
   eine Handlung und bleibt neutral. */

/* ------------------------------------------------------------- Zeitraumwahl */

/* Die wichtigste Bedienung der Seite steht ganz oben und sagt, womit verglichen
   wird. Ein «+40 %» ohne Vergleichszeitraum ist keine Auskunft. */
.zeitraumwahl__titel { font-size: 1.15rem; margin-bottom: .35rem; }
.zeitraumwahl__vergleich { margin-bottom: 1rem; max-width: 46rem; }

.spannen {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: 1rem;
}

/* Ein Link und kein Auswahlfeld: verlinkbar, im Browserverlauf auffindbar, ohne
   «Anzeigen» dahinter. Die Trefferflaeche haelt --griff, damit sie auf einem
   Telefon mit dem Finger zu treffen ist. */
.spanne {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  min-height: var(--griff);
  padding: .35rem .9rem;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  background: var(--flaeche);
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
}
.spanne:hover { background: var(--flaeche-2); color: var(--text); text-decoration: none; }

/* Der gewaehlte Ausschnitt: Zustand, also die Marke — gefuellt, mit dunkler
   Schrift darauf (7.93 hell). Das Wort steht daneben und aria-current sagt es
   auch ohne Farbe. */
.spanne--aktiv {
  background: var(--akzent);
  color: var(--akzent-schrift);
  border-color: var(--akzent-dunkel);
}
.spanne--aktiv:hover { background: var(--akzent); color: var(--akzent-schrift); }

/* Unter 30 Tagen faellt «Blindstellen» weg. Das steht an der Schaltflaeche und
   nicht erst im leeren Abschnitt: Wer den Ausschnitt verkleinert und dabei einen
   Abschnitt verliert, soll den Zusammenhang sehen, bevor er scrollt. */
.spanne__warnung { font-size: .7rem; font-weight: 400; }

.spannen__form fieldset { border: 0; margin: 0; padding: 0; }
.spannen__form input[type="date"] { width: auto; margin-right: .5rem; }

/* --------------------------------------------------------------- Sprungliste */

/* Neun Abschnitte sind eine lange Seite. Die Sprungliste ist eine echte
   Navigation mit Ankern — kein Klappmenue, damit sie beim Drucken mitkommt und
   ohne JavaScript funktioniert. */
.sprungliste {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  margin-bottom: 1.25rem;
}
.sprungliste__titel {
  display: block;
  font-size: .78rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-leise);
  font-weight: 600;
  margin-bottom: .5rem;
}
.sprungliste ol {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: .3rem .5rem;
  counter-reset: sprung;
}
@media (min-width: 46rem) {
  .sprungliste ol { grid-template-columns: 1fr 1fr 1fr; }
}
.sprungliste li { counter-increment: sprung; font-size: .9rem; }
.sprungliste li::before {
  content: counter(sprung) ". ";
  color: var(--text-leise);
}

/* ---------------------------------------------------------------- Abschnitte */

.abschnitt__nummer {
  display: inline-block;
  min-width: 1.6rem;
  color: var(--text-leise);
  font-weight: 400;
}

/* Der Satz, der sagt, welche Frage der Abschnitt beantwortet. Ohne ihn ist jeder
   Abschnitt eine Tabellensammlung. */
.abschnitt__lead {
  max-width: 46rem;
  margin-bottom: 1.5rem;
}

/* Ein Block innerhalb einer Abschnittskarte: Ueberschrift, Erklaerung, Tabelle,
   «und dann?». Die Trennlinie ersetzt die Karte-in-Karte — verschachtelte Karten
   mit zwei Raendern und zwei Schatten lesen sich als zwei Ebenen, und es ist nur
   eine. */
.karte__block {
  margin-bottom: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--linie);
}
.karte__block:first-of-type { padding-top: 0; border-top: 0; }
.karte__block h3 { margin-bottom: .35rem; }
.karte__block > p { max-width: 46rem; }
.karte__block .tabelle-huelle { margin: 0 -1.25rem; }
.karte__block > :last-child { margin-bottom: 0; }

/* ------------------------------------------------------------------ Kacheln */

.kachelreihe {
  display: grid;
  gap: 1rem;
  margin-bottom: 1.5rem;
}
@media (min-width: 44rem) {
  .kachelreihe { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
}

.kachel-zahl {
  background: var(--flaeche-2);
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  padding: .9rem 1rem;
}
.kachel-zahl__name {
  font-size: .8rem;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--text-leise);
  font-weight: 600;
}
.kachel-zahl__wert {
  font-size: 1.9rem;
  font-weight: 600;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

/* Eine Zahl, die noch keine Aussage traegt, ist nicht falsch — sie ist zu duenn.
   Deshalb gedaempft und mit dem Wort «etwa» davor, NICHT in --warnung: Ein roter
   oder oranger Hinweis an einer Zahl, die stimmt, erzieht dazu, farbige Hinweise
   zu uebersehen. Der Grund steht darunter im Klartext. */
.kachel-zahl__wert--tendenz,
.kachel-zahl__wert--leer { color: var(--text-leise); font-weight: 500; }
.kachel-zahl__etwa { font-size: 1.1rem; font-weight: 400; }
.kachel-zahl--tendenz { border-style: dashed; }

.kachel-zahl__gesperrt { font-size: 1rem; font-weight: 500; }
.kachel-zahl--gesperrt { border-style: dashed; }

.kachel-zahl__vergleich {
  font-size: .85rem;
  color: var(--text-leise);
  margin-top: .1rem;
}
/* Pfeil UND Wort UND Zahl: Eine Richtung, die nur an einer Farbe haengt, ist
   fuer etwa jeden zwoelften Mann keine Richtung. */
.kachel-zahl__pfeil { font-size: .75rem; }

.kachel-zahl__hinweis {
  font-size: .82rem;
  color: var(--text-leise);
  margin: .5rem 0 0;
}

/* «Und dann?» ist der wertvollste Teil des Moduls: Er sagt, was man an der
   Website aendert. Er steht deshalb an der Zahl und nicht in einer Fussnote. */
.kachel-zahl__dann {
  font-size: .82rem;
  margin: .6rem 0 0;
  padding-top: .6rem;
  border-top: 1px solid var(--linie);
}

.dann {
  font-size: .88rem;
  margin: .75rem 0 0;
  max-width: 46rem;
}
.dann__marke {
  font-weight: 600;
  color: var(--akzent-dunkel);
}

.grenze { max-width: 46rem; margin-top: .75rem; }

/* Ein Band, das eine Einschraenkung der Messung benennt — «nur als Tendenz
   lesen». Eigene Form (Rand links, wie eine Meldung, aber neutral), damit es
   nicht wie ein Fehler aussieht: Die Zahlen darunter sind brauchbar, nur nicht
   als Zahl. */
.tendenzband {
  border-left: 4px solid var(--diagramm-linie);
  background: var(--flaeche-2);
  padding: .7rem .9rem;
  border-radius: var(--radius-klein);
  font-size: .9rem;
  max-width: 46rem;
}
.tendenzband--sachlich { border-left-color: var(--akzent-dunkel); }

/* -------------------------------------------------------- Zahlen in Tabellen */

.zahl { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.zahl--tendenz { color: var(--text-leise); font-weight: 500; }
.zahl__menge {
  display: block;
  font-size: .75rem;
  color: var(--text-leise);
  font-variant-numeric: tabular-nums;
}
.tendenzlegende { max-width: 46rem; margin-top: .75rem; }

.zeile__hinweis { margin: .25rem 0 0; text-transform: none; letter-spacing: 0; font-weight: 400; }

/* Eine Zeilenueberschrift ist keine Spaltenueberschrift.

   `.tabelle th` setzt Grossbuchstaben, Sperrung und die leise Farbe — richtig
   fuer eine Spaltenbeschriftung im thead, falsch fuer ein <th scope="row">. Die
   Statistik nennt in der ersten Spalte Seitenpfade, und «/FR/SERVICES» ist eine
   ANDERE Adresse als «/fr/services»: Wer die Zeile in die Adresszeile tippt,
   landet auf einer 404. Ausserdem ist die Zeilenueberschrift die wichtigste
   Zelle der Zeile und darf nicht die leiseste sein.

   Eine zusaetzliche, genauere Regel und keine Aenderung an `.tabelle th`: Die
   Spaltenkoepfe im ganzen Admin sollen bleiben, wie sie sind. */
.tabelle tbody th[scope="row"],
.tabelle tfoot th[scope="row"] {
  text-transform: none;
  letter-spacing: 0;
  color: var(--text);
  font-size: .93rem;
}

.zeile--luecke th, .zeile--luecke td { background: var(--flaeche-2); }

/* Der kleine Balken neben einer Quote. Er dehnt sich auf die Zellenbreite
   (preserveAspectRatio="none" im Markup), die Hoehe steht hier — so ist die Skala
   linear und der Balken auf jedem Schirm gleich hoch. */
.zelle--balken { min-width: 8rem; }
.anteilsbalken {
  display: block;
  width: 100%;
  height: .4rem;
  margin-top: .3rem;
  border-radius: 999px;
  overflow: hidden;
}
.anteilsbalken__grund { fill: var(--linie); }
.anteilsbalken__wert { fill: var(--akzent-dunkel); }

/* ================================================================ Statistik

   Lorins Entwurf: vier Zahlen von heute in einer Reihe, darunter ein grosses
   Verlaufsdiagramm mit einer schmalen Karte daneben, darunter dasselbe noch
   einmal. Die Geometrie steckt in SVG-Attributen und nicht in style="…" — die
   CSP aus O.8 verbietet unsafe-inline. */

/* -------------------------------------------------------- Die Zahlen von heute

   Vier gleich breite Kacheln, unter 62rem zwei, unter 34rem eine. `auto-fit`
   mit minmax waere kuerzer, gaebe aber bei drei Kacheln in einer Reihe eine
   Anordnung, die es in Lorins Entwurf nicht gibt. */
.heutereihe {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: .75rem;
  margin-bottom: .75rem;
}
@media (max-width: 62rem) { .heutereihe { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 34rem) { .heutereihe { grid-template-columns: minmax(0, 1fr); } }

.heute {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  padding: .85rem 1rem 1rem;
  min-width: 0;
}
.heute__name {
  margin: 0;
  font-size: .75rem;
  color: var(--text-leise);
}
.heute__wert {
  margin: .15rem 0 .3rem;
  font-size: 1.55rem;
  font-weight: 600;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.heute__leer { color: var(--text-leise); font-weight: 400; }

/* DIE KACHEL ALLEIN IN EINER KARTE — so steht sie auf der Startseite.

   Ohne eigenen Rand und ohne eigene Flaeche: In einem Kartenrumpf waere sie ein
   Kasten im Kasten, und der innere Rand (--linie) laege 1px neben dem aeusseren.
   Die Zahl wird dafuer groesser. Auf der Statistikseite stehen vier Kacheln
   nebeneinander und teilen die Aufmerksamkeit; hier ist sie der Grund, warum es
   die Karte gibt.

   2.1rem und nicht mehr: Die Seitenspalte ist 19rem breit, minus 2rem Polsterung
   der Karte bleiben 17rem. «12'345» braucht darin bei 2.1rem rund 8rem — auch
   eine Website mit hunderttausend Aufrufen am Tag bricht die Zeile nicht. */
.heute--allein {
  background: none;
  border: 0;
  padding: 0;
}
.heute--allein .heute__wert { font-size: 2.1rem; margin-top: .1rem; }

/* Die Tendenz. Das Vorzeichen steht im Text UND als Zeichen davor — Rot und
   Gruen sind fuer rund jeden zwoelften Mann dasselbe. */
.heute__tendenz {
  margin: 0;
  font-size: .78rem;
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: center;
  gap: .3rem;
}
.heute__tendenz--auf { color: var(--erfolg); }
.heute__tendenz--ab { color: var(--fehler); }
.heute__tendenz--gleich,
.heute__tendenz--still { color: var(--text-leise); }

/* --------------------------------------------------------------- Zwei Spalten

   Inhalt und Seitenspalte, wie im uebrigen Admin — nicht ein Raster mit vier
   Zellen. Als Raster richteten sich die Karten zeilenweise aneinander aus: Die
   schmale Karte oben rechts wurde so hoch wie das Diagramm daneben, und
   zwischen ihr und der Karte darunter stand eine Luecke von der Hoehe des
   Unterschieds (Lorins Befund). In zwei Spalten stapelt jede Seite fuer sich.

   Die Verhaeltnisse sind die aus Lorins Entwurf, etwa zwei Drittel zu einem —
   und damit breiter als die 19rem, die .spalten__seite sonst gibt. */
.spalten--statistik { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: .75rem; }
.spalten--statistik .spalten__inhalt { display: flex; flex-direction: column; gap: .75rem; }
.spalten--statistik .spalten__seite { gap: .75rem; }
.spalten--statistik .karte { margin-bottom: 0; }
@media (max-width: 62rem) {
  .spalten--statistik { grid-template-columns: minmax(0, 1fr); }
}

/* Die grosse Zahl im Kartenkopf: Sie IST die Ueberschrift der Karte, das Wort
   darueber ist die Beschriftung. Umgekehrt waere die Zahl eine Fussnote zur
   Ueberschrift, und sie ist das Gegenteil davon. */
.statistik__zahl {
  margin: 0;
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.statistik__zahl small {
  font-size: .85rem;
  font-weight: 400;
  color: var(--text-leise);
}
.karte__kopf .karte__unterzeile { margin: 0 0 .1rem; font-size: .75rem; }

/* --------------------------------------------------------------- Verlauf

   Eine Tabelle, die als Diagramm aussieht: Zeilen sind Tage, und `display:
   flex` auf dem <tbody> legt sie nebeneinander. Die Tabellensemantik bleibt —
   ein Screenreader liest «Freitag, 390 Aufrufe» statt einer Reihe
   unbeschrifteter Kaesten.

   Verworfen: ein <canvas>. Es braucht ein Skript, ist im Ausdruck leer, hat
   keinen Text und muesste alles doppelt tragen, was hier schon dasteht. */
.verlauf {
  margin: 0;
  display: flex;
  flex-direction: row-reverse;
  align-items: stretch;
  gap: .6rem;
}
.verlauf__tabelle {
  flex: 1 1 auto;
  min-width: 0;
  border-collapse: collapse;
  display: block;
}
/* Die Hoehe kommt aus dem KACHELRASTER und nicht aus einem runden rem-Wert:
   22 Zeilen mit 8px Kachel und 2px Abstand sind 22*10px minus der letzte
   Abstand. Bei 13rem (208px) waeren die Zeilen 6.5px hoch und die Kacheln
   8x6.5px — fast quadratisch und dadurch schief. So sind sie es genau. */
/* KEINE Hoehe hier: Sie kommt aus dem Kachelraster in der Zelle. Erst stand
   sie hier (13rem), und die Zeilen wurden dann 6.5px hoch, weil die Beschriftung
   der Wochentage von derselben Hoehe abging — die Kacheln waren 8x6.5px, also
   fast quadratisch und dadurch schief. Jetzt bestimmt das Raster die Hoehe und
   die Tabelle folgt. */
/* KEIN Abstand zwischen den Spalten: Das Kachelgitter laeuft durch, und die
   Trennung zwischen zwei Tagen ist dieselbe Kachelluecke wie innerhalb eines
   Tages. Mit 4px dazwischen brach das Raster an jeder Spaltengrenze ab — auf
   dem Bildschirm sah es aus wie sieben Kaesten und nicht wie eine Flaeche. */
.verlauf__tabelle tbody {
  display: flex;
  align-items: flex-end;
  gap: 0;
}
.verlauf__spalte {
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: .35rem;
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  position: relative;
}
.verlauf__tag {
  flex: none;
  font-weight: 400;
  font-size: .7rem;
  color: var(--text-leise);
  padding: 0;
  border: 0;
  white-space: nowrap;
  overflow: hidden;

  /* IMMER eine Zeile hoch, auch ohne Kuerzel. Bei dreissig Tagen traegt nur
     jeder dritte Tag eines; die uebrigen Zellen waren dadurch 17px hoeher als
     die beschrifteten, und die Saeulen standen auf zwei verschiedenen
     Grundlinien — gemessen 344.45px gegen 361.80px, und im Bild ein dunkler
     Streifen alle drei Tage. Bei sieben Tagen fiel es nicht auf, weil dort jeder
     Tag beschriftet ist.

     `min-height` in em mit derselben Zahl als `line-height`: So ist die Hoehe
     dieselbe, ob Text drin steht oder nicht, und sie haengt an der
     Schriftgroesse und nicht an einer abgeschriebenen Pixelzahl. */
  line-height: 1.5;
  min-height: 1.5em;
}
/* Die Zelle eines Tages ist eine REIHE von Saeulen — eine je Stundenblock.
   `align-items: flex-end` waere unnoetig: Jede Saeule ist so hoch wie die Zelle
   und traegt ihre Fuellung von unten im Farbverlauf. */
.verlauf__zelle {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  padding: 0;
  border: 0;
  position: relative;
  display: flex;
  gap: 0;
}

/* Die Saeule aus Kacheln (Lorins Entwurf). 22 Zeilen als Raster, von unten
   gefuellt — `column-reverse` waere kuerzer, aber ein Raster haelt die Zeilen
   auch dann auf gleicher Hoehe, wenn eine Spalte weniger Kacheln hat.

   Warum echte Elemente und kein SVG-Muster: Ein <pattern> skaliert mit seinem
   SVG, und bei sieben Spalten unterschiedlicher Pixelbreite laege das Gitter
   von Spalte zu Spalte anders. 22 Zellen liegen von selbst uebereinander. */
.verlauf__saeule {
  /* IM FLUSS und nicht absolut: Die Saeule ist das Element, das die Hoehe des
     Diagramms bestimmt. Absolut positioniert hatte sie Hoehe 0, weil die Zelle
     seit dem Wegfall des 22-Zeilen-Rasters keine eigene Hoehe mehr hat —
     gemessen, nachdem alle sieben Saeulen unsichtbar waren.

     22 Kacheln mit 8px und 2px Abstand, ohne den letzten Abstand: 218px. Die
     Zahl steht hier und in AnalyticsController::KACHELZEILEN, und das ist die
     eine Stelle, an der sie doppelt ist — dafuer traegt die Vorlage keine
     Rechnung. */
  position: relative;
  display: block;

  /* Alle Saeulen eines Tages teilen die Zellenbreite gleich auf. `flex: 1 1 0`
     und nicht `width`: Bei acht Bloecken je Tag und sieben Tagen sind es
     56 Saeulen, und jede Pixelbreite von Hand ausgerechnet waere eine Zahl, die
     zur Fensterbreite passen muesste. */
  flex: 1 1 0;
  min-width: 0;

  /* DIE HOEHE KOMMT AUS DER BREITE: 22 Zeilen, eine Kachel breit — also ist die
     Saeule 22-mal so hoch wie breit, und die Kachel ist ein Quadrat. Bei jeder
     Fensterbreite.

     Vorher stand hier eine feste Hoehe von 218px. Gemessen war die Kachel dann
     9.6 x 8px — fast quadratisch und dadurch schief, weil Breite und Hoehe aus
     zwei verschiedenen Quellen kamen (Fensterbreite bzw. Pixelzahl).

     Die Grenzen sind da, wo Quadrate keinen Sinn mehr haben: Bei 365 Tagen ist
     eine Saeule 1.8px breit, und ein Diagramm von 39px Hoehe ist keines mehr.
     Innerhalb der Grenzen — grob 150 bis 270px — stimmt das Quadrat genau. */
  aspect-ratio: 1 / 22;
  min-height: 9rem;
  max-height: 17rem;

  /* DREI VERLAEUFE, uebereinander gelegt — und keine 22 Elemente je Spalte.
     In der Malreihenfolge von oben:

     1. die Zeilenluecken: waagrechte Streifen in Kartenfarbe, alle 10px,
     2. die Spaltenluecken: senkrechte Streifen in Kartenfarbe, alle --kachel,
     3. die Fuellung: unten --voll bis zur Hoehe --f, darueber --blass.

     Die Luecken sind DECKEND in Kartenfarbe und nicht durchsichtig: So braucht
     es keine Maske (mask-composite ist noch nicht ueberall da) und kein Element
     je Kachel. Erst stand hier eine Schleife ueber 22 Zellen je Spalte — im
     Jahresverlauf 8030 Elemente, gemessen 978 KB Markup und 176 ms Layout fuer
     ein Diagramm.

     WARUM DAS RASTER NAHTLOS IST: `--kachel` ist ein Anteil der SPALTENBREITE
     (calc(100% / n)) und keine Pixelzahl. Damit liegt der Rhythmus in jeder
     Spalte gleich, und weil die Spalten sich beruehren, ist die Luecke zwischen
     zwei Tagen genau dieselbe 2px-Luecke wie im Inneren eines Tages — gemessen.
     Mit fester Kachelbreite endete jede Spalte irgendwo mitten in einer Kachel
     und das Muster fing an der naechsten neu an. */
  /* EINE Kachel breit: Der senkrechte Schnitt sitzt am rechten Rand der
     Saeule, und weil die Saeulen sich beruehren, ist die Luecke zwischen zwei
     Stundenbloecken genau dieselbe 2px-Luecke wie zwischen zwei Kachelzeilen.
     Nahtlos ueber den ganzen Tag und ueber die Tagesgrenze hinweg — es gibt
     keinen Wert mehr, der zu einer Spaltenzahl passen muesste. */
  --kachel: 100%;
  /* Die Zeilenhoehe ist ein Anteil der Saeulenhoehe und keine Pixelzahl — sonst
     passt sie nicht mehr, sobald die Saeule ueber `aspect-ratio` mitwaechst. Die
     Luecke bleibt bei 2px: Sie ist eine Fuge und soll nicht mitwachsen. */
  --zeile: calc(100% / 22);
  --f: calc(var(--k, 0) * var(--zeile));
  background-image:
    repeating-linear-gradient(
      180deg,
      transparent 0, transparent calc(var(--zeile) - 2px),
      var(--flaeche) calc(var(--zeile) - 2px), var(--flaeche) var(--zeile)
    ),
    repeating-linear-gradient(
      90deg,
      transparent 0, transparent calc(var(--kachel, 100%) - 2px),
      var(--flaeche) calc(var(--kachel, 100%) - 2px), var(--flaeche) var(--kachel, 100%)
    ),
    linear-gradient(
      to top,
      var(--voll) 0, var(--voll) var(--f),
      var(--blass) var(--f), var(--blass) 100%
    );

  /* --linie und nicht --flaeche-2 fuer die blasse Kachel: Gemessen sitzt
     --flaeche-2 im Hellmodus mit 1.05 auf der Karte und ist damit praktisch
     unsichtbar — das Gitter, das die ganze Gestalt traegt, waere dort nicht da.
     --linie sind 1.32 hell und 1.21 dunkel, und der Unterschied zur gefuellten
     Kachel bleibt bei 2.61 (hell) und 3.87 (dunkel). */
  --blass: var(--linie);
  --voll: var(--diagramm-linie);
}

/* Wie hoch gefuellt wird: eine Klasse je Kachelzahl. Als style-Attribut waere
   es direkter und verstiesse gegen die CSP aus O.8 (kein unsafe-inline). */
.verlauf__saeule--f0 { --k: 0; }
.verlauf__saeule--f1 { --k: 1; }
.verlauf__saeule--f2 { --k: 2; }
.verlauf__saeule--f3 { --k: 3; }
.verlauf__saeule--f4 { --k: 4; }
.verlauf__saeule--f5 { --k: 5; }
.verlauf__saeule--f6 { --k: 6; }
.verlauf__saeule--f7 { --k: 7; }
.verlauf__saeule--f8 { --k: 8; }
.verlauf__saeule--f9 { --k: 9; }
.verlauf__saeule--f10 { --k: 10; }
.verlauf__saeule--f11 { --k: 11; }
.verlauf__saeule--f12 { --k: 12; }
.verlauf__saeule--f13 { --k: 13; }
.verlauf__saeule--f14 { --k: 14; }
.verlauf__saeule--f15 { --k: 15; }
.verlauf__saeule--f16 { --k: 16; }
.verlauf__saeule--f17 { --k: 17; }
.verlauf__saeule--f18 { --k: 18; }
.verlauf__saeule--f19 { --k: 19; }
.verlauf__saeule--f20 { --k: 20; }
.verlauf__saeule--f21 { --k: 21; }
.verlauf__saeule--f22 { --k: 22; }

/* Die Spalte unter dem Zeiger und die von heute heben sich ab. Heute BLASSER
   und nicht farbig: Der Tag ist noch nicht vorbei, und ein grellgruener Balken
   neben sechs grauen liest sich als «hier war viel» statt als «hier ist noch
   nicht Schluss». */
.verlauf__spalte:hover .verlauf__saeule { --voll: var(--akzent-dunkel); }
.verlauf__spalte--heute .verlauf__saeule { --voll: var(--text-leise); }

/* Der Punkt am oberen Ende der Saeule, wie im Entwurf — er sitzt am Ende der
   gepunkteten Linie. Die Hoehe kommt aus derselben Rechnung wie die Fuellung,
   damit er auf der obersten gefuellten Kachel liegt und nicht daneben.

   Nur an der LETZTEN Saeule des Tages: Ein Punkt auf jedem der acht
   Stundenbloecke waere eine Perlenkette und keine Markierung. Der letzte Block
   ist der, an dem die gepunktete Senkrechte steht (sie sitzt am rechten Rand der
   Zelle, nicht in deren Mitte — sonst laege sie mitten in einer Saeule). */
.verlauf__spalte:hover .verlauf__saeule:last-child::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: calc(var(--f) - .25rem - 1px);
  width: .5rem;
  height: .5rem;
  margin-left: -.25rem;
  border-radius: 50%;
  background: var(--text);
  box-shadow: 0 0 0 2px var(--flaeche);
}
/* Ohne gefuellte Kachel kein Punkt: Er saesse auf der Grundlinie und behauptete
   dort einen Wert. */
.verlauf__spalte:hover .verlauf__saeule--f0::after { content: none; }

/* Die gepunktete Senkrechte durch die ganze Spalte. Ein ::before an der Zelle
   und kein eigenes Element: Sie traegt keine Auskunft, sie zeigt nur, welche
   Spalte gemeint ist. */
/* Die gepunktete Senkrechte am RECHTEN Rand der Zelle und nicht in ihrer Mitte:
   Ein Tag besteht jetzt aus mehreren Saeulen, und eine Linie in der Mitte laege
   mitten in einer davon. Am Rand markiert sie die Tagesgrenze — und dort endet
   auch die Fuellung, deren obersten Punkt sie traegt. */
.verlauf__zelle::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 1px;
  border-left: 2px dotted var(--diagramm-linie);
  opacity: 0;
  z-index: 1;
}
.verlauf__spalte:hover .verlauf__zelle::before { opacity: 1; }

/* Ein Tag ohne Daten: ein gestrichelter Sockel unter dem blassen Gitter und
   keine gefuellte Kachel. Eine Null waere eine Aussage, die niemand gemessen
   hat.

   `position: absolute` am unteren Rand, weil das Kachelgitter die Zelle fuellt —
   im Fluss laege der Sockel darunter und schoebe die Zeile auseinander. */
.verlauf__luecke {
  position: absolute;
  left: 0;
  right: 2px;
  bottom: 0;
  height: 0;
  border-top: 2px dashed var(--diagramm-linie);
}

/* Die Blase am Zeiger, wie in Lorins Entwurf. Ohne Skript: Sie haengt am
   :hover der Spalte, genauso wie die Tooltips der Icon-Knoepfe. */
.verlauf__blase {
  position: absolute;
  top: 1.5rem;
  left: 50%;
  transform: translateX(.6rem);
  margin-bottom: 0;
  padding: .35rem .5rem;
  border-radius: var(--radius-klein);
  background: var(--text);
  color: var(--grund);
  font-size: .72rem;
  line-height: 1.3;
  white-space: nowrap;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 20;
}
.verlauf__spalte:hover .verlauf__blase { opacity: 1; visibility: visible; }

/* An den letzten zwei Spalten kippt die Blase nach LINKS. Gemessen: Bei 700px
   Fensterbreite ragte sie an der rechten Spalte 7px hinaus und machte die Seite
   waagrecht rollbar — beim Hovern, also genau dann, wenn niemand damit rechnet. */
.verlauf__spalte:nth-last-child(-n+2) .verlauf__blase {
  transform: translateX(-100%) translateX(-.6rem);
}
.verlauf__blase-datum { display: block; opacity: .75; }
.verlauf__blase-wert { display: block; font-weight: 600; }

/* Die senkrechte Achse. Sechs Beschriftungen, gleichmaessig verteilt — die
   Stelle kommt aus `space-between` und nicht aus einem Wert im Markup.
   `row-reverse` am .verlauf setzt sie links, obwohl sie im Markup nach der
   Tabelle steht: So liest ein Screenreader zuerst die Daten und dann die
   Achse, und die Achse ist fuer ihn ohnehin aria-hidden. */
/* Die Achse ist so hoch wie die Tabelle daneben (align-items: stretch am
   .verlauf) und traegt unten denselben Sockel wie die Wochentagszeile. Die Null
   sitzt damit auf der Grundlinie — ohne eine Pixelzahl, die aus den
   Schriftmassen abgeschrieben waere und beim naechsten Schriftgrad daneben laege.

   Das gilt jetzt doppelt: Die Diagrammhoehe haengt an der Saeulenbreite und
   damit am Fenster. Eine Achse mit fester Hoehe waere bei jeder zweiten
   Fensterbreite verschoben. */
.verlauf__achse {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: .68rem;
  color: var(--text-leise);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.verlauf__striche {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.verlauf__strich { line-height: 1; }

.verlauf__hinweis { margin: .75rem 0 0; }

/* ------------------------------------------------------------------ Ring

   Der Ring aus vier Kreisen mit stroke-dasharray. Gedreht, damit das erste
   Segment oben beginnt: Ein Kreis faengt in SVG rechts an (drei Uhr), und ein
   Ring, dessen groesstes Stueck rechts unten anfaengt, liest sich falsch. */
.ring {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  flex-wrap: wrap;
}
.ring__bild {
  flex: none;
  width: 7.5rem;
  height: 7.5rem;
  transform: rotate(-90deg);
}
.ring__bild circle {
  fill: none;
  stroke-width: 5;
}
/* DIE VIER TOENE. Sie muessen sich voneinander unterscheiden und nicht nur von
   der Karte — der Ring ist die einzige Stelle im Backend, an der vier Farben
   nebeneinander etwas bedeuten.

   Desktop stand auf --akzent-dunkel, im Dunkelmodus #7ce0a4. Neben --akzent
   #50C878 sind das zwei Gruentoene mit einem gerechneten Verhaeltnis von 1.32 —
   Lorins Befund: «contrast is too low of the two greens. Make desktop white».

   Jetzt --text, also #ecebe8 im Dunkeln und #1e1d1a im Hellen: der staerkste
   neutrale Ton, den die Palette hat, in beide Richtungen. Gerechnet (dunkel /
   hell):

     Handy   --akzent      auf --flaeche   8.34 / 2.13
     Desktop --text        auf --flaeche  14.87 / 16.86
     Tablet  --linie-stark auf --flaeche   3.84 / 3.43
     Andere  --linie       auf --flaeche   1.21 / 1.32
     Desktop gegen Handy                   1.78 / 7.93
     Desktop gegen Tablet                  3.87 / 4.91
     ALT: Desktop gegen Handy              1.32 / 3.28

   Die 1.78 zwischen Weiss und Gruen sind kein Rueckschritt gegenueber 1.32: Der
   Unterschied liegt dort in der SAETTIGUNG, und die traegt zwischen zwei
   Flaechen weiter als die Helligkeit.

   Die schwachen Zahlen — Gruen im Hellen mit 2.13, «Andere» in beiden Modi —
   stehen hier, weil sie da sind und nicht, weil sie gut sind. Sie sind zulaessig,
   weil die Legende Name UND Prozentzahl traegt: Die Aufteilung haengt an keiner
   Stelle allein an der Farbe (SC 1.4.1), und die Zahl daneben ist der Weg, sie zu
   lesen. Wer den Ring ohne Legende irgendwo einbaut, muss sie neu rechnen. */
.ring__grund { stroke: var(--flaeche-2); }
.ring__stueck--handy { stroke: var(--akzent); }
.ring__stueck--rechner { stroke: var(--text); }
.ring__stueck--tablet { stroke: var(--diagramm-linie); }
.ring__stueck--unbekannt { stroke: var(--linie); }

.ring__legende {
  flex: 1 1 8rem;
  min-width: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .3rem;
}
.ring__zeile {
  display: flex;
  align-items: center;
  gap: .45rem;
  font-size: .85rem;
}
.ring__punkt {
  flex: none;
  width: .6rem;
  height: .6rem;
  border-radius: 2px;
}
.ring__punkt--handy { background: var(--akzent); }
/* Derselbe Ton wie im Ring — die Legende ist der Schluessel dazu. */
.ring__punkt--rechner { background: var(--text); }
.ring__punkt--tablet { background: var(--diagramm-linie); }
.ring__punkt--unbekannt { background: var(--linie); }
.ring__name { flex: 1 1 auto; min-width: 0; color: var(--text-leise); }
.ring__wert { flex: none; font-weight: 600; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------- Balken in der Liste

   Unter der Zahl und nicht daneben: In einer rechtsbuendigen Zahlenspalte
   nimmt ein Balken daneben der Zahl den Platz, und die Zahl ist das Wichtigere. */
.seitenbalken {
  display: block;
  width: 100%;
  height: 4px;
  margin-top: .25rem;
}
.seitenbalken__grund { fill: var(--flaeche-2); }
.seitenbalken__wert { fill: var(--akzent-dunkel); }
/* ------------------------------------------------------ Zeitraumwahl (Statistik)

   Ein <details>, das nach unten RECHTS oeffnet: Es sitzt am rechten Rand des
   Kartenkopfs, und eine Tafel, die nach rechts aufgeht, laege ausserhalb der
   Karte. Nicht die Klassen des Kontomenues geliehen — das sitzt in der Leiste,
   oeffnet nach links und traegt drei Punkte statt eines Wortes. */
.spannenwahl { position: relative; flex: none; }
.spannenwahl__knopf {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .85rem;
  padding: .4rem .7rem;
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  background: var(--flaeche-2);
  color: var(--text-leise);
  cursor: pointer;
  white-space: nowrap;
}
.spannenwahl__knopf::-webkit-details-marker { display: none; }
.spannenwahl__knopf:hover { color: var(--text); }
.spannenwahl[open] .spannenwahl__knopf { color: var(--text); }

.spannenwahl__winkel {
  width: .35rem; height: .35rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-1px);
}
.spannenwahl[open] .spannenwahl__winkel { transform: rotate(-135deg) translateY(-1px); }

.spannenwahl__tafel {
  position: absolute;
  top: calc(100% + .25rem);
  right: 0;
  z-index: 30;
  min-width: 9rem;
  padding: .25rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  box-shadow: var(--schatten);
  display: flex;
  flex-direction: column;
}
.spannenwahl__punkt {
  padding: .45rem .6rem;
  border-radius: var(--radius-klein);
  font-size: .88rem;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}
.spannenwahl__punkt:hover { background: var(--flaeche-2); text-decoration: none; }
/* Der gewaehlte Zeitraum traegt das Wort UND die Marke: aria-current sagt es
   der Technik, das Gruen dem Auge. */
.spannenwahl__punkt[aria-current="true"] {
  background: var(--akzent-leicht);
  color: var(--akzent-dunkel);
  font-weight: 600;
}


/* ------------------------------------------------------------- Ausstiege */
.ausstiege {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .6rem;
}
.ausstiege__zeile { display: flex; align-items: flex-start; gap: .6rem; }
.ausstiege__rang {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--flaeche-2);
  color: var(--text-leise);
  font-size: .75rem;
  font-weight: 600;
}
.ausstiege__text { min-width: 0; }
.ausstiege__titel {
  display: block;
  font-weight: 600;
  font-size: .9rem;
  overflow-wrap: anywhere;
}
.ausstiege__neben {
  display: block;
  font-size: .78rem;
  color: var(--text-leise);
  font-variant-numeric: tabular-nums;
}


/* --------------------------------------------------------------- Diagramme */

.diagramm { margin: 1.25rem 0 0; }
.diagramm__kopf h3 { margin-bottom: .25rem; }
.diagramm__kopf p { max-width: 46rem; margin-bottom: .75rem; }

/* Auf einem schmalen Schirm scrollt das Diagramm seitwaerts statt zu schrumpfen:
   Ein auf 320 px gestauchtes 720er-viewBox macht die Achsenbeschriftung 5 px
   hoch — und dann liest sie niemand mehr. Die Tabelle darunter braucht kein
   Scrollen; dort stehen dieselben Zahlen. */
.diagramm__flaeche { overflow-x: auto; }
.diagramm__svg {
  display: block;
  width: 100%;
  height: auto;
  min-width: 36rem;
}

.diagramm__gitter { stroke: var(--linie); stroke-width: 1; }
/* Die Nulllinie traegt eine Aussage und haelt deshalb 3.0 (--linie-stark). */
.diagramm__gitter--null { stroke: var(--diagramm-linie); }

.diagramm__achse {
  fill: var(--text-leise);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.diagramm__achse--y { text-anchor: end; }
.diagramm__achse--x { text-anchor: middle; }

/* Die Luecke. Die Flaeche verstaerkt, der Streifen unter der Nulllinie traegt:
   Eine Flaeche hinter den Daten, die selbst 3.0 haelt, macht die Linie darauf
   unlesbar (--akzent-dunkel auf --linie-stark waeren 2.03). */
.diagramm__luecke { fill: var(--linie); }
.diagramm__lueckenstrich { fill: var(--diagramm-linie); }

/* Balken: #50C878 als Datenfarbe, aber der Rand in --akzent-dunkel haelt die
   3.0. Ohne Rand waeren die Balken im hellen Modus 2.13 gegen Weiss — sichtbar
   fuer die meisten, unsichtbar fuer einige. */
.diagramm__balken {
  fill: var(--akzent);
  stroke: var(--akzent-dunkel);
  stroke-width: .75;
}

.diagramm__linie { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }

/* Zwei Reihen, unterscheidbar OHNE Farbe: durchgezogen mit runden Punkten gegen
   gestrichelt mit eckigen. Zwei Linien, die sich nur im Farbton unterscheiden,
   sind fuer etwa jeden zwoelften Mann eine Linie. Die Legende zeigt beide
   Formen. */
.diagramm__reihe--1 .diagramm__linie { stroke: var(--akzent-dunkel); }
.diagramm__reihe--1 .diagramm__punkt { fill: var(--akzent-dunkel); }
.diagramm__reihe--2 .diagramm__linie {
  stroke: var(--text-leise);
  stroke-dasharray: 6 4;
}
.diagramm__reihe--2 .diagramm__punkt { fill: var(--text-leise); }

.diagramm__legende {
  list-style: none;
  margin: .5rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1.25rem;
  font-size: .85rem;
  color: var(--text-leise);
}
.diagramm__legende li { display: flex; align-items: center; gap: .4rem; }
.legende__probe { width: 30px; height: 12px; flex: none; }

/* Kein leeres Achsenkreuz. Ein Diagramm ohne Daten sieht kaputt aus; ein Satz,
   der sagt, was passieren muss, ist eine Auskunft. */
.diagramm__grund {
  background: var(--flaeche-2);
  border: 1px dashed var(--linie-stark);
  border-radius: var(--radius-klein);
  padding: 1.25rem;
  color: var(--text-leise);
  font-size: .9rem;
  max-width: 46rem;
}

/* Die Zahlen zum Diagramm. Zusammengeklappt, weil 365 Tageszeilen die Seite
   sonst zerreissen — aber immer im Dokument und damit fuer einen Screenreader
   erreichbar. Ein SVG ohne diese Tabelle waere ein leeres Bild. */
.diagramm__zahlen { margin-top: .75rem; }
.diagramm__zahlen > summary {
  cursor: pointer;
  font-size: .85rem;
  color: var(--text-leise);
  min-height: 2rem;
  display: flex;
  align-items: center;
}
.diagramm__zahlen[open] > summary { margin-bottom: .5rem; }
.diagramm__zahlen .tabelle-huelle { max-height: 26rem; overflow-y: auto; }
.diagramm__zahlen tfoot th, .diagramm__zahlen tfoot td {
  border-top: 2px solid var(--linie-stark);
  font-weight: 600;
}

/* ----------------------------------------------------------------- Listchen */

.zielseiten, .stoerungen {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: .85rem;
}
.zielseiten li, .stoerungen li { margin-bottom: .2rem; }

.grenzenliste { margin: 0; padding-left: 1.2rem; max-width: 46rem; }
.grenzenliste li { margin-bottom: .5rem; }
