/* ==========================================================================
   EveryLingua — das ganze Aussehen in einer Datei.

   Aufbau:
     1. Farbwerte und Masse (die einzige Stelle, an der Farben stehen)
     2. Grundlagen und Schrift
     3. Kopf, Navigation, Fuss
     4. Bausteine: Knoepfe, Karten, Kaesten
     5. Startseite
     6. Stufen und Grammatik
     7. Ueben
     8. Auswertung
     9. Kleinigkeiten, Druck, Ruecksicht

   Zwei Farbfassungen, drei Zustaende: ohne gespeicherte Wahl folgt die Seite
   dem System, mit Wahl gilt die Wahl — in beide Richtungen. Deshalb ist die
   Medienabfrage als :root:not([data-thema="hell"]) geschrieben und nicht
   einfach ohne Erwaehnung der hellen Fassung: Wer auf einem dunklen System
   sitzt und diese Seite hell will, hat das gesagt.
   ========================================================================== */

/* --- 1. Werte ----------------------------------------------------------- */

:root {
  /* Helle Fassung — der Normalfall. Eine Lernseite wird am Tag benutzt.

     Der Grund war lange ein kuehles Blaugrau (#eaedf2). Das ist eine
     saubere Farbe und eine unfreundliche: Blaugrau ist die Farbe von
     Verwaltungssoftware, und wer eine Stunde Vokabeln lernt, sitzt eine
     Stunde davor. Jetzt ist es ein warmes Beige — heller als vorher
     (Leuchtdichte 0.867 gegen 0.845), spuerbar warm (Buntheit 0.071 gegen
     0.031) und weit unter dem, was als Farbflaeche statt als Papier
     gelesen wird.

     Warm heisst hier nicht nur der Grund. Eine blaugraue Schrift auf
     Beige sieht schmutzig aus, weil zwei Farbtemperaturen aufeinander
     liegen; die Tinten sind deshalb mitgewandert, von Blauschwarz zu
     einem sehr dunklen Braunschwarz. Dasselbe gilt fuer die Schatten und
     den Schein: Ein blauer Schatten auf Beige ist ein grauer Fleck.

     Alle Werte sind gerechnet und nicht geschaetzt — die stillste Tinte
     steht bei 6.47:1 auf dem Grund, wo 4.5 gefordert sind. Nachgerechnet
     wird bei jedem Lauf von `thema`, und zwar gegen das, was wirklich
     dahinterliegt, das gemalte Canvas eingeschlossen. */
  --bg:        #f5efe3;   /* warmes Papier, kein Weiss und kein Grau */
  --bg-tief:   #ebe3d3;   /* Vertiefungen */
  --karte:     #fdfaf4;
  --karte-2:   #f9f4ea;
  --linie:     #e6dcc9;
  --flaeche-umriss: #b98d4e;
  --linie-kraeftig: #cdbfa6;

  --ink:       #1e1913;   /* Braunschwarz statt Blauschwarz */
  --ink-2:     #4a4136;
  --ink-3:     #5e5447;

  --marke:     #0f7160;   /* ruhiges Gruen — Fortschritt, nicht Alarm */
  --marke-ink: #0d6152;
  --marke-weich: #dcece6;
  --akzent:    #a95d1e;   /* warmer Gegenpol fuer Hinweise */
  --akzent-ink:#8d4a17;
  --akzent-weich: #f6e6d3;

  --knopf-ink: #ffffff;   /* Schrift auf der gefuellten Flaeche */
  --ok:        #0f7160;
  --ok-ink:    #0d6152;
  --ok-weich:  #dcece6;
  --fehler:    #a3342f;
  --fehler-weich: #f7e0dc;
  --warn:      #7d5606;
  --warn-weich: #f6ecd6;

  --tint: 62, 48, 28;     /* woraus zarte Flaechen gemischt werden — warm */
  --schatten-1: 0 1px 2px rgba(74, 56, 30, .07), 0 2px 8px rgba(74, 56, 30, .05);
  --schatten-2: 0 2px 4px rgba(74, 56, 30, .08), 0 8px 22px rgba(74, 56, 30, .09);
  --schatten-3: 0 4px 8px rgba(74, 56, 30, .09), 0 18px 42px rgba(74, 56, 30, .14);

  /* Der Feinschliff: Schein und Anhebung.

     Getrennt von den Schatten, weil sie zwei verschiedene Dinge tun. Ein
     Schatten sagt, dass etwas ueber dem Grund liegt. Ein Schein sagt, dass
     es lebt — und er ist auf Papier fast nichts und auf dunklem Grund fast
     alles, weil ein Schein dort das Einzige ist, was einen Rand sichtbar
     macht. Deshalb sind es Token und keine festen Werte.

     `--glanz` ist die Farbe des Scheins. Sie ist nicht --marke: Ein Schein
     im Markenton faerbt jede Karte gruen, und die elf Kategoriefarben
     haetten dann eine gemeinsame Truebung. Sie ist ein sehr blasses Blau
     aus dem Grundton, und die Kategoriekarten setzen sie per
     --stufe-farbe selbst um.

     `--saum` ist der Lichtsaum an der Oberkante einer Flaeche — eine
     Zeile, die auf Papier aus Weiss und auf dunklem Grund aus einem
     Hauch Weiss besteht. Das ist der Unterschied zwischen „Kasten mit
     Rahmen" und „Karte, die liegt", und er kostet einen Wert. */
  /* Der Schein war blau. Auf Beige ist ein blauer Schein ein grauer
     Fleck — er nimmt der Flaeche genau die Waerme, wegen der sie gewaehlt
     wurde. Jetzt ein warmes Gold, das dasselbe tut und nichts kuehlt. */
  --glanz: 150, 112, 48;
  --halo: 0 0 18px -10px rgba(var(--glanz), .30);
  --halo-hi: 0 0 26px -8px rgba(var(--glanz), .42), 0 0 0 3px rgba(var(--glanz), .10);

  /* --- Glas ------------------------------------------------------------
     Die grossen Kaesten stehen nicht mehr auf einer deckenden Flaeche,
     sondern auf einer durchscheinenden mit Unschaerfe darunter. Damit
     laeuft der Hintergrund sichtbar durch sie hindurch, ohne dass der
     Text darauf schwerer zu lesen waere: Was die Lesbarkeit traegt, ist
     die Deckung — 0,78 ist matt genug, dass kein Wort des Hintergrunds
     durch eine Zeile laeuft — und was die Tiefe macht, ist die
     Unschaerfe. Beides ist getrennt einstellbar, und nur eines davon
     darf man erhoehen, ohne zu messen.

     Die Zahl wurde nicht geschaetzt: `pruefen.sh thema` misst jeden Text
     gegen das, was wirklich hinter ihm liegt, einschliesslich des
     Pixels, den die Flaeche dort gemalt hat. */
  --glas: 253, 250, 244;
  --glas-deckung: .78;
  --glas-unschaerfe: 14px;
  --glas-saettigung: 1.35;
  --glas-saum: inset 0 1px 0 rgba(255, 255, 255, .75);
  --lift: 0 1px 2px rgba(74, 56, 30, .06);
  --lift-hi: 0 6px 18px -6px rgba(74, 56, 30, .20);
  --saum: inset 0 1px 0 rgba(255, 255, 255, .7);

  /* Der Schein — ein weissliches Licht auf den Flaechen, die auf der Seite
     liegen. Zwei Teile, weil ein Glow zwei Dinge tut: Er legt Licht AUF die
     Flaeche und einen Hof UM sie herum.

     Der Hof ist auf Papier nichts wert: Ein weisser Schimmer neben einer
     fast weissen Seite ist unsichtbar, und wer ihn trotzdem aufdreht,
     bekommt keinen Glanz, sondern Matsch. Auf Papier arbeitet deshalb nur
     das Licht auf der Flaeche, und es macht aus einer flachen Karte eine
     leicht gewoelbte.

     Der Verlauf ist ein background-image, und den sieht `thema` nicht — es
     misst background-color. Also wurde er von Hand gerechnet: Im
     unguenstigsten Fall, ganz oben am Rand, steigt der Kontrast auf Papier
     sogar (7,11 auf 7,35 bei der leisesten Schrift). */
  --schein: linear-gradient(180deg,
              rgba(255, 255, 255, .85) 0%,
              rgba(255, 255, 255, .28) 34%,
              rgba(255, 255, 255, 0) 68%);
  --schein-hof: 0 0 0 0 rgba(255, 255, 255, 0);
  --schein-hof-hi: 0 0 0 0 rgba(255, 255, 255, 0);
  --ring: 0 0 0 3px color-mix(in srgb, var(--marke) 30%, transparent);

  --rund-s: 8px;
  --rund:   14px;
  --rund-l: 22px;
  --rund-voll: 999px;

  --breite: 74rem;
  --lesebreite: 39rem;    /* rund 72 Zeichen — das Lesemass */

  /* Zwei Familien, beide OFL, beide lokal. Warum genau diese: siehe
     assets/fonts/LIZENZ.txt — die Wahl folgt fuenf Anforderungen, die
     man an einer Schriftdatei nachsehen kann, und nicht dem Geschmack.
     "Plex Sans" heisst hier so, weil der Familienname der Datei
     "IBM Plex Sans" ist und der reservierte Name "Plex" lautet; die
     Datei ist unveraendert. */
  --moduswahl-kraft: 1;
  --schrift: "Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --schrift-titel: "Literata", Georgia, "Times New Roman", serif;

  --schleier-oben: .08;
  --schleier-rand: .30;

  /* Muno, das Chamäleon — die Ruhefassung.

     Warum ein Chamäleon, warum im Profil und woher die Farben je Sprache
     kommen, steht im Kopf von tools/maskottchen.py. Diese Werte stehen
     dort noch einmal, weil das Markenzeichen ohne Stylesheet gezeichnet
     werden muss — ein Favicon hat keins. Die Prüfgruppe `maskottchen`
     liest beide Seiten und fällt über jede Abweichung.

     Zehn Töne und nicht sechs: Eine flache Fläche in Flaggenrot ist ein
     Warnschild; eine Fläche mit Licht oben, Schatten unten, hellem Bauch
     und einer Bänderung darüber ist eine Haut. Es sind nicht andere
     Farben als vorher, sondern mehr Töne aus derselben Farbe — und jeder
     an der Stelle, an der Licht ihn hinlegen würde.

     Sie gelten, solange keine Sprache im Spiel ist: auf der Startseite,
     im Impressum, überall ohne data-paar. Ein Chamäleon in Ruhe ist
     grün, und Grün ist unter den fünf Sprachfarben die einzige, die
     nicht wie eine sechste Sprache aussieht. Ausdrücklich **nicht** das
     Grün der Seite: Ein Maskottchen im Markenton liest sich als
     Bedienelement, und Muno soll eine Figur sein und kein Knopf. */
  --mu-ast:        #7a6248;
  --mu-ast-tief:   #54432f;
  --mu-auge:       #1d2a1b;
  --mu-hut:        #39415a;
  --mu-hut-tief:   #242a3c;
  --mu-glanz:      #ffffff;

  /* Die sechs Stufenfarben, damit der Hintergrund sie zeichnen kann.

     Sie stehen im Inhalt — inhalt/stufen.json —, und hier steht eine
     zweite Fassung davon. Zwei Fassungen laufen auseinander, und deshalb
     hält `tools/hintergrund_pruefen.py` sie bei jedem Lauf gegeneinander:
     Wer eine Stufenfarbe ändert und diese Zeilen vergisst, bekommt eine
     Leiter in den Farben von gestern.

     Warum nicht aus einer Datei gelesen: Der Hintergrund liegt auf jeder
     Seite und holt nichts aus dem Netz. Eine Datendatei für sechs
     Farbwerte wäre eine Anfrage für 120 Byte. */
  /* Wie kräftig die Leiter im Hintergrund höchstens gemalt wird — und das
     ist keine Geschmacksfrage, sondern eine gerechnete Grenze.

     Über Papier verdunkelt jede Farbe den Grund, und Text, der darüber
     steht, verliert genau so viel Kontrast. Nachgerechnet gegen --ink-3,
     die leiseste Schrift der Seite: Bei 0,15 Deckkraft einer Stufenfarbe
     bleiben die geforderten 4,5:1 gerade eben stehen, darüber nicht mehr.
     Auf dunklem Grund liegt die Grenze bei 0,19 — nicht höher, weil
     dort mehr ginge, sondern weil dort weniger geht, als lange
     dastand. Der frühere Wert war 0,33, und der war schon vor dem
     Farbwechsel falsch: Nachgerechnet steht --ink-3 über der
     A1-Sprosse bei 0,33 auf 3,39:1 statt auf den geforderten 4,5.
     Gefunden hat das kein Blick, sondern die Rechnung — und die
     Browserprüfung nicht, weil sie einen Augenblick misst und die
     unterste Sprosse selten hinter Text steht. Die Grenze wird
     deshalb jetzt gerechnet und nicht mehr geschätzt:
     tools/farben_pruefen.py legt jede der sechs Stufenfarben bei
     der eingetragenen Deckkraft über den Grund und misst --ink-3
     darüber.

     Das ist die Zahl, die dieser Hintergrund nicht überschreiten darf, und
     `grundflaeche.js` deckelt alles daran — Sprossen, Holme, Lichtpunkte
     und Wörter. Der frühere Entwurf malte kräftiger und kam damit durch,
     weil tools/thema_pruefen.mjs einen Augenblick misst und in diesem
     Augenblick zufällig kein Wort hinter dem Vorspann stand. Eine Prüfung,
     die vom Zufall abhängt, ist keine.

     Der Gegenzug steht direkt darunter: Weil der Schleier über der Bühne
     fast weg ist, kommt von diesen 0,15 auch fast alles an. Vorher lagen
     0,62 auf dem Canvas und ein Schleier von 0,55 darüber — doppelt so viel
     gemalt, halb so viel zu sehen, und die Prüfung sieht den Schleier nicht. */
  --flaeche-kraft: .15;

  --stufe-a1: #307846;
  --stufe-a2: #267287;
  --stufe-b1: #3168bd;
  --stufe-b2: #675cc3;
  --stufe-c1: #985b34;
  --stufe-c2: #8d4a66;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-thema="hell"]) {
    --moduswahl-kraft: 1.6;
    --bg:        #0e1319;
    --bg-tief:   #090d12;
    --karte:     #171e26;
    --karte-2:   #1d262f;
    --linie:     #28323d;
    --flaeche-umriss: #7a6a4e;
    --linie-kraeftig: #384652;

    --ink:       #e9eef3;
    --ink-2:     #b4c1cc;
    --ink-3:     #8d9ca9;

    --marke:     #45c3a4;
    --marke-ink: #5cd3b4;
    --marke-weich: #113029;
    --akzent:    #e59a5f;
    --akzent-ink:#efab72;
    --akzent-weich: #33241a;

    --knopf-ink: #06201a;
    --ok:        #45c3a4;
    --ok-ink:    #45c3a4;
    --ok-weich:  #113029;
    --fehler:    #f0918a;
    --fehler-weich: #351f1e;
    --warn:      #e0b562;
    --warn-weich: #2f2716;

    --tint: 255, 255, 255;
    --schatten-1: 0 1px 2px rgba(0, 0, 0, .34);
    --schatten-2: 0 2px 6px rgba(0, 0, 0, .38), 0 10px 26px rgba(0, 0, 0, .32);
    --schatten-3: 0 6px 14px rgba(0, 0, 0, .44), 0 22px 50px rgba(0, 0, 0, .4);

    /* Auf dunklem Grund traegt der Schein fast allein. Ein Schatten unter
       einer dunklen Karte auf dunklem Grund ist nicht zu sehen; ein
       heller Saum an ihrer Oberkante schon. */
    --glanz: 150, 210, 255;
    --halo: 0 0 24px -12px rgba(var(--glanz), .34), 0 0 0 1px rgba(var(--glanz), .05);
    --halo-hi: 0 0 34px -6px rgba(var(--glanz), .48), 0 0 0 1px rgba(var(--glanz), .14);

    --glas: 23, 30, 38;
    --glas-deckung: .70;
    --glas-unschaerfe: 16px;
    --glas-saettigung: 1.25;
    --glas-saum: inset 0 1px 0 rgba(255, 255, 255, .07);
    --lift: 0 1px 2px rgba(0, 0, 0, .3);
    --lift-hi: 0 8px 22px -8px rgba(0, 0, 0, .55);
    --saum: inset 0 1px 0 rgba(255, 255, 255, .06);

    /* Hier zaehlt beides: Das Licht auf der Flaeche hebt die Karte vom
       Grund ab, der Hof legt einen weichen Schimmer darum. Fuenf Prozent
       Weiss ganz oben sind der unguenstigste Punkt des Verlaufs, und dort
       faellt die leiseste Schrift von 6,79 auf 5,84 — mit Abstand ueber
       4,5. Der Fliesstext steht unterhalb der Blende, wo fast nichts mehr
       ankommt. */
    --schein: linear-gradient(180deg,
                rgba(255, 255, 255, .05) 0%,
                rgba(255, 255, 255, .016) 40%,
                rgba(255, 255, 255, 0) 75%);
    --schein-hof: 0 0 18px -14px rgba(255, 255, 255, .35);
    --schein-hof-hi: 0 0 30px -12px rgba(255, 255, 255, .5);
    --ring: 0 0 0 3px color-mix(in srgb, var(--marke) 34%, transparent);

    --schleier-oben: .10;
    --schleier-rand: .34;

    /* Muno auf der dunklen Fassung. Die Haut wird eine Spur heller,
     damit die Figur nicht im Grund versinkt. Einfach zu invertieren
     käme nicht in Frage — dann wäre es ein anderes Tier.

     Die Sprachfarben weiter unten bekommen **keine** zweite Fassung:
     Sie sind aus Flaggentönen gerechnet und liegen schon in der Mitte,
     wo sie auf beiden Gründen tragen.

     Dieser Absatz stand hier von Anfang an — und er beschrieb, was
     gemeint war, nicht was geschah. Dieser Block setzte die `--mu-*`
     mit, alle, und unter einem Selektor mit zwei Merkmalen. Der
     Sprachblock `[data-mufarbe="de-fr"]` hat eines. Also gewann dieser
     hier, und Muno war auf der dunklen Fassung in jeder Sprache grün.
     `thema` hat es nicht gemerkt: Es misst Kontrast, und Grün auf
     Dunkel hat Kontrast.

     Darum stehen hier nur noch die fünf Töne, die dem Bild gehören und
     nicht dem Kurs — Ast, Zweig, Pupille und der Doktorhut. Alles, was
     mit der Sprache wechselt, steht ausschließlich in einem
     `[data-mufarbe]`-Block, die Ruhefassung eingeschlossen, und
     `maskottchen` fällt über jede Ausnahme. */
  --mu-ast:        #8a7053;
  --mu-ast-tief:   #5f4d37;
  --mu-auge:       #16200f;
  --mu-hut:        #5b6688;
  --mu-hut-tief:   #3f4763;
  --mu-glanz:      #ffffff;
    /* Die sechs Stufenfarben der Leiter im Hintergrund, fuer die dunkle
       Fassung aufgehellt — dieselbe Mischung wie --stufe-ink: 62 % Farbe
       auf Weiss. Die hellen Werte sind fuer Papier gewaehlt; bei den
       Deckkraeften, die dieser Hintergrund fahren darf, waere ein
       dunkles Blau auf dunklem Grund schlicht nicht da.
       tools/hintergrund_pruefen.py rechnet beide Fassungen gegen
       inhalt/stufen.json nach. */
    --flaeche-kraft: .19;

    --stufe-a1: #7fab8c;
    --stufe-a2: #78a8b5;
    --stufe-b1: #7fa1d6;
    --stufe-b2: #a19ada;
    --stufe-c1: #bf9981;
    --stufe-c2: #b88fa0;

    color-scheme: dark;
  }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-thema="hell"]) * {
    --stufe-ink: color-mix(in srgb, var(--stufe-farbe, var(--marke)) 62%, #fff);
  }
}
:root[data-thema="dunkel"] * {
  --stufe-ink: color-mix(in srgb, var(--stufe-farbe, var(--marke)) 62%, #fff);
}

:root[data-thema="dunkel"] {
    --moduswahl-kraft: 1.6;
  --bg:        #0e1319;
  --bg-tief:   #090d12;
  --karte:     #171e26;
  --karte-2:   #1d262f;
  --linie:     #28323d;
  --flaeche-umriss: #7a6a4e;
  --linie-kraeftig: #384652;

  --ink:       #e9eef3;
  --ink-2:     #b4c1cc;
  --ink-3:     #8d9ca9;

  --marke:     #45c3a4;
  --marke-ink: #5cd3b4;
  --marke-weich: #113029;
  --akzent:    #e59a5f;
  --akzent-ink:#efab72;
  --akzent-weich: #33241a;

  --knopf-ink: #06201a;
  --ok:        #45c3a4;
  --ok-ink:    #45c3a4;
  --ok-weich:  #113029;
  --fehler:    #f0918a;
  --fehler-weich: #351f1e;
  --warn:      #e0b562;
  --warn-weich: #2f2716;

  --tint: 255, 255, 255;
  --schatten-1: 0 1px 2px rgba(0, 0, 0, .34);
  --schatten-2: 0 2px 6px rgba(0, 0, 0, .38), 0 10px 26px rgba(0, 0, 0, .32);
  --schatten-3: 0 6px 14px rgba(0, 0, 0, .44), 0 22px 50px rgba(0, 0, 0, .4);

  /* Wortgleich mit der Medienabfrage darüber — und schon wieder ist es
     hier vergessen worden.

     Als der Schein verstärkt und das Glas eingeführt wurde, bekam nur der
     `@media`-Block die neuen Werte. Wer auf einem hellen System die dunkle
     Fassung ausdrücklich wählt, sah den alten, matten Schein und gar kein
     Glas: `--glas` und seine vier Geschwister waren dort nicht gesetzt,
     also blieb `rgba(var(--glas), …)` ungültig. Gemeldet hat es
     `fassungen`, die Gruppe, die genau diese beiden Blöcke gegeneinander
     hält — direkt unter einem Kommentar, der dieselbe Lehre schon einmal
     festhält. Zwei Blöcke, die dasselbe sagen müssen, sind eine Stelle zum
     Vergessen, und sie wird auch benutzt. */
  --glanz: 150, 210, 255;
  --halo: 0 0 24px -12px rgba(var(--glanz), .34), 0 0 0 1px rgba(var(--glanz), .05);
  --halo-hi: 0 0 34px -6px rgba(var(--glanz), .48), 0 0 0 1px rgba(var(--glanz), .14);

  --glas: 23, 30, 38;
  --glas-deckung: .70;
  --glas-unschaerfe: 16px;
  --glas-saettigung: 1.25;
  --glas-saum: inset 0 1px 0 rgba(255, 255, 255, .07);
  --lift: 0 1px 2px rgba(0, 0, 0, .3);
  --lift-hi: 0 8px 22px -8px rgba(0, 0, 0, .55);
  --saum: inset 0 1px 0 rgba(255, 255, 255, .06);

  /* Dieselbe Blende wie in der Medienabfrage darueber. Sie stand dort
     allein, und damit bekam sie genau der nicht, der sie ausdruecklich
     gewaehlt hat: Wer auf einem hellen System die dunkle Fassung
     einschaltet, sah Karten ohne Licht darauf. Die Fassungspruefung liest
     beide Bloecke und meldet jedes Merkmal, das nur in einem steht. */
  --schein: linear-gradient(180deg,
              rgba(255, 255, 255, .05) 0%,
              rgba(255, 255, 255, .016) 40%,
              rgba(255, 255, 255, 0) 75%);
  --schein-hof: 0 0 18px -14px rgba(255, 255, 255, .35);
  --schein-hof-hi: 0 0 30px -12px rgba(255, 255, 255, .5);
  --ring: 0 0 0 3px color-mix(in srgb, var(--marke) 34%, transparent);

  --schleier-oben: .10;
  --schleier-rand: .34;

  /* Muno auf der dunklen Fassung. Die Haut wird eine Spur heller, damit
     die Figur nicht im Grund versinkt. Einfach zu invertieren käme nicht
     in Frage — dann wäre es ein anderes Tier.

     Die Sprachfarben weiter unten bekommen **keine** zweite Fassung, und
     das ist Absicht: Sie sind aus Flaggentönen gerechnet und liegen
     schon in der Mitte, wo sie auf beiden Gründen tragen. Eine zweite
     Fassung wäre eine zweite Stelle zum Vergessen — und die Prüfgruppe
     `thema` misst auf beiden Fassungen, würde es also merken. */
  --mu-ast:        #8a7053;
  --mu-ast-tief:   #5f4d37;
  --mu-auge:       #16200f;
  --mu-hut:        #5b6688;
  --mu-hut-tief:   #3f4763;
  --mu-glanz:      #ffffff;
  /* Die sechs Stufenfarben der Leiter im Hintergrund, fuer die dunkle
     Fassung aufgehellt — dieselbe Mischung wie --stufe-ink: 62 % Farbe
     auf Weiss. Die hellen Werte sind fuer Papier gewaehlt; bei den
     Deckkraeften, die dieser Hintergrund fahren darf, waere ein
     dunkles Blau auf dunklem Grund schlicht nicht da.
     tools/hintergrund_pruefen.py rechnet beide Fassungen gegen
     inhalt/stufen.json nach. */
  --flaeche-kraft: .19;

  --stufe-a1: #7fab8c;
  --stufe-a2: #78a8b5;
  --stufe-b1: #7fa1d6;
  --stufe-b2: #a19ada;
  --stufe-c1: #bf9981;
  --stufe-c2: #b88fa0;

  color-scheme: dark;
}

/* --- Schriften ----------------------------------------------------------
   Lokal ausgeliefert. Eine Einbindung ueber fonts.googleapis.com wuerde bei
   jedem Aufruf die IP-Adresse des Besuchers an einen Dritten uebertragen;
   siehe assets/fonts/LIZENZ.txt.                                          */

@font-face {
  font-family: "Plex Sans";
  src: url("../fonts/plex-sans-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: "Plex Sans";
  src: url("../fonts/plex-sans-latin-ext.woff2") format("woff2");
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
                 U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Plex Sans";
  src: url("../fonts/plex-sans-latin-italic.woff2") format("woff2");
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: "Plex Sans";
  src: url("../fonts/plex-sans-latin-ext-italic.woff2") format("woff2");
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
                 U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Literata";
  src: url("../fonts/literata-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: "Literata";
  src: url("../fonts/literata-latin-ext.woff2") format("woff2");
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
                 U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Literata";
  src: url("../fonts/literata-latin-italic.woff2") format("woff2");
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: "Literata";
  src: url("../fonts/literata-latin-ext-italic.woff2") format("woff2");
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
                 U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- 2. Grundlagen ------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

/* `hidden` ist eine Aussage und keine Verzierung — es hat Vorrang.
 *
 * Der Browser bringt zwar `[hidden] { display: none }` mit, aber jede eigene
 * Regel mit einem `display` schlaegt sie: Autorregeln stehen ueber denen des
 * Browsers. Genau das ist passiert. `.modus { display: block }` liess den
 * Hoermodus sichtbar, obwohl das Skript ihn ausdruecklich versteckt hatte —
 * ein Modus ohne Sprachausgabe, der beim Anfassen stumm geblieben waere.
 *
 * Gefunden hat es nicht das Auge, sondern tools/uebungen_pruefen.mjs mit
 * einem Browser ohne englische Stimme.
 *
 * `!important` ist hier nicht Gewalt, sondern die Bedeutung des Attributs:
 * Wer `hidden` setzt, sagt „das ist nicht da", und keine Layoutregel darf
 * dem widersprechen. Wer ein verstecktes Element zeigen will, nimmt das
 * Attribut weg — und tut damit genau das, was er meint. */
[hidden] { display: none !important; }

/* Ein Pastellton ist keine Textfarbe.
   Die sechs Stufenfarben sind als Akzent gewaehlt — als Fuellung, als Rand,
   als Balken. Als Schrift auf Papier liegen sie zwischen 3,0 und 4,2 zu eins
   und damit unter dem, was lesbar heisst; gemessen von tools/thema_pruefen.mjs.
   Deshalb gibt es zu jeder eine abgedunkelte Fassung fuer Schrift.

   Die Regel steht auf * und nicht auf :root, weil --stufe-farbe als
   Inline-Eigenschaft je Karte hereinkommt und pro Element neu gerechnet
   werden muss. Auf :root waere sie einmal berechnet und ueberall gleich. */
* {
  --stufe-ink: color-mix(in srgb, var(--stufe-farbe, var(--marke)) 62%, #000);
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--schrift);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  /* Deutsch hat Woerter wie „Possessivpronomen" und
     „Verlaufsform der Vergangenheit". Auf 320 Pixeln passt ein solches Wort
     nicht in eine Zeile, und ohne Trennung schiebt es die ganze Seite nach
     rechts — auf elf Seiten gleichzeitig, gefunden von tools/layout_pruefen.mjs.
     overflow-wrap greift nur im Notfall, hyphens trennt vorher an einer
     sinnvollen Stelle. */
  overflow-wrap: break-word;
  hyphens: auto;
}

h1, h2, h3, h4 {
  font-family: var(--schrift-titel);
  color: var(--ink);
  line-height: 1.2;
  margin: 0 0 .5em;
  font-weight: 600;
  letter-spacing: -.01em;
}
h1 { font-size: clamp(1.85rem, 1.35rem + 2.1vw, 3rem); font-variation-settings: "opsz" 48; }
h2 { font-size: clamp(1.4rem, 1.15rem + 1.1vw, 2rem);  font-variation-settings: "opsz" 32; margin-top: 2.2em; }
h3 { font-size: 1.2rem; font-variation-settings: "opsz" 20; margin-top: 1.8em; }
h4 { font-size: 1rem; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--marke-ink); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--ink); }

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

code, kbd, .ziel {
  font-feature-settings: "tnum" 0;
}

.huelle {
  width: 100%;
  max-width: var(--breite);
  margin: 0 auto;
  padding: 0 1.15rem;
}

.lesespalte { max-width: var(--lesebreite); }

/* --- Das Lesemaß, wo Fließtext steht --------------------------------------

   `--breite` ist 74rem und richtig für ein Raster aus Karten. Für einen
   Absatz ist es das nicht: Gemessen liefen Absätze in Karten auf einem
   breiten Schirm über 1100 Pixel, also gut das Anderthalbfache dessen, was
   ein Auge in einer Zeile noch bequem zurückverfolgt. Am Zeilenende
   angekommen findet man den Anfang der nächsten nicht mehr.

   Die Regel greift an direkten Kindern und nicht mit `main p`: Ein Absatz
   in einer Tabellenzelle, in einer Knopfreihe oder in einem Rasterfeld ist
   kein Fließtext, und dort wäre eine Grenze von 39rem eine willkürliche
   Verengung. Auf dem Telefon ändert das alles hier gar nichts — dort war
   die Breite nie das Problem. */
.karte > p, .kasten > p, .karte > ul, .kasten > ul,
.anf-warum, .anf-vokabeln {
  max-width: var(--lesebreite);
}

/* Die Rollleiste bekommt ihren Platz, auch wenn sie gerade fehlt.
   Ohne das haengt die *Breite* der Seite an ihrer *Hoehe*: Wird der Inhalt
   um wenige Pixel hoeher als das Fenster, erscheint die senkrechte
   Rollleiste, das Fenster wird fuenfzehn Pixel schmaler, und alles
   Zentrierte rutscht. Auf der Startseite passiert das im Takt der
   Vorfuehrung, die alle paar Sekunden eine andere Szene zeigt — der Kasten
   wird hoeher, die Leiste kommt, der Kasten wird flacher, sie geht.
   Sichtbar war das als ein Versatz der ganzen Seite alle paar Sekunden.
   Und es war zugleich die Ursache des Flackerns im Hintergrund: Jede
   dieser Breitenaenderungen loeste `resize` aus. */
html { scrollbar-gutter: stable; }

main { min-height: 60vh; padding-bottom: 4rem; }

.sprungmarke {
  position: absolute; left: -999px; top: 0; z-index: 100;
  background: var(--marke); color: #fff; padding: .7rem 1.1rem;
  border-radius: 0 0 var(--rund-s) 0;
}
.sprungmarke:focus { left: 0; }

.nur-vorlesen {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* --- 3. Kopf und Fuss ---------------------------------------------------- */

.kopf {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(12px) saturate(1.3);
  -webkit-backdrop-filter: blur(12px) saturate(1.3);
  border-bottom: 1px solid transparent;
  transition: border-color .2s, box-shadow .2s;
}
.kopf[data-gescrollt="ja"] {
  border-bottom-color: var(--linie);
  box-shadow: var(--schatten-1);
}
.kopf-innen {
  display: flex; align-items: center; gap: 1rem;
  min-height: 4rem;
}

/* Der Innenabstand ist nicht Kosmetik: Ohne ihn ist die Marke genau so hoch
   wie ihr Zeichen, also 30 Pixel, und damit knapp unter dem, was ein Daumen
   sicher trifft. */
.marke {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--schrift-titel); font-weight: 600; font-size: 1.15rem;
  color: var(--ink); text-decoration: none; flex: none;
  padding: .2rem 0;
}
.marke svg { width: 30px; height: 30px; flex: none; }
.marke:hover { color: var(--marke-ink); }

.navi-schalter {
  margin-left: auto; display: none;
  background: none; border: 1px solid var(--linie); color: var(--ink);
  border-radius: var(--rund-s); padding: .45rem; cursor: pointer;
}
.navi-schalter svg { width: 22px; height: 22px; display: block; }

.hauptnavi {
  margin-left: auto;
  display: flex; align-items: center; gap: .15rem; flex-wrap: wrap;
}
.hauptnavi > a {
  color: var(--ink-2); text-decoration: none;
  padding: .45rem .7rem; border-radius: var(--rund-voll);
  font-size: .95rem; white-space: nowrap;
}
.hauptnavi > a:hover { background: var(--bg-tief); color: var(--ink); }
.hauptnavi > a[aria-current="page"] {
  background: var(--marke-weich); color: var(--marke-ink); font-weight: 600;
}
.navi-werkzeuge { display: inline-flex; gap: .3rem; margin-left: .4rem; }

.knopf-still {
  display: inline-flex; align-items: center; gap: .35rem;
  background: none; border: 1px solid var(--linie); color: var(--ink-2);
  border-radius: var(--rund-voll); padding: .4rem .6rem;
  cursor: pointer; font: inherit; font-size: .9rem; text-decoration: none;
}
.knopf-still:hover { border-color: var(--linie-kraeftig); color: var(--ink); }
.knopf-still svg { width: 18px; height: 18px; }
.thema-wort { font-size: .85rem; }

.fuss {
  border-top: 1px solid var(--linie);
  background: var(--bg-tief);
  padding: 2.6rem 0 2rem;
  font-size: .93rem;
  color: var(--ink-2);
}
.fuss-raster {
  display: grid; gap: 1.8rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.fuss h4 {
  font-family: var(--schrift); font-size: .78rem; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: .7rem;
}
.fuss ul { list-style: none; margin: 0; padding: 0; }
.fuss li { margin-bottom: .15rem; }
/* Gemessen waren die Verweise hier 18 Pixel hoch — die Höhe der Zeile und
   sonst nichts. Auf einem Telefon ist das kein Ziel, das man trifft, es ist
   eines, das man beim dritten Versuch trifft. `inline-block` plus etwas
   Innenabstand macht daraus ein Ziel von gut zweiunddreißig Pixeln, ohne
   dass sich am Aussehen etwas ändert: Der Abstand zwischen den Zeilen
   schrumpft um genau so viel, wie das Ziel wächst. */
.fuss a {
  color: var(--ink-2); text-decoration: none;
  display: inline-block; padding: .38rem 0;
}
.fuss a:hover { color: var(--marke-ink); text-decoration: underline; }
.fuss-schluss {
  margin-top: 2rem; padding-top: 1.2rem; border-top: 1px solid var(--linie);
  display: flex; flex-wrap: wrap; gap: .6rem 1.6rem;
  font-size: .87rem; color: var(--ink-3);
}
/* Der Herausgeber steht neben dem Namen der Seite und nicht im Fliesstext
   der Schlusszeile: „Ein Projekt von DELISORIA" ist eine Angabe ueber die
   Herkunft und kein Hinweis darauf, was die Seite ist. Etwas mehr Gewicht
   als der Rest der Zeile, aber weniger als der Seitenname. */
.fuss-herausgeber {
  color: var(--ink-2); font-weight: 600; letter-spacing: .01em;
}

/* --- 4. Bausteine -------------------------------------------------------- */

.knopf {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  background: var(--marke); color: var(--knopf-ink);
  border: 1px solid transparent; border-radius: var(--rund-voll);
  padding: .72rem 1.35rem; font: inherit; font-weight: 600; font-size: .98rem;
  cursor: pointer; text-decoration: none; text-align: center;
  box-shadow: var(--schatten-1);
  transition: transform .12s, box-shadow .18s, background .18s;
}
.knopf:hover { color: var(--knopf-ink); box-shadow: var(--schatten-2); }
.knopf:active { transform: translateY(1px); }
.knopf svg { width: 19px; height: 19px; }
.knopf[disabled] { opacity: .45; cursor: not-allowed; box-shadow: none; }

.knopf-zweit {
  background: var(--karte); color: var(--ink);
  border-color: var(--linie-kraeftig);
}
.knopf-zweit:hover { color: var(--ink); background: var(--bg-tief); }

.knopf-klein { padding: .45rem .9rem; font-size: .9rem; }

.karte {
  background: var(--karte);
  border: 1px solid var(--linie);
  border-radius: var(--rund);
  padding: 1.4rem;
  box-shadow: var(--schatten-1);
}

.raster {
  display: grid; gap: 1.1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
}
.raster-2 {
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
}

.kasten {
  border-radius: var(--rund);
  padding: 1.1rem 1.25rem;
  margin: 1.6rem 0;
  border: 1px solid var(--linie);
  background: var(--karte-2);
}
.kasten > :first-child { margin-top: 0; }
.kasten > :last-child { margin-bottom: 0; }
.kasten h3, .kasten h4 { margin-top: 0; }

.kasten-hinweis { background: var(--marke-weich); border-color: transparent; }
.kasten-warnung { background: var(--warn-weich); border-color: transparent; }
.kasten-falle   { background: var(--akzent-weich); border-color: transparent; }

.marke-schild {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .82rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-3);
  margin-bottom: .5rem;
}
/* Ein <svg> mit viewBox und ohne eigene Größe ist 300 mal 150 Pixel groß —
   das ist der Standardwert, den kaum jemand im Kopf hat. In einem
   Flex-Behälter wird daraus je nach Nachbarn entweder ein Riese oder ein
   Nichts, und beides sieht nach etwas anderem aus als nach einer fehlenden
   Größenangabe.

   Genau das war hier: Das Warnsymbol im „Aufgepasst"-Kasten war auf allen
   Grammatikseiten unsichtbar, und dasselbe Symbol auf einer neuen Karte
   wurde riesig. Aufgefallen ist es erst durch den Riesen. */
.marke-schild svg { width: 17px; height: 17px; flex: none; }

.stufe-punkt {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.35rem; padding: .12rem .5rem;
  border-radius: var(--rund-voll);
  font-size: .82rem; font-weight: 700; letter-spacing: .04em;
  background: color-mix(in srgb, var(--stufe-farbe, var(--marke)) 16%, var(--karte));
  color: var(--stufe-ink);
  border: 1px solid color-mix(in srgb, var(--stufe-farbe, var(--marke)) 30%, transparent);
}

/* Auch die stille Zeile ist Fließtext — meistens die, die erklärt, was die
   Zahl darüber bedeutet. Sie ist die letzte gewesen, die über das Lesemaß
   hinauslief. */
.zeile-still {
  color: var(--ink-3); font-size: .9rem; max-width: var(--lesebreite);
}

table { border-collapse: collapse; width: 100%; }

.tabelle-rahmen { overflow-x: auto; margin: 1.3rem 0; }
.tabelle-rahmen table { min-width: 24rem; }
th, td {
  text-align: left; padding: .6rem .8rem;
  border-bottom: 1px solid var(--linie); vertical-align: top;
}
th { font-size: .8rem; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; }
tbody tr:last-child td { border-bottom: none; }

/* Der Rahmen um englische Beispielsaetze. Englisch wird durchgaengig anders
   gesetzt als Deutsch — nicht als Verzierung, sondern damit beim Ueberfliegen
   sofort klar ist, welche Sprache man vor sich hat. */
.ziel {
  font-weight: 500;
  color: var(--ink);
}
.de {
  color: var(--ink-3);
  font-size: .95em;
}
/* Ein Satzpaar ist Fließtext und gehört damit unter das Lesemaß. Ohne die
   Grenze läuft es in einer Karte auf dem Schreibtisch über die volle
   Containerbreite — gemessen 1122 Pixel, also gut das Anderthalbfache dessen,
   was ein Auge in einer Zeile noch bequem verfolgt. Auf dem Telefon ändert
   sich dadurch nichts; dort war die Breite nie das Problem. */
.satzpaar { margin: 0 0 .85rem; max-width: var(--lesebreite); }
.satzpaar .ziel { display: block; }
.satzpaar .de { display: block; }
.satzpaar:last-child { margin-bottom: 0; }

.falsch-richtig { display: grid; gap: .55rem; margin: .9rem 0 0; }
.fr-zeile {
  display: flex; gap: .6rem; align-items: baseline;
  padding: .5rem .75rem; border-radius: var(--rund-s);
  background: color-mix(in srgb, var(--karte) 70%, transparent);
}
.fr-zeile[data-art="falsch"] { background: var(--fehler-weich); }
.fr-zeile[data-art="richtig"] { background: var(--ok-weich); }
.fr-mark { font-weight: 700; flex: none; }
.fr-zeile[data-art="falsch"] .fr-mark { color: var(--fehler); }
.fr-zeile[data-art="richtig"] .fr-mark { color: var(--ok-ink); }

.marken-liste { list-style: none; margin: 0; padding: 0; }
.marken-liste li {
  position: relative; padding-left: 1.5rem; margin-bottom: .45rem;
}
.marken-liste li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--marke); opacity: .55;
}

.signalwoerter {
  display: flex; flex-wrap: wrap; gap: .4rem; margin: .8rem 0 0; padding: 0;
  list-style: none;
}
.signalwoerter li {
  background: var(--bg-tief); border: 1px solid var(--linie);
  border-radius: var(--rund-voll); padding: .25rem .7rem;
  font-size: .88rem; color: var(--ink-2);
}

/* --- 4b. Der leise Hintergrund auf jeder Seite ---------------------------- */

/* `position: fixed` und nicht `absolute`: Die Fläche ist einen Bildschirm
   groß und bleibt beim Scrollen stehen. Absolut positioniert wäre sie so hoch
   wie der Viewport und stünde ab dem zweiten Bildschirm nicht mehr dahinter —
   also genau da nicht, wo die meiste Zeit gelesen wird.

   `z-index: 0` mit `isolation: isolate` auf nichts: Alles andere im Körper hat
   keinen eigenen Stapelkontext und liegt schon deshalb darüber. Ein negativer
   Wert war die erste Fassung und ist falsch — er schiebt das Canvas hinter den
   Hintergrund des Körpers, und dann sieht man gar nichts.

   `pointer-events: none` ist nicht Kosmetik: Ohne das fängt eine
   bildschirmgroße Fläche jeden Klick ab, der nicht auf einen Text trifft. */
.grundflaeche {
  position: fixed; inset: 0; width: 100%; height: 100%;
  display: block; z-index: 0; pointer-events: none;
}
/* Nur `z-index`, nicht `position`. Die erste Fassung setzte hier
   `position: relative` auf `.kopf` mit — und überschrieb damit das `sticky`
   der Kopfzeile, die daraufhin nach oben aus dem Bild scrollte. `.kopf` und
   die Übungsfußzeile bringen ihren Stapelkontext schon selbst mit; die beiden
   übrigen brauchen einen. */
.kopf, .fuss { z-index: 40; }
main, .sprungmarke { position: relative; z-index: 1; }

/* Auf der Startseite malt die Bühne ihr eigenes, kräftigeres Bild — die
   Grundfläche schaltet sich dort selbst ab, siehe grundflaeche.js. Zwei
   Flächen übereinander wären zweimal dieselbe Idee, nur unruhiger. */

/* --- 5. Startseite ------------------------------------------------------- */

.buehne { position: relative; overflow: hidden; }
.buehne-grund {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; z-index: 0;
}
.buehne-schleier {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--bg) calc(var(--schleier-oben) * 100%), transparent) 0%,
      color-mix(in srgb, var(--bg) calc(var(--schleier-rand) * 100%), transparent) 62%,
      var(--bg) 100%);
}
/* Nur oben und unten setzen. Die Kurzform `padding: 3.4rem 0 3rem` stand hier
   zuerst — und weil dieses Element AUCH .huelle traegt, loeschte sie deren
   seitlichen Rand: Auf dem Telefon klebte die Ueberschrift am Displayrand.
   Eine Kurzform setzt eben alle vier Seiten, auch die, die man gar nicht
   meinte. */
.buehne-innen {
  position: relative; z-index: 2;
  padding-top: 3.4rem; padding-bottom: 3rem;
}

/* Auf breiten Schirmen stehen Text und Vorfuehrung nebeneinander: Die
   Vorfuehrung ist das Argument, und ein Argument, fuer das man erst scrollen
   muss, ist keines. */
@media (min-width: 1020px) {
  .buehne-innen {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: 2.6rem; align-items: center;
  }
  .buehne-innen > .hero { max-width: none; }
}

.hero { max-width: 40rem; }
.hero h1 { margin-bottom: .55rem; }
.hero-sub {
  font-size: 1.15rem; color: var(--ink-2); max-width: 34rem;
  margin-bottom: 1.6rem;
}
.hero-knoepfe { display: flex; flex-wrap: wrap; gap: .7rem; }

/* --- Der Anspruch der Seite ---------------------------------------------
   Zwei Zeilen mit verschiedenen Aufgaben, und deshalb mit verschiedenem
   Gewicht. Der Claim steht ueber der Ueberschrift und ist die kuerzeste
   Zeile der Seite; die Belegzeile steht unter dem Vorspann und ist die
   ruhigste. Dazwischen liegt die Ueberschrift, die weiter das Thema nennt
   und nicht den Anspruch — ein Suchergebnis lebt vom Thema.

   Der Claim ist bewusst nicht in Versalien gesetzt. Ein Satz mit Punkt am
   Ende, in Versalien, liest sich als Werbung; hier soll er sich als
   Aussage lesen. Die Marke traegt ihn, nicht die Typografie. */
.claim {
  margin: 0 0 .5rem; font-family: var(--schrift-titel);
  font-size: 1.05rem; font-style: italic; letter-spacing: .01em;
  color: var(--marke-ink);
}
.claim-beleg {
  margin: 0 0 1.6rem; max-width: 34rem;
  font-size: .95rem; line-height: 1.65; color: var(--ink-3);
}
/* Steht der Beleg da, hat der Vorspann seinen Abstand schon abgegeben. */
.hero-sub:has(+ .claim-beleg) { margin-bottom: .7rem; }

/* Der Herausgeber steht neben dem Namen der Seite und vor dem Satz, der
   sagt, was sie ist: eine Angabe ueber die Herkunft und kein Hinweis auf
   den Inhalt. Etwas mehr Gewicht als der Rest der Zeile, weniger als der
   Seitenname. */
.fuss-herausgeber {
  color: var(--ink-2); font-weight: 600; letter-spacing: .01em;
}

.leiter { display: grid; gap: .5rem; margin: 2.4rem 0 0; }
.leiter-sprosse {
  display: grid; grid-template-columns: 3.2rem minmax(0, 1fr) auto; gap: .9rem;
  align-items: center;
  background: var(--karte); border: 1px solid var(--linie);
  border-left: 4px solid var(--stufe-farbe, var(--marke));
  border-radius: var(--rund); padding: .8rem 1rem;
  text-decoration: none; color: var(--ink);
  box-shadow: var(--schatten-1);
  transition: transform .14s, box-shadow .2s;
}
.leiter-sprosse:hover {
  transform: translateX(3px); box-shadow: var(--schatten-2); color: var(--ink);
}
.leiter-name {
  font-family: var(--schrift-titel); font-size: 1.35rem; font-weight: 600;
  color: var(--stufe-ink);
}
.leiter-titel { font-weight: 600; }
.leiter-kurz { color: var(--ink-3); font-size: .92rem; }
.leiter-zahl { color: var(--ink-3); font-size: .87rem; white-space: nowrap; }

/* Die Vorfuehrung. Sie steht fertig da, auch ohne JavaScript — das erste
   Bild ist im HTML ausgeschrieben, alles Weitere schaltet das Skript. */
.vorfuehrung {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund-l); box-shadow: var(--schatten-3);
  overflow: hidden;
}
.vf-kopf {
  display: flex; align-items: center; gap: .6rem;
  padding: .7rem 1rem; border-bottom: 1px solid var(--linie);
  background: var(--bg-tief);
}
.vf-punkte { display: flex; gap: 0; margin-left: auto; }
/* Ein Punkt von acht Pixeln ist ein Ziel, das auf dem Telefon niemand
   trifft. Sichtbar bleibt er klein, anfassbar wird er 24 Pixel gross — der
   Knopf traegt die Flaeche, das ::after zeichnet den Punkt. */
.vf-punkt {
  /* 32 und nicht 24: Vierundzwanzig war schon der zweite Anlauf und immer
     noch unter dem, was ein Daumen sicher trifft. Sichtbar bleibt der Punkt
     unverändert klein — die Fläche liegt im Knopf, der Punkt im ::after. */
  width: 32px; height: 32px; border: none; padding: 0; cursor: pointer;
  background: none; display: inline-flex; align-items: center;
  justify-content: center; border-radius: 50%;
}
.vf-punkt::after {
  content: ""; width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--linie-kraeftig);
  transition: background .2s, transform .2s;
}
.vf-punkt[aria-selected="true"]::after {
  background: var(--marke); transform: scale(1.35);
}
.vf-titel { font-weight: 600; font-size: .93rem; }
/* Alle Szenen liegen uebereinander in derselben Rasterzelle. Damit ist
   die Buehne so hoch wie ihre hoechste Szene und aendert ihre Hoehe beim
   Wechsel nicht mehr. `min-height` war ein Boden und keine Decke: Eine
   Szene mit einer Zeile mehr — etwa die mit dem Kasten „Richtig ist" —
   machte den ganzen Kasten hoeher und die Seite mit ihm.
   `visibility` statt `display`, weil eine Szene, die nicht angezeigt wird,
   trotzdem Platz beanspruchen soll; aus dem Tastaturlauf und aus dem
   Vorlesen faellt sie damit ebenso heraus wie vorher. */
.vf-buehne {
  padding: 1.3rem; min-height: 13.5rem; position: relative;
  display: grid; align-items: start;
}
.vf-szene { grid-area: 1 / 1; visibility: hidden; }
.vf-szene[data-aktiv="ja"] {
  visibility: visible; animation: vf-rein .38s ease-out;
}
@keyframes vf-rein {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.vf-frage { font-size: 1.08rem; margin-bottom: .9rem; }
.vf-fuss {
  padding: .6rem 1rem; border-top: 1px solid var(--linie);
  font-size: .82rem; color: var(--ink-3); background: var(--bg-tief);
}

.vf-wahl { display: grid; gap: .45rem; list-style: none; margin: 0; padding: 0; }
.vf-wahl li {
  border: 1px solid var(--linie); border-radius: var(--rund-s);
  padding: .55rem .8rem; background: var(--karte-2);
  transition: background .25s, border-color .25s;
}
.vf-wahl li[data-stand="falsch"] { background: var(--fehler-weich); border-color: var(--fehler); }
.vf-wahl li[data-stand="richtig"] { background: var(--ok-weich); border-color: var(--ok); }

.vf-zeiger {
  position: absolute; width: 22px; height: 22px; z-index: 5;
  pointer-events: none; opacity: 0;
  transition: transform .55s cubic-bezier(.3,.8,.3,1), opacity .25s;
  color: var(--ink);
}
.vf-zeiger[data-sichtbar="ja"] { opacity: .85; }
.vf-zeiger[data-druck="ja"] { transform: scale(.86); }

.vf-tipp {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--bg-tief); border: 1px solid var(--linie);
  border-radius: var(--rund-s); padding: .6rem .8rem; min-height: 2.6rem;
}
.vf-tipp::after {
  content: "▍"; color: var(--marke); animation: blinken 1s steps(2) infinite;
}
@keyframes blinken { 50% { opacity: 0; } }

.vf-uhr {
  font-family: var(--schrift-titel); font-size: 2rem; font-weight: 600;
  color: var(--akzent-ink);
}
.vf-faecher { display: grid; grid-template-columns: repeat(5, 1fr); gap: .4rem; }
.vf-fach {
  border: 1px solid var(--linie); border-radius: var(--rund-s);
  padding: .5rem .3rem; text-align: center; background: var(--karte-2);
  transition: background .3s, transform .3s;
}
.vf-fach[data-leuchtet="ja"] { background: var(--marke-weich); transform: translateY(-3px); }
.vf-fach b { display: block; font-size: 1.15rem; }
.vf-fach span { font-size: .82rem; color: var(--ink-3); }

.vf-zahlen { display: grid; grid-template-columns: repeat(3, 1fr); gap: .8rem; margin-top: 1rem; }
.vf-zahl { text-align: center; }
.vf-zahl b {
  display: block; font-family: var(--schrift-titel); font-size: 1.9rem;
  color: var(--marke-ink); font-weight: 600;
}
.vf-zahl span { font-size: .8rem; color: var(--ink-3); }

.wegweiser {
  display: grid; gap: .9rem;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
}
.weg {
  display: block; text-decoration: none; color: var(--ink);
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1.2rem;
  box-shadow: var(--schatten-1);
  transition: transform .14s, box-shadow .2s, border-color .2s;
}
.weg:hover {
  transform: translateY(-2px); box-shadow: var(--schatten-2);
  border-color: var(--linie-kraeftig); color: var(--ink);
}
.weg svg { width: 26px; height: 26px; color: var(--marke); margin-bottom: .5rem; }
.weg b { display: block; font-family: var(--schrift-titel); font-size: 1.08rem; margin-bottom: .2rem; }
.weg span { color: var(--ink-3); font-size: .93rem; }

/* Die Sprachauswahl auf der Startseite der Marke. Grösser als ein Wegweiser,
   weil hier die eigentliche Entscheidung getroffen wird: Wer hier steht, hat
   noch keine Sprache gewählt, und alles andere auf der Seite setzt eine
   voraus. Eine einzelne Karte darf trotzdem nicht die halbe Breite fluten —
   daher `max-width` statt `1fr` bei nur einem Eintrag. */
/* Die Flagge sitzt in der Zeile und nicht darueber: `vertical-align`
   auf der Grundlinie liesse sie an der Unterkante haengen, weil ein SVG
   ein ersetztes Element ist und keine Schriftlinie kennt. */
.flagge {
  display: inline-block; vertical-align: -.14em; flex: 0 0 auto;
  border-radius: .18em;
}

/* --- Sprachpaar: der Satz und die beiden Felder -------------------------- */

.paarwahl { margin: 0 0 1.6rem; }
.paarwahl-satz {
  font-size: 1.15rem; line-height: 1.7; margin: 0 0 .9rem; color: var(--ink);
}
.paar-marke {
  display: inline-flex; align-items: center; gap: .38em;
  font-weight: 600; white-space: nowrap;
}
.paarwahl-felder {
  display: flex; flex-wrap: wrap; gap: 1rem 1.6rem; align-items: flex-end;
  padding: 1rem 1.1rem; border: 1px solid var(--linie);
  border-radius: var(--rund); background: var(--karte);
  box-shadow: var(--schatten-1);
}
.paarwahl-felder[hidden] { display: none; }
.paarwahl-feld { display: flex; flex-direction: column; gap: .35rem; }
.paarwahl-schild {
  font-size: .82rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-2); font-weight: 600;
}
.paarwahl-eingabe {
  display: flex; align-items: center; gap: .55rem;
  border: 1px solid var(--linie); border-radius: .6rem;
  background: var(--bg); padding: .1rem .6rem .1rem .7rem;
}
.paarwahl-eingabe:focus-within {
  border-color: var(--marke); box-shadow: 0 0 0 3px var(--marke-weich);
}
.paarwahl-flagge { display: inline-flex; align-items: center; }
/* Ein `select` ohne eigenen Rahmen: Der Rahmen gehoert der Huelle, damit
   Flagge und Feld wie ein Bedienelement wirken und nicht wie zwei. */
.paarwahl-eingabe select {
  border: 0; background: none; color: var(--ink); font: inherit;
  font-size: 1.05rem; padding: .55rem .2rem .55rem 0; min-width: 8.5rem;
  appearance: none; -webkit-appearance: none; cursor: pointer;
}
.paarwahl-eingabe select:focus { outline: none; }
.paarwahl-eingabe::after {
  content: ""; width: .5rem; height: .5rem; margin-left: -.1rem;
  border-right: 2px solid var(--ink-2); border-bottom: 2px solid var(--ink-2);
  transform: rotate(45deg) translate(-2px, -2px); flex: 0 0 auto;
}
.paarwahl-stand {
  flex: 1 1 100%; margin: 0; color: var(--akzent-ink);
  font-size: .95rem; line-height: 1.6;
}
.paarwahl-stand:empty { display: none; }
.paarwahl-vorrat[hidden] { display: none; }

@media (max-width: 30rem) {
  .paarwahl-felder { gap: .9rem; }
  .paarwahl-feld { flex: 1 1 100%; }
  .paarwahl-eingabe select { width: 100%; }
}

.sprachwahl {
  display: grid; gap: 1rem; margin-bottom: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
}
.sprachkarte {
  display: block; text-decoration: none; color: var(--ink);
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1.5rem 1.4rem;
  box-shadow: var(--schatten-1); max-width: 30rem;
  transition: transform .14s, box-shadow .2s, border-color .2s;
}
.sprachkarte:hover {
  transform: translateY(-2px); box-shadow: var(--schatten-2);
  border-color: var(--marke); color: var(--ink);
}
/* Ein Sprachpaar, das es noch nicht gibt. Es steht in der Auswahl, damit
   sie vollstaendig ist, und es ist kein Verweis, weil es nirgendwohin
   fuehrt — deshalb ein <span> und keine Umrandung, die zum Klicken
   einlaedt. Der gestrichelte Rand sagt dasselbe wie der Text darunter,
   nur schneller. */
.sprachkarte-bald {
  border-style: dashed; box-shadow: none; cursor: default;
  color: var(--ink-3);
}
.sprachkarte-bald:hover {
  transform: none; box-shadow: none; border-color: var(--linie);
}
.sprachkarte-name {
  display: block; font-family: var(--schrift-titel);
  font-size: 1.5rem; line-height: 1.2; margin-bottom: .45rem;
}
.sprachkarte-kurz {
  display: block; color: var(--ink-2); font-size: .95rem; line-height: 1.55;
}
.sprachkarte-mehr {
  display: block; margin-top: .8rem; font-weight: 600;
  color: var(--marke-ink); font-size: .95rem;
}

/* --- 6. Stufen und Grammatik --------------------------------------------- */

.seitenkopf { padding: 2.4rem 0 1.4rem; }
.seitenkopf .zeile-still { margin-bottom: .4rem; }

.brotkrumen {
  font-size: .87rem; color: var(--ink-3); margin-bottom: .9rem;
  overflow-wrap: anywhere;
}
/* Sechzehn Pixel hoch war die Krume genau so hoch wie ihre Schrift. Auf
   dem Telefon ist das der erste Verweis, den jemand sucht, wenn er sich
   verlaufen hat — und der schwerste zu treffen. */
.brotkrumen a {
  color: var(--ink-3); text-decoration: none;
  display: inline-block; padding: .45rem 0;
}
.brotkrumen a:hover { color: var(--marke-ink); text-decoration: underline; }
.brotkrumen span { margin: 0 .35rem; opacity: .5; }

.bereich-block { margin-bottom: 2.6rem; }
.bereich-kopf {
  display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap;
  border-bottom: 2px solid var(--linie); padding-bottom: .5rem; margin-bottom: 1rem;
}
.bereich-kopf h2 { margin: 0; }

.themenliste { display: grid; gap: .55rem; }
.thema-zeile {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: .8rem;
  align-items: center;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: .7rem .95rem;
  text-decoration: none; color: var(--ink);
  transition: border-color .16s, transform .14s, box-shadow .2s;
}
.thema-zeile:hover {
  border-color: var(--linie-kraeftig); transform: translateX(2px);
  box-shadow: var(--schatten-1); color: var(--ink);
}
.thema-name { font-weight: 600; }
.thema-kurz { display: block; color: var(--ink-3); font-size: .9rem; font-weight: 400; }
.thema-stand {
  font-size: .82rem; color: var(--ink-3); white-space: nowrap;
}
.thema-stand[data-fach] { color: var(--marke-ink); font-weight: 600; }

.thema-seite h2 { border-bottom: 1px solid var(--linie); padding-bottom: .35rem; }

/* Eine Themenseite ist ein Dokument, keine Anwendungsoberflaeche. Alles darin
   steht in einer Spalte — auch die Tabellen und die Uebung, sonst zieht sich
   die Formtabelle auf 1280 Pixel auseinander, waehrend der Absatz darueber
   bei 620 endet. */
.dokument { max-width: 48rem; }
.dokument .lesespalte { max-width: var(--lesebreite); }

.formtabelle td:first-child {
  color: var(--ink-3); font-size: .9rem; white-space: nowrap; width: 11rem;
}
.formtabelle td:last-child { font-weight: 500; }

.regelliste { display: grid; gap: 1rem; margin: 1.2rem 0; padding: 0; list-style: none; }
.regel {
  border-left: 3px solid var(--marke); padding-left: 1rem;
}
.regel-text { margin-bottom: .4rem; }

.merksatz {
  display: flex; gap: .8rem; align-items: flex-start;
  background: var(--marke-weich); border-radius: var(--rund);
  padding: 1rem 1.2rem; margin: 1.6rem 0;
  font-family: var(--schrift-titel); font-size: 1.12rem; line-height: 1.45;
}
.merksatz svg { width: 22px; height: 22px; flex: none; color: var(--marke-ink); margin-top: .15rem; }

.verwandt-liste { display: flex; flex-wrap: wrap; gap: .5rem; padding: 0; list-style: none; margin: .8rem 0 0; }
.verwandt-liste a {
  display: inline-block; background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund-voll); padding: .35rem .85rem;
  font-size: .9rem; text-decoration: none; color: var(--ink-2);
}
.verwandt-liste a:hover { border-color: var(--marke); color: var(--marke-ink); }

/* --- Die Grammatik auf einen Blick: fuenf Familien ----------------------- */
/* Karten und keine Tabelle, und der Grund ist nicht der Geschmack: Eine
   Tabelle mit fuenf Zeilen und wechselnd vielen Bereichen je Zeile hat auf
   einem Telefon keine Breite, in der sie noch eine Tabelle waere. Karten
   stapeln sich, ohne dass jemand etwas dafuer tun muss — und dieselbe
   Gliederung traegt spaeter in einer App, wo es gar kein HTML mehr gibt.

   `auto-fit` mit `minmax(min(…, 100%), 1fr)`: die Karten teilen sich die
   Breite, die da ist, und werden auf einem schmalen Schirm einspaltig,
   ohne dass eine Medienabfrage das anordnen muesste. Das `min(…, 100%)`
   ist der Teil, der es auf 320px rettet — ohne ihn erzwingt die Mindest-
   breite einen waagerechten Scrollbalken. */
.gfam-raster {
  display: grid; gap: 1rem; margin: 1.4rem 0 2.4rem;
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
}
.gfam {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1.1rem 1.2rem;
  box-shadow: var(--schatten-1);
  display: flex; flex-direction: column; gap: .5rem;
}
.gfam-kopf {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: .4rem;
}
/* Die Ueberschrift traegt hier kein Gewicht einer Seitenueberschrift: Sie
   benennt eine Karte, nicht einen Abschnitt. Die Stufe darf sie nicht
   ueberragen — sonst liest man fuenfmal „Zeiten" und danach erst, was auf
   der Seite steht. */
.gfam-kopf h2 {
  font-size: 1.15rem; margin: 0;
  display: inline-flex; align-items: center; gap: .5rem;
}
/* Das Symbol traegt die Farbe der Marke und nicht die der Schrift: Es soll
   die Ueberschrift begleiten und nicht mit ihr um Gewicht streiten. */
.gfam-zeichen {
  display: inline-flex; color: var(--marke-ink); flex: none;
}
.gfam-zeichen svg { width: 21px; height: 21px; display: block; }
.gfam-kurz { color: var(--ink-2); font-size: .93rem; margin: 0; }
/* Die Bereiche einer Familie stehen untereinander, ihre Themen darunter.
   Vorher waren es Chips in einer Zeile — kompakt, aber sie sagten nur,
   wie viele Themen es gibt, und nicht welche. Wer eine Uebersicht
   aufschlaegt, sucht ein bestimmtes Thema. */
.gfam-bereiche {
  display: grid; gap: .9rem; margin: .8rem 0 0;
}
/* `align-items: center` und nicht `baseline`, seit der Verweis eine Höhe
   hat: Ein Ziel, das man mit dem Daumen treffen soll, muss zweiunddreißig
   Pixel hoch sein — `layout` besteht darauf, und es hatte recht: Ein
   nackter Textverweis ist achtzehn. */
.gfam-bereich-kopf {
  display: flex; align-items: center; gap: .45rem;
  margin: 0 0 .35rem; font-size: .93rem; font-weight: 700;
  letter-spacing: .02em; color: var(--ink-2);
}
.gfam-bereich-kopf a {
  color: inherit; text-decoration: none;
  display: inline-flex; align-items: center; min-height: 32px;
}
.gfam-bereich-kopf a:hover { color: var(--marke-ink); }
/* Die Zahl in einer eigenen Ziffernbreite, damit die Koepfe untereinander
   nicht zappeln, wenn aus 5 eine 12 wird. */
.gfam-zahl {
  font-variant-numeric: tabular-nums; font-weight: 600;
  font-size: .8rem; color: var(--ink-3);
}
.gfam-themen {
  display: flex; flex-wrap: wrap; gap: .3rem;
  list-style: none; padding: 0; margin: 0;
}
.gfam-themen a {
  display: inline-flex; align-items: center; gap: .35rem;
  min-height: 32px;
  background: var(--karte-2); border: 1px solid var(--linie);
  border-radius: var(--rund-voll); padding: .3rem .7rem;
  font-size: .85rem; text-decoration: none; color: var(--ink-2);
  transition: border-color .15s, color .15s, background .15s;
}
.gfam-themen a:hover, .gfam-themen a:focus-visible {
  border-color: var(--marke); color: var(--marke-ink);
}
/* Die Stufe steht als Beiwerk am Thema und nicht als zweiter Titel. */
.gfam-stufe {
  font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  color: var(--ink-3);
}
/* Die Zahl ist die eigentliche Auskunft der Marke — sie sagt, ob hinter
   dem Namen drei Themen stehen oder fuenfzehn. Sie steht deshalb da und
   nicht im Titel, wo sie jede Zeile laenger machen wuerde. */
.gfam-bereiche a span {
  font-variant-numeric: tabular-nums; color: var(--ink-3);
  font-size: .82rem;
}

/* Die Familie ueber ihren Bereichen — dieselbe Ordnung wie in der
   Uebersicht, sonst waeren es zwei. Ein Strich statt einer Karte: Auf
   dieser Seite ist schon jeder Bereich ein Block und jedes Thema eine
   Zeile; eine dritte Umrandung darum haette die Seite in Kaesten
   verpackt, in denen man nichts mehr findet. */
.gfam-gruppe { margin: 0 0 3.2rem; }
.gfam-titel {
  font-size: 1.6rem; margin: 0 0 1.2rem;
  padding-bottom: .3rem;
  border-bottom: 3px solid var(--marke);
  display: inline-block;
}
.bereich-kopf h3 { margin: 0; font-size: 1.2rem; }

.stufe-kopf {
  border-radius: var(--rund-l); padding: 2rem 1.6rem;
  background: color-mix(in srgb, var(--stufe-farbe) 12%, var(--karte));
  border: 1px solid color-mix(in srgb, var(--stufe-farbe) 26%, transparent);
  margin-bottom: 2rem;
}
.stufe-kopf h1 { margin-bottom: .3rem; }
.stufe-kopf .stufe-gross {
  font-family: var(--schrift-titel); font-size: 3rem; line-height: 1;
  color: var(--stufe-ink); font-weight: 600;
}

/* Vertiefung — der aufklappbare Teil eines Grammatikpunkts.

   Eine Erklaerung, die alles auf einmal zeigt, wird nicht gelesen; eine, die
   alles wegklappt, wird nicht gefunden. Deshalb steht die Kurzfassung offen
   und die Vertiefung dahinter, mit einer Zusammenfassung, die sagt, was
   drinsteht — und mit einem Zaehler, damit niemand blind aufklappen muss.

   details/summary statt eines eigenen Schalters: das klappt auch ohne
   JavaScript auf, laesst sich mit der Tastatur bedienen und wird von der
   Browsersuche geoeffnet. Ein selbst gebauter Aufklapper kann keins davon. */

.vertiefung {
  border: 1px solid var(--linie); border-radius: var(--rund);
  background: var(--karte-2); margin: 1.1rem 0; overflow: hidden;
}
.vertiefung + .vertiefung { margin-top: .7rem; }
.vertiefung > summary {
  display: flex; align-items: center; gap: .6rem;
  padding: .85rem 1.1rem; cursor: pointer; list-style: none;
  font-family: var(--schrift-titel); font-weight: 600; color: var(--ink);
  min-height: 2.75rem;
}
.vertiefung > summary::-webkit-details-marker { display: none; }
.vertiefung > summary::after {
  content: ''; margin-left: auto; flex: none;
  width: .5rem; height: .5rem; border-right: 2px solid var(--ink-3);
  border-bottom: 2px solid var(--ink-3); transform: rotate(45deg);
  transition: transform .18s ease;
}
.vertiefung[open] > summary::after { transform: rotate(-135deg); }
.vertiefung > summary:hover { background: var(--bg-tief); }
.vertiefung > summary:focus-visible {
  outline: 2px solid var(--marke); outline-offset: -2px;
}
.vertiefung .v-zahl {
  font-family: var(--schrift); font-weight: 500; font-size: .82rem;
  color: var(--ink-3); background: var(--bg-tief);
  border-radius: var(--rund-voll); padding: .12rem .55rem;
}
.vertiefung > .v-inhalt { padding: 0 1.1rem 1.1rem; }
.vertiefung > .v-inhalt > p { max-width: var(--lesebreite); }
.vertiefung > .v-inhalt > :first-child { margin-top: 0; }

/* Deutsch daneben gelegt — zwei Spalten, auf dem Handy zwei Zeilen. */
.gegenueber { display: grid; gap: .7rem; margin: .2rem 0 0; padding: 0; list-style: none; }
.gg-paar {
  display: grid; grid-template-columns: 1fr 1fr; gap: .1rem 1rem;
  border-left: 3px solid var(--akzent); padding-left: .9rem;
}
.gg-paar > .gg-de, .gg-paar > .gg-en { align-self: end; }
.gg-paar > .gg-de { color: var(--ink-2); }
.gg-paar > .gg-en { font-weight: 500; }
.gg-paar > .gg-was {
  grid-column: 1 / -1; font-size: .88rem; color: var(--ink-3); margin-top: .3rem;
}
@media (max-width: 640px) {
  .gg-paar { grid-template-columns: 1fr; }
}

/* Sonderfaelle — je einer ein kleiner Block mit Titel, Satz und Beispiel. */
.sonderfaelle { display: grid; gap: 1rem; margin: .2rem 0 0; padding: 0; list-style: none; }
.sonderfall > h3 {
  font-size: 1rem; margin: 0 0 .3rem; color: var(--akzent-ink);
}
.sonderfall > p { max-width: var(--lesebreite); margin-bottom: .45rem; }

/* Schaubilder — vier Bildtypen, aus Daten gezeichnet.

   Die Farben stehen hier und nicht im SVG, damit ein Bild in beiden
   Farbfassungen richtig aussieht. Ein SVG mit eingebauten Hexwerten waere
   auf Papier entweder unsichtbar oder ein Loch in der Seite. */

.schaubild-rahmen {
  margin: 1.4rem 0; padding: 1rem 1rem .4rem;
  border: 1px solid var(--linie); border-radius: var(--rund);
  background: var(--karte-2);
}
.schaubild { display: block; width: 100%; height: auto; }
.schaubild-rahmen figcaption {
  margin: .6rem .2rem .5rem; font-size: .9rem; color: var(--ink-3);
  max-width: var(--lesebreite);
}

.sb-text  { fill: var(--ink); font-family: var(--schrift); }
.sb-still { fill: var(--ink-3); font-family: var(--schrift); }
.sb-en    { fill: var(--ink); font-family: var(--schrift); }

.sb-achse  { stroke: var(--linie-kraeftig); stroke-width: 1.5; }
.sb-spitze { fill: var(--linie-kraeftig); }
.sb-jetzt  { stroke: var(--akzent); stroke-width: 1.5; stroke-dasharray: 4 4; }
.sb-punkt  { fill: var(--marke); }
.sb-strecke{ fill: var(--marke); opacity: .8; }
.sb-linie  { stroke: var(--linie-kraeftig); stroke-width: 1.5; fill: none; }

.sb-feld    { fill: var(--marke-weich); stroke: none; }
.sb-frage   { fill: var(--akzent-weich); stroke: none; }
.sb-pille   { fill: var(--bg-tief); stroke: none; }
.sb-ausgang { fill: var(--marke-weich); stroke: none; }
.sb-sprosse { fill: var(--marke-weich); stroke: none; }

/* Muno — das Maskottchen.

   Warum ein Murmeltier und warum diese Posen: siehe den Kopf von
   tools/maskottchen.py. Hier steht nur, wie er gemalt wird.

   Die Farben stehen als Token oben und nicht hier, damit Muno auf Papier
   und im Dunkeln derselbe ist. Ein SVG mit eingebauten Hexwerten wäre in
   einer der beiden Fassungen ein brauner Fleck. */

.muno { width: 96px; height: 96px; display: block; flex: none; }

/* Jede Fläche der Figur holt ihre Farbe über eine Marke — nur so wechselt
   Muno mit dem Sprachpaar und bleibt auf Papier wie im Dunkeln lesbar. */
.mu-haut       { fill: var(--mu-haut); }
.mu-haut-hell  { fill: var(--mu-haut-hell); }
.mu-haut-tief  { fill: var(--mu-haut-tief); }
.mu-band       { fill: var(--mu-band); }
.mu-bauch      { fill: var(--mu-bauch); }
.mu-kamm       { fill: var(--mu-kamm); }
.mu-kamm-tief  { fill: var(--mu-kamm-tief); }
.mu-auge       { fill: var(--mu-auge); }
.mu-wange      { fill: var(--mu-wange); }
/* Der Doktorhut. Er wechselt als Einziges an der Figur die Farbe *nicht*
   mit der Sprache: Ein Doktorhut ist dunkel, überall, und ein blauer wäre
   eine Mütze. Die Sprache trägt statt dessen die Quaste, die in
   `--mu-band` gezeichnet ist. */
.mu-hut        { fill: var(--mu-hut); }
.mu-hut-tief   { fill: var(--mu-hut-tief); }
.mu-ast        { fill: var(--mu-ast); }
.mu-ast-tief   { fill: var(--mu-ast-tief); }
.mu-glanz      { fill: var(--mu-glanz); }

/* Und dasselbe noch einmal für die Halte in den Verläufen.

   **Warum eine eigene Klasse und nicht `stop-color="var(--mu-haut)"`:**
   Eine CSS-Eigenschaft in einem *Attribut* wird nicht aufgelöst. Das
   Attribut ist schlicht ungültig, der Halt fällt auf Schwarz zurück, und
   niemand bekommt eine Fehlermeldung — die Figur ist nur plötzlich ein
   Schatten. Es muss eine Regel sein, und dafür braucht der Halt eine
   Klasse. */
.mu-s-haut     { stop-color: var(--mu-haut); }
.mu-s-haut-hell { stop-color: var(--mu-haut-hell); }
.mu-s-haut-tief { stop-color: var(--mu-haut-tief); }
.mu-s-band     { stop-color: var(--mu-band); }
.mu-s-bauch    { stop-color: var(--mu-bauch); }
.mu-s-kamm     { stop-color: var(--mu-kamm); }
.mu-s-kamm-tief { stop-color: var(--mu-kamm-tief); }
.mu-s-auge     { stop-color: var(--mu-auge); }
.mu-s-wange    { stop-color: var(--mu-wange); }
.mu-s-ast      { stop-color: var(--mu-ast); }
.mu-s-ast-tief { stop-color: var(--mu-ast-tief); }

/* Die Striche. Sie brauchen `stroke` statt `fill` und deshalb eigene
   Regeln; die Breite steht am Element, weil sie von Bein zu Bein und von
   Schwanzstück zu Schwanzstück verschieden ist. */
.mu-band      { stroke: var(--mu-band); }
/* Der helle Längsstreifen auf der Flanke — beim Tier trennt er den
   dunklen Rücken vom hellen Bauch. Er nimmt den Bauchton, weil er
   genau dessen Ausläufer ist. */
.mu-flanke    { stroke: var(--mu-bauch); }
/* Die beiden Falten auf dem Augentürmchen. Ein Chamäleon trägt sein Auge
   in einem beschuppten Hautkegel, und die Falten sind das, woran man den
   Kegel als Kegel erkennt statt als Scheibe. */
.mu-falte     { stroke: var(--mu-haut-tief); stroke-width: 1.1;
                fill: none; }
.mu-mund      { stroke: var(--mu-auge); stroke-width: 1.7; fill: none;
                stroke-linecap: round; }
.mu-bein      { stroke: var(--mu-haut-tief); fill: none;
                stroke-linecap: round; stroke-linejoin: round; }
.mu-schwanz-1 { stroke: var(--mu-haut-tief); stroke-width: 8.5; fill: none;
                stroke-linecap: round; }
.mu-schwanz-2 { stroke: var(--mu-haut-tief); stroke-width: 5.5; fill: none;
                stroke-linecap: round; }
.mu-schwanz-3 { stroke: var(--mu-haut-tief); stroke-width: 3; fill: none;
                stroke-linecap: round; }

/* --- und jetzt der eigentliche Trick: die Farbe je Sprache ---

   Am <body> steht ohnehin `data-paar`, seit es Sprachpaare gibt. Muno
   liest es mit und ist auf jeder englischen Seite dunkelblau, auf jeder
   spanischen golden, auf jeder italienischen grün. Es braucht dafür kein
   Skript, keine zweite Zeichnung und keine zweite Datei — nur diese
   sechs Blöcke, weil jede Fläche der Figur ihre Farbe über eine Marke
   bezieht und nicht eingebaut hat.

   Die Werte sind aus den Flaggentönen **gerechnet** und nicht von Hand
   gemischt: `maskottchen.farben()` hellt auf, dunkelt ab, entsättigt und
   sättigt. Aus zwei Tönen werden sieben. Wer einen ändern will, ändert
   ihn dort; `maskottchen` vergleicht beide Seiten und fällt über jede
   Abweichung.

   Der Ast fehlt hier mit Absicht: Ein Ast ist ein Ast. Wechselte er mit
   der Sprache, wäre die Farbe kein Zeichen mehr, sondern Muster.

   Warum die Haut nicht immer der erstgenannte Flaggenton ist, warum
   Spanisch golden und Portugiesisch rot ist: siehe FLAGGENTOENE.

   **Für `ruhe` steht hier mit Absicht kein Block.** Das ist der Wert für
   jede Seite, die keiner Sprache gehört — Startseite, Impressum,
   Fehler- und Offline-Seite —, und er bedeutet genau: nichts
   überschreiben. Es gelten dann die Werte auf `:root`, also das grüne
   Chamäleon mit den goldenen Bändern. Ein Block, der die `:root`-Werte
   noch einmal hinschreibt, wäre eine zweite Fassung derselben Farben und
   damit eine Stelle, an der sie auseinanderlaufen können.

   Die Angabe steht als eigenes `data-mufarbe` am Körper und **nicht** als
   `data-paar`: Jede Seite wird von einem Sprachpaar gebaut, auch die
   ohne Sprache — die deutsche Oberfläche liegt an der Wurzel. Solange
   die Farbe an `data-paar` hing, trug die Startseite ein englisch-blaues
   Chamäleon, und die Ruhefassung kam auf keiner einzigen Seite an. */
[data-mufarbe="ruhe"] {
  --mu-band:       #dd941a;
  --mu-bauch:      #d6e6db;
  --mu-haut:       #25a04b;
  --mu-haut-hell:  #5eb97a;
  --mu-haut-tief:  #1a7034;
  --mu-kamm:       #e7a230;
  --mu-kamm-tief:  #ab7824;
  --mu-wange:      #77895f;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-thema="hell"]) [data-mufarbe="ruhe"] {
    --mu-band:       #eda32b;
    --mu-bauch:      #dfece3;
    --mu-haut:       #31b45c;
    --mu-haut-hell:  #6ac989;
    --mu-haut-tief:  #227e40;
    --mu-kamm:       #f0ae3e;
    --mu-kamm-tief:  #b3822e;
    --mu-wange:      #86976c;
  }
}
:root[data-thema="dunkel"] [data-mufarbe="ruhe"] {
  --mu-band:       #eda32b;
  --mu-bauch:      #dfece3;
  --mu-haut:       #31b45c;
  --mu-haut-hell:  #6ac989;
  --mu-haut-tief:  #227e40;
  --mu-kamm:       #f0ae3e;
  --mu-kamm-tief:  #b3822e;
  --mu-wange:      #86976c;
}
[data-mufarbe="de-en"] {
  --mu-band:       #ee2a4a;
  --mu-bauch:      #f2f2f2;
  --mu-haut:       #012e93;
  --mu-haut-hell:  #4364af;
  --mu-haut-tief:  #01174a;
  --mu-kamm:       #f03d5b;
  --mu-kamm-tief:  #b22d43;
  --mu-wange:      #cccccc;
}
[data-mufarbe="de-es"] {
  --mu-band:       #f32a3e;
  --mu-bauch:      #faf2d5;
  --mu-haut:       #c89a00;
  --mu-haut-hell:  #d6b442;
  --mu-haut-tief:  #8c6c00;
  --mu-kamm:       #f43d50;
  --mu-kamm-tief:  #b52d3b;
  --mu-wange:      #d58533;
}
[data-mufarbe="de-fr"] {
  --mu-band:       #ef4135;
  --mu-bauch:      #f2f2f2;
  --mu-haut:       #0055a4;
  --mu-haut-hell:  #4281bc;
  --mu-haut-tief:  #003a6f;
  --mu-kamm:       #ef4439;
  --mu-kamm-tief:  #b1322a;
  --mu-wange:      #cccccc;
}
[data-mufarbe="de-it"] {
  --mu-band:       #de353d;
  --mu-bauch:      #f2f3ed;
  --mu-haut:       #008c45;
  --mu-haut-hell:  #42aa75;
  --mu-haut-tief:  #006230;
  --mu-kamm:       #e14750;
  --mu-kamm-tief:  #a6353b;
  --mu-wange:      #ccd1ba;
}
[data-mufarbe="de-pt"] {
  --mu-band:       #069d53;
  --mu-bauch:      #ffe900;
  --mu-haut:       #da291c;
  --mu-haut-hell:  #e46157;
  --mu-haut-tief:  #991d14;
  --mu-kamm:       #07b45f;
  --mu-kamm-tief:  #058546;
  --mu-wange:      #f5e000;
}
[data-mufarbe="en-de"] {
  --mu-band:       #686868;
  --mu-bauch:      #ffce00;
  --mu-haut:       #dd0000;
  --mu-haut-hell:  #e64242;
  --mu-haut-tief:  #930000;
  --mu-kamm:       #777777;
  --mu-kamm-tief:  #585858;
  --mu-wange:      #ffce00;
}

.muno-block {
  display: flex; gap: 1rem; align-items: center;
  background: var(--karte-2); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1rem 1.2rem; margin: 1.4rem 0;
}
/* **Kein Flex-Kasten.** Er war einer, und solange der Satz nur Text
   enthielt, fiel das nicht auf. Sobald eine Auszeichnung darin steht — und
   seit Muno je Sprache einen eigenen Satz sagt, tut sie das —, wird jedes
   Element darin zu einem eigenen Flex-Element, das nicht mit dem Text
   davor umbricht: Auf 320px lief der Absatz 146 Pixel über den Rand. Es
   ist dieselbe Falle wie beim Raster, und sie steht in der Anleitung: Der
   Kasten ändert still, was ein Kind *ist*.

   Ein Absatz ist ein Absatz. Was daneben stehen soll, steht inline. */
.muno-spruch {
  margin: 0; font-family: var(--schrift-titel); font-size: 1.05rem;
  line-height: 1.45; color: var(--ink); max-width: var(--lesebreite);
}
/* Der Haken steht nur bei der starken Runde und trägt die Erfolgsfarbe.
   `flex-shrink: 0`, weil ein Zeichen in einem Flex-Kasten sonst schmaler
   gedrückt wird, sobald der Satz lang wird — und ein zusammengedrückter
   Haken sieht aus wie ein Strich. */
.muno-spruch svg { vertical-align: -.15em; color: var(--ok-ink); }
/* Der Schalter zwischen Auswahl und Freitext, und die Lückenmarke.

   Zwei Knöpfe mit `aria-pressed` und kein Kästchen: Ein Kästchen mit der
   Aufschrift „Freitext" lässt offen, was passiert, wenn es leer ist. Zwei
   benannte Stellungen lassen nichts offen. */
.eingabewahl { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .6rem; }
.eingabewahl [aria-pressed="true"] {
  background: var(--marke); border-color: var(--marke); color: var(--knopf-ink);
}

/* Die Lücke in der Auswahl: eine Marke, kein Feld. Ein Feld, das man
   anfassen kann und das nichts bewirkt, ist schlimmer als keins. */
.luecke-marke {
  display: inline-block; min-width: 4.5rem; border-bottom: 2px solid var(--marke);
  margin: 0 .15rem; vertical-align: baseline;
}

/* Die Aussprache-Feinheiten.

   Jedes Beispiel ist ein Satz mit Lautsprecher und darunter der Hinweis,
   worauf zu hören ist. Der Hinweis ist der eigentliche Inhalt — ohne ihn
   wäre es eine Satzliste, und eine Satzliste bringt niemandem bei,
   worauf er hören soll. */
.fein { margin: 2.5rem 0 0; }
.fein-punkt { margin: 2rem 0; }
.fein-kopf { display: flex; align-items: baseline; gap: .6rem;
             flex-wrap: wrap; }
.fein-kopf h3 { margin: 0; font-size: 1.25rem; }
.fein-frage {
  margin: .4rem 0 .9rem; font-family: var(--schrift-titel);
  font-size: 1.05rem; color: var(--ink-2); font-style: italic;
  max-width: var(--lesebreite);
}
.fein-beispiele { list-style: none; margin: 1rem 0 0; padding: 0;
                  display: grid; gap: .9rem; }
.fein-beispiel {
  border-left: 3px solid var(--marke); padding: .1rem 0 .1rem .9rem;
  max-width: var(--lesebreite);
}
.fein-beispiel .satzpaar { margin: 0; }
.fein-achten {
  margin: .35rem 0 0; font-size: .9rem; color: var(--ink-3);
  line-height: 1.45;
}

/* Die Sprachgeschichte.

   Die Lautregeln sind Karten und keine Tabelle: Eine Tabelle mit sechs
   Zeilen und acht Beispielspalten ist auf einem Telefon nicht zu lesen,
   und die Regel steht in der Überschrift — „ss, ß → t" ist die ganze
   Aussage, alles andere ist Beleg. */
.lautregeln {
  display: grid; gap: 1rem; margin: 1.4rem 0 2rem;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}
.lautregel {
  background: var(--karte-2); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1rem 1.1rem;
}
.lautregel h3 {
  margin: 0 0 .3rem; display: flex; align-items: center; gap: .5rem;
  font-size: 1.05rem;
}
.lr-form {
  font-family: var(--schrift-titel); font-weight: 700;
  background: var(--marke-weich); color: var(--ink);
  padding: .1rem .5rem; border-radius: .4rem;
}
.lr-form-en { background: var(--akzent-weich); }
.lr-pfeil { color: var(--ink-3); }
.lr-wo { margin: 0 0 .5rem; font-size: .85rem; }
.lautregel p { margin: 0 0 .7rem; color: var(--ink-2); font-size: .95rem;
               line-height: 1.5; }
.lr-paare { list-style: none; margin: 0; padding: 0; display: grid;
            gap: .2rem; }
.lr-paare li {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: baseline; gap: .5rem; font-size: .92rem;
  padding: .18rem 0; border-top: 1px solid var(--linie);
}
.lr-paare li:first-child { border-top: none; }
.lr-de { color: var(--ink-3); text-align: right; }
.lr-en { color: var(--ink); font-weight: 600; }

.gs-kapitel { margin: 2.2rem 0; max-width: var(--lesebreite); }
.gs-kopf { display: flex; align-items: baseline; gap: .7rem;
           flex-wrap: wrap; }
.gs-kopf h2 { margin: 0; }
.gs-jahr {
  font-size: .8rem; font-weight: 600; letter-spacing: .05em;
  color: var(--marke); background: var(--marke-weich);
  padding: .15rem .5rem; border-radius: var(--rund-voll);
}
.gs-frage {
  margin: .5rem 0 1rem; font-family: var(--schrift-titel);
  font-size: 1.08rem; color: var(--ink-2); font-style: italic;
}
/* „Was das für Sie heißt" ist der Grund, warum das Kapitel hier steht und
   nicht in einem Lexikon. Deshalb steht es abgesetzt und nicht als
   letzter Absatz — ein Ausgang, den man überliest, ist keiner. */
.gs-heisst {
  margin-top: 1.1rem; border-left: 3px solid var(--marke);
  background: var(--karte-2); border-radius: var(--rund);
  padding: .9rem 1.1rem;
}
.gs-heisst-marke {
  margin: 0 0 .4rem; font-size: .8rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--marke); font-weight: 600;
}
.gs-heisst p { margin: 0; color: var(--ink); }
.gs-heisst ul { margin: .7rem 0 0; padding-left: 1.1rem; }
.gs-heisst li { margin: .2rem 0; }

@media (max-width: 520px) {
  .lr-paare li { grid-template-columns: 1fr auto 1fr; font-size: .88rem; }
}

/* Die Grammatikmatrix: 15 Bereiche mal 6 Stufen.

   Auf dem Schreibtisch ein echtes Gitter — nebeneinander sagt die
   Zuordnung etwas, das eine Liste nicht sagen kann. Auf dem Telefon ist
   ein Gitter mit sieben Spalten dagegen unlesbar, und deshalb wird es
   dort zu einer Folge von Bereichen, in denen die Stufe über ihrer
   Zelle steht.

   Derselbe HTML-Code für beides: Die Zelle trägt ihre Stufe im
   `data-stufe`, und die schmale Fassung zeigt sie über `content:
   attr(...)`. Eine zweite Auszeichnung für die zweite Breite wäre eine
   zweite Wahrheit. */
.gr-matrix { margin: 1.6rem 0 2.4rem; }
.gr-legende {
  display: grid; gap: .5rem; margin: 1rem 0 1.2rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.gr-stufe {
  display: block; text-decoration: none; color: inherit;
  border-left: 3px solid var(--st, var(--marke));
  background: var(--karte-2); border-radius: var(--rund);
  padding: .55rem .75rem;
}
.gr-stufe:hover, .gr-stufe:focus-visible { background: var(--karte); }
/* `width: fit-content`, sonst zieht sich die Marke auf die volle Breite
   der Karte und liest sich als Balken statt als Schild. */
.gr-stufe .stufe-punkt { margin-bottom: .35rem; width: fit-content; }
.gr-stufe span { display: block; font-size: .85rem; color: var(--ink-3);
                 line-height: 1.35; }

.gr-gitter {
  display: grid;
  grid-template-columns: minmax(9rem, 13rem) repeat(6, minmax(0, 1fr));
  gap: 1px; background: var(--linie);
  border: 1px solid var(--linie); border-radius: var(--rund);
  overflow: hidden;
}
.gr-kopf {
  background: var(--karte-2); padding: .5rem .6rem;
  font-family: var(--schrift-titel); font-weight: 600; font-size: .9rem;
  color: var(--ink-2); text-align: center;
}
.gr-ecke { background: var(--karte-2); }
.gr-name {
  background: var(--karte-2); padding: .6rem .7rem; font-size: .9rem;
  display: flex; align-items: center;
}
.gr-name a { color: var(--ink); text-decoration: none; font-weight: 600; }
.gr-name a:hover { text-decoration: underline; }
.gr-zelle {
  background: var(--karte); padding: .4rem; display: flex;
  flex-direction: column; gap: .25rem;
}
.gr-chip {
  display: block; font-size: .78rem; line-height: 1.25;
  padding: .22rem .4rem; border-radius: .35rem;
  background: var(--karte-2); color: var(--ink-2); text-decoration: none;
}
.gr-chip:hover, .gr-chip:focus-visible {
  background: var(--marke-weich); color: var(--ink);
}
.gr-lese { margin-top: 1.1rem; }
.gr-lese p { color: var(--ink-2); }

@media (max-width: 900px) {
  /* Sieben Spalten auf einem Telefon sind keine Übersicht, sondern eine
     Tapete. Dieselbe Zuordnung, untereinander. */
  .gr-gitter { display: block; background: none; border: none;
               border-radius: 0; }
  .gr-kopf { display: none; }
  .gr-name {
    background: none; padding: 1.1rem 0 .4rem; font-size: 1.05rem;
    font-family: var(--schrift-titel);
  }
  /* Antippbar, nicht nur anklickbar. Auf 390 Pixeln maß `layout` die
     Marken mit 23 Pixeln Höhe und die Bereichszeile mit 28 — beides
     unter dem, was ein Daumen zuverlässig trifft. Auf dem Schreibtisch
     bleiben sie klein: Dort ist die Dichte der Zweck der Matrix. */
  .gr-name a { display: block; padding: .4rem 0; }
  .gr-zelle {
    background: none; padding: 0 0 0 3.2rem; position: relative;
    margin-bottom: .35rem;
    /* Marken fließen statt zu stapeln: Auf einem Telefon ist die Höhe
       das knappe Gut, nicht die Breite. */
    display: block;
  }
  .gr-zelle:empty { display: none; }
  .gr-zelle::before {
    content: attr(data-stufe); position: absolute; left: 0; top: .22rem;
    font-size: .78rem; font-weight: 600; color: var(--ink-3);
    letter-spacing: .04em;
  }
  .gr-chip {
    display: inline-block; margin: 0 .25rem .3rem 0;
    padding: .5rem .65rem; font-size: .85rem; line-height: 1.3;
    /* Die Untergrenze steht in `tools/layout_pruefen.mjs`: 32 Pixel.
       Aus Polsterung und Zeilenhöhe zusammengerechnet kam der erste
       Versuch auf 31 — die Prüfung meldete drei Marken, und sie hatte
       recht: Ein Ziel, das der Daumen um einen Pixel verfehlt, verfehlt
       er ganz. */
    min-height: 32px;
  }
}

/* Das Bedarfsfeld und die Anlassseiten.

   Das Feld steht bewusst groß und allein da: Es ist der einzige Grund,
   diese Seite zu öffnen, und alles darunter ist Nachschlagewerk. */
.bedarf {
  display: flex; flex-wrap: wrap; gap: .7rem; align-items: flex-end;
  background: var(--karte-2); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1.2rem 1.3rem; margin: 1.4rem 0 0;
}
.bedarf label {
  flex: 1 1 100%; font-size: .82rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--marke); font-weight: 600;
}
.bedarf input { flex: 1 1 16rem; }
.bedarf-treffer { margin-top: 1rem; }
.bedarf-zahl { margin: 0 0 .6rem; }

.anl-liste { list-style: none; margin: 1rem 0 0; padding: 0;
             display: grid; gap: .7rem; }
.anl-raster { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.anl-karte {
  display: block; text-decoration: none; padding: .85rem 1rem;
  border: 1px solid var(--linie); border-radius: var(--rund);
  background: var(--karte); color: inherit;
}
.anl-karte:hover, .anl-karte:focus-visible {
  border-color: var(--marke); background: var(--karte-2);
}
.anl-karte b { display: block; font-family: var(--schrift-titel);
               font-size: 1.02rem; color: var(--ink); }
.anl-karte span { display: block; margin-top: .25rem; font-size: .9rem;
                  color: var(--ink-3); }
.anl-gross b { font-size: 1.08rem; }

/* Eine Wendung ist drei Zeilen: der Satz, seine Übersetzung, und der
   Moment, in dem man ihn braucht. Der dritte ist der eigentliche Inhalt —
   ohne ihn wäre es eine Vokabelliste mit längeren Einträgen. */
.wendungsliste { list-style: none; margin: 1rem 0 0; padding: 0;
                 display: grid; gap: .8rem; }
.wendung {
  border-left: 3px solid var(--marke); padding: .1rem 0 .1rem .9rem;
}
.wendung-en { margin: 0; font-size: 1.05rem; color: var(--ink); }
.wendung-de { margin: .15rem 0 0; color: var(--ink-2); }
.wendung-wann { margin: .3rem 0 0; font-size: .9rem; color: var(--ink-3); }

/* Der Wegweiser: der eine Rat, über allem anderen.

   Er ist kräftiger gesetzt als eine gewöhnliche Karte, weil er auf einer
   Seite mit achtzehn Karten sonst die neunzehnte wäre. Kräftiger heißt
   hier: eine Kante in der Markenfarbe an der linken Seite und sonst nichts.
   Ein voll eingefärbter Kasten würde die Karten darunter zu Beiwerk machen,
   und sie sind es nicht — der Rat ist ein Rat und keine Ansage. */
.ww {
  border-left: 3px solid var(--marke);
  background: var(--karte-2);
  margin: 1.4rem 0 0;
}
.ww-marke {
  margin: 0 0 .5rem; font-size: .82rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--marke); font-weight: 600;
}
.ww-titel {
  margin: 0 0 .45rem; font-family: var(--schrift-titel); font-size: 1.2rem;
  font-weight: 600; color: var(--ink);
}
.ww-grund {
  margin: 0; color: var(--ink-2); max-width: var(--lesebreite);
  line-height: 1.55;
}
.ww-weiter { margin: 1rem 0 0; }

/* Der Etappenschluss: Muno am Ende einer Runde.

   Er darf etwas mehr Aufmerksamkeit haben als ein Muno im Fließtext — es ist
   der Moment, in dem jemand entscheidet, ob eine zweite Runde folgt. Mehr
   aber auch nicht: Ein Konfettifeld nach jeder Runde ist an der dritten
   durchschaut, und was nach jeder Runde jubelt, jubelt nach keiner.

   Die ruhige Pose bekommt den stilleren Grund. Nach einer harten Runde ist
   ein warm leuchtender Kasten nicht freundlich, sondern taktlos. */
.etappe { margin: 1.5rem 0 0; background: var(--marke-weich);
          border-color: transparent; }
.etappe[data-pose="ruht"] { background: var(--karte-2);
                            border-color: var(--linie); }
.etappe .muno { width: 84px; height: 84px; }
.etappe-weiter { margin: .9rem 0 0; }
@media (max-width: 520px) {
  .etappe { flex-direction: column; align-items: flex-start; }
}

.muno-vorstellung { align-items: flex-start; padding: 1.3rem 1.4rem; }
.muno-vorstellung .muno { width: 116px; height: 116px; }
.muno-name {
  margin: 0 0 .35rem; font-family: var(--schrift-titel); font-weight: 600;
  font-size: 1.15rem; color: var(--ink);
}
.muno-nach { margin-top: .55rem; color: var(--ink-2); font-size: 1rem; }
@media (max-width: 640px) {
  .muno-vorstellung { flex-direction: column; gap: .6rem; }
  .muno-vorstellung .muno { width: 84px; height: 84px; }
}
@media (max-width: 520px) {
  .muno-block { gap: .8rem; padding: .9rem 1rem; }
  .muno { width: 68px; height: 68px; }
}

/* Kategoriesymbole — ein Strich, keine Fläche.

   currentColor und stroke, damit ein Symbol die Farbe seiner Kachel annimmt
   und in beiden Farbfassungen stimmt. Ein gefülltes Symbol müsste zwei
   Farbwerte kennen und kennt sie nicht. */

.kat-symbol {
  width: 1.5rem; height: 1.5rem; flex: none;
  color: var(--marke-ink); opacity: .9;
}
.kat-symbol-gross { width: 2.2rem; height: 2.2rem; }
.kat-titelzeile { display: flex; align-items: center; gap: .7rem; }
.kat-titelzeile h2, .kat-titelzeile h1 { margin: 0; }

/* Ähnliche Wörter — je Paar eine Karte.

   Warum Karten und keine Tabelle: Bei den falschen Freunden trägt eine
   Tabelle, weil jede Zeile dieselben vier Felder hat. Hier hat jeder
   Eintrag zwei oder drei Wörter mit je zwei Sätzen, dazu den Griff und die
   Probe — das sind fünf Blöcke ungleicher Länge, und die in Spalten zu
   zwingen hieße, sie alle auf die längste zu ziehen. */

.aw-liste { display: grid; gap: 1.2rem; margin: 1.2rem 0 2rem; }
@media (min-width: 62rem) {
  .aw-liste { grid-template-columns: repeat(2, 1fr); }
}
.aw-karte {
  border: 1px solid var(--linie); border-radius: var(--rund-l);
  background: var(--karte); padding: 1.2rem 1.3rem;
  display: flex; flex-direction: column; gap: .85rem;
}
.aw-kopf { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.aw-kopf h3 { margin: 0; font-size: 1.15rem; }

.aw-woerter { display: grid; gap: .8rem; margin: 0; padding: 0;
              list-style: none; }
.aw-wort {
  display: grid; gap: .1rem;
  border-left: 3px solid var(--marke); padding-left: .9rem;
}
.aw-wort > .ziel { font-size: 1.02rem; }
.aw-bedeutung { color: var(--ink-2); font-size: .95rem; }
.aw-satz { font-size: .92rem; margin-top: .25rem; }
.aw-satz.de { color: var(--ink-3); margin-top: 0; }

/* Der Griff ist der Grund, warum es diese Seite gibt — er bekommt deshalb
   die Fläche und nicht eine Fußnote. */
.aw-griff { background: var(--marke-weich); border-color: transparent; }
.aw-griff p:last-child { margin-bottom: 0; }

.aw-probe {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem;
  margin: 0; padding-top: .2rem; border-top: 1px solid var(--linie);
}
.aw-probe-marke {
  font-size: .8rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3);
}
.aw-probe .ziel { flex: 1 1 12rem; }
.aw-loesung {
  background: var(--bg-tief); border-radius: var(--rund-voll);
  padding: .12rem .6rem; font-weight: 600; font-size: .92rem;
}

/* Die Suche auf der Startseite.

   Sie sitzt in der Bühne unter den beiden Knöpfen und nicht darüber: Wer
   zum ersten Mal hier ist, soll zuerst lesen, worum es geht. Wer etwas
   Bestimmtes sucht, findet ein Suchfeld auch, wenn es an zweiter Stelle
   steht — er sucht ja danach.

   Die Trefferliste wächst nach unten in die Seite hinein statt als Überlage
   darüber. Eine Überlage auf der Startseite verdeckt genau das, was den
   ersten Eindruck ausmacht, und sie muss weggeklickt werden. */

.startsuche { margin-top: 1.6rem; max-width: 34rem; }
.sts-zeile {
  display: flex; align-items: center; gap: .5rem;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund-voll); padding: .3rem .4rem .3rem .9rem;
  box-shadow: var(--schatten-1);
}
.sts-zeile:focus-within { border-color: var(--marke); }
.sts-zeile > svg { width: 19px; height: 19px; flex: none; color: var(--ink-3); }
.sts-zeile input {
  flex: 1 1 auto; min-width: 0; border: 0; background: none;
  font: inherit; color: var(--ink); padding: .55rem 0;
}
.sts-zeile input:focus { outline: none; }
.sts-zeile input::placeholder { color: var(--ink-3); }
.sts-zeile > .knopf-still { flex: none; border-radius: var(--rund-voll); }

.sts-stand { margin: .6rem .2rem 0; min-height: 0; }
.sts-stand:empty { display: none; }

.sts-liste { display: grid; gap: .3rem; margin-top: .5rem; }
.sts-liste:empty { display: none; }
.sts-treffer {
  display: flex; align-items: center; gap: .7rem;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: .6rem .8rem;
  text-decoration: none; color: var(--ink);
}
.sts-treffer:hover, .sts-treffer:focus-visible {
  border-color: var(--marke); background: var(--karte-2);
}
.sts-text { display: grid; gap: .1rem; min-width: 0; flex: 1 1 auto; }
.sts-name { font-weight: 600; }
.sts-kurz {
  color: var(--ink-3); font-size: .88rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sts-bereich {
  flex: none; font-size: .78rem; color: var(--ink-3);
  background: var(--bg-tief); border-radius: var(--rund-voll);
  padding: .12rem .55rem;
}
.sts-alle { justify-content: center; background: var(--marke-weich);
            border-color: transparent; }

/* `--ink-2` und nicht `--ink-3`: Diese Zeile steht auf der Startseite über
   der bewegten Fläche, und dort ist der Untergrund nicht die Seitenfarbe,
   sondern das, was der Canvas gerade gemalt hat. `tools/thema_pruefen.mjs`
   misst gegen genau diesen Pixel und kam auf 3,94:1 — nötig sind 4,5:1.
   Eine leise Farbe über einem ruhigen Grund ist etwas anderes als eine
   leise Farbe über einem, der sich bewegt. */
.sts-hinweis {
  margin: .7rem .2rem 0; font-size: .86rem; color: var(--ink-2);
}
.startsuche[data-offen] .sts-hinweis { display: none; }

@media (max-width: 520px) {
  .sts-zeile > .knopf-still { display: none; }
  .sts-bereich { display: none; }
}

/* Die Auswertungskarten — aufklappbar, mit der Zahl außen.

   Warum die Zahl in der Zusammenfassung steht und nicht erst drinnen:
   Zwanzig geschlossene Aufklapper sind schlechter als zwanzig offene
   Karten — man sieht nichts und muss raten, wo etwas steht. Mit der Zahl
   außen ist die zugeklappte Seite eine Übersicht und die aufgeklappte der
   Graph dahinter. */

.aus-karte {
  border: 1px solid var(--linie); border-radius: var(--rund-l);
  background: var(--karte); margin: 0 0 .8rem; overflow: hidden;
  box-shadow: var(--schatten-1);
}
.aus-karte > summary {
  display: flex; align-items: center; gap: .8rem;
  padding: 1rem 1.2rem; cursor: pointer; list-style: none;
  min-height: 3rem;
}
.aus-karte > summary::-webkit-details-marker { display: none; }
.aus-karte > summary::after {
  content: ''; flex: none; margin-left: .2rem;
  width: .5rem; height: .5rem; border-right: 2px solid var(--ink-3);
  border-bottom: 2px solid var(--ink-3); transform: rotate(45deg);
  transition: transform .18s ease;
}
.aus-karte[open] > summary::after { transform: rotate(-135deg); }
.aus-karte > summary:hover { background: var(--karte-2); }
.aus-karte > summary:focus-visible {
  outline: 2px solid var(--marke); outline-offset: -2px;
}
.aus-titel {
  font-family: var(--schrift-titel); font-weight: 600; font-size: 1.08rem;
  color: var(--ink); flex: 1 1 auto; min-width: 0;
}
.aus-kennzahl {
  flex: none; font-size: .9rem; font-weight: 600; color: var(--marke-ink);
  background: var(--marke-weich); border-radius: var(--rund-voll);
  padding: .18rem .7rem; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.aus-inhalt { padding: 0 1.2rem 1.2rem; }
.aus-inhalt > :first-child { margin-top: 0; }

/* Der Schalter über den Karten: alles auf, alles zu. */
.aus-schalter {
  display: flex; gap: .5rem; flex-wrap: wrap; align-items: center;
  margin: 0 0 1rem;
}
.aus-schalter > .zeile-still { margin: 0 0 0 auto; }

@media (max-width: 520px) {
  .aus-karte > summary { padding: .85rem .9rem; gap: .5rem; }
  .aus-titel { font-size: 1rem; }
  .aus-kennzahl { font-size: .82rem; padding: .15rem .55rem; }
  .aus-inhalt { padding: 0 .9rem 1rem; }
}

/* --- 7. Ueben ------------------------------------------------------------ */

/* Eine Aufgabe ist ein Satz, den man liest. Auf 1280 Pixeln zieht sich die
   Karte sonst über die volle Fensterbreite, und der englische Beispielsatz
   steht als eine einzige lange Zeile darin — genau das Maß, bei dem das Auge
   die Zeile verliert. */
.uebung-karte {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund-l); box-shadow: var(--schatten-2);
  overflow: hidden; margin-top: 1.4rem;
  max-width: 46rem;
}
.uebung-kopf {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  padding: .75rem 1.1rem; border-bottom: 1px solid var(--linie);
  background: var(--bg-tief); font-size: .88rem; color: var(--ink-3);
}
.uebung-koerper { padding: 1.5rem 1.3rem; }
.uebung-frage { font-size: 1.15rem; line-height: 1.55; margin-bottom: 1.2rem; }
.uebung-frage .luecke-feld { display: inline-block; }

.luecke-feld, .antwort-feld {
  font: inherit; color: var(--ink);
  background: var(--bg-tief);
  border: 1px solid var(--linie-kraeftig);
  border-bottom-width: 2px;
  border-radius: var(--rund-s);
  padding: .3rem .6rem;
  min-width: 8rem;
}
.antwort-feld { width: 100%; padding: .65rem .8rem; }
.luecke-feld:focus, .antwort-feld:focus { border-color: var(--marke); background: var(--karte); }
.luecke-feld[data-stand="richtig"] { border-color: var(--ok); background: var(--ok-weich); }
.luecke-feld[data-stand="falsch"] { border-color: var(--fehler); background: var(--fehler-weich); }

.wahlliste { display: grid; gap: .5rem; list-style: none; margin: 0 0 1.2rem; padding: 0; }
.wahl-knopf {
  display: flex; align-items: flex-start; gap: .7rem; width: 100%;
  text-align: left; font: inherit; color: var(--ink);
  background: var(--karte-2); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: .7rem .9rem; cursor: pointer;
  position: relative;
  transition: border-color .15s, background .15s, transform .1s;
}
.wahl-knopf:hover:not([disabled]) { border-color: var(--linie-kraeftig); background: var(--bg-tief); }
.wahl-knopf:active:not([disabled]) { transform: translateY(1px); }
/* Ziffern und nicht Buchstaben, seit die Auswahl mit der Tastatur geht:
   Die Beschriftung IST die Taste. Ein „c)" neben einer Antwort, die man mit
   der 3 waehlt, waere eine Uebersetzungsaufgabe vor der Uebungsaufgabe. */
.wahl-ziffer {
  font-weight: 700; color: var(--ink-3); flex: none;
  font-variant-numeric: tabular-nums;
}
.wahl-knopf[data-stand="richtig"] { border-color: var(--ok); background: var(--ok-weich); }
.wahl-knopf[data-stand="falsch"] { border-color: var(--fehler); background: var(--fehler-weich); }
/* Rot und Gruen allein reichen nicht — bei Rotgruenblindheit sind das zwei
   gleich helle Flaechen. Deshalb zusaetzlich Haken und Kreuz. */
.wahl-knopf[data-stand]::after {
  position: absolute; right: .8rem; top: .65rem; font-weight: 700;
}
.wahl-knopf[data-stand="richtig"]::after { content: "✓"; color: var(--ok-ink); }
.wahl-knopf[data-stand="falsch"]::after { content: "✕"; color: var(--fehler); }

/* --- Die Woerter eines Satzes als Knoepfe -------------------------------- */
/* „Finde den Fehler" braucht keine erfundenen Ablenker: Die Woerter des
   Satzes sind die Auswahl. Deshalb sehen sie auch nicht aus wie eine Liste
   von Antworten, sondern wie der Satz — nebeneinander, in der Reihenfolge,
   die die Bedeutung traegt. Ein Wort, das aus der Zeile faellt, waere ein
   Wort, das aus dem Satz faellt. */
.wortwahl {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: .25rem .35rem;
}
.wortwahl-knopf {
  font: inherit; color: inherit; line-height: 1.5;
  background: var(--karte-2); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: .15em .45em; cursor: pointer;
  position: relative;
  transition: border-color .15s, background .15s, transform .1s;
}
.wortwahl-knopf:hover:not([disabled]) {
  border-color: var(--linie-kraeftig); background: var(--bg-tief);
}
.wortwahl-knopf:active:not([disabled]) { transform: translateY(1px); }
.wortwahl-knopf[data-stand="richtig"] {
  border-color: var(--ok); background: var(--ok-weich);
}
.wortwahl-knopf[data-stand="falsch"] {
  border-color: var(--fehler); background: var(--fehler-weich);
}
/* Wie bei der Antwortliste: Farbe allein traegt die Auskunft nicht. Der
   Haken steht hier hinter dem Wort statt in der Ecke — ein Knopf von der
   Groesse eines Wortes hat keine Ecke, in die etwas passt. */
.wortwahl-knopf[data-stand]::after { font-weight: 700; margin-left: .3em; }
.wortwahl-knopf[data-stand="richtig"]::after { content: "✓"; color: var(--ok-ink); }
.wortwahl-knopf[data-stand="falsch"]::after { content: "✕"; color: var(--fehler); }

/* --- Dranbleiben: Woche, Serie, Meilensteine ----------------------------- */

/* Sieben Kaestchen statt eines Balkens. Ein Balken sagt „drei von fuenf" und
   verschweigt, an welchen Tagen — und die Frage, die jemand wirklich hat,
   ist „welcher Tag ist mir durchgerutscht?". */
.wochenreihe {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: .35rem;
}
.wochentag {
  display: flex; flex-direction: column; align-items: center; gap: .1rem;
  padding: .5rem .2rem; border-radius: var(--rund);
  border: 1px solid var(--linie); background: var(--karte-2);
}
.wochentag-name { font-size: .82rem; color: var(--ink-3); letter-spacing: .04em; }
.wochentag-zahl { font-weight: 700; font-variant-numeric: tabular-nums; }
.wochentag[data-stand="voll"] {
  border-color: var(--ok); background: var(--ok-weich);
}
.wochentag[data-stand="voll"] .wochentag-zahl { color: var(--ok-ink); }
.wochentag[data-stand="angefangen"] { border-color: var(--linie-kraeftig); }
/* Ein Tag, der noch kommt, ist kein verpasster Tag. Er sieht deshalb auch
   nicht aus wie einer: kein Rahmen, keine Null, nur ein Punkt. */
.wochentag[data-stand="kommt"] {
  border-style: dashed; opacity: .55; background: transparent;
}

/* Das Wort auf der Lernkarte. Gross, weil es das Einzige ist, worum es
   geht — und mit dem Lautsprecher in derselben Zeile statt darunter: Ein
   Knopf in eigener Zeile sieht aus wie der naechste Schritt, und der
   naechste Schritt ist hier das Antworten. */
.lernkarte-wort {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin: 0 0 .2rem;
}
.lernkarte-wort .ziel {
  font-family: var(--schrift-titel); font-size: 1.9rem; font-weight: 600;
  line-height: 1.2;
}

.serie-zahl { margin: 0; line-height: 1.1; }
.serie-zahl b {
  font-family: var(--schrift-titel); font-size: 2.6rem; font-weight: 700;
  color: var(--marke-ink); font-variant-numeric: tabular-nums;
}
.serie-zahl span { color: var(--ink-3); margin-left: .3rem; }

.marke-titel { margin: 0 0 .5rem; font-weight: 600; }
.balken-zeile[data-erreicht="ja"] { color: var(--ink); }
.balken-zeile[data-erreicht="nein"] { color: var(--ink-3); }

/* Zwei Zahlenfelder nebeneinander, solange Platz ist. Auf dem Telefon
   untereinander — zwei halbe Eingabefelder auf 320 Pixeln sind zwei
   Eingabefelder, in die niemand tippen kann. */
.zielfelder { display: grid; gap: .8rem; }
@media (min-width: 30rem) {
  .zielfelder { grid-template-columns: 1fr 1fr; align-items: end; }
}

/* Ein Minimalpaar ist ein Vergleich, und ein Vergleich will beide Haelften
   im selben Blick. Erst ab 420px: Darunter stehen zwei Knoepfe nebeneinander
   so eng, dass der Haken hinter dem Wort sitzt statt daneben — und die
   Auskunft, die nicht nur an der Farbe haengen soll, waere die erste, die
   verlorengeht. */
@media (min-width: 420px) {
  .wahlliste-paar { grid-template-columns: 1fr 1fr; }
  .wahlliste-paar .wahl-knopf {
    align-items: center; justify-content: center;
    padding: 1.1rem .9rem; font-size: 1.1rem;
  }
}

.karten-legen { display: flex; flex-wrap: wrap; gap: .45rem; margin-bottom: 1rem; min-height: 3rem; }
.wortkarte {
  font: inherit; background: var(--karte-2); color: var(--ink);
  border: 1px solid var(--linie-kraeftig); border-radius: var(--rund-s);
  padding: .4rem .75rem; cursor: pointer;
}
.wortkarte:hover { border-color: var(--marke); }

/* --- Tastatur ------------------------------------------------------------
   Die Ziffer auf der Karte und die Zeile in der Fußleiste stehen nur da, wo
   es eine Tastatur gibt. Auf einem Telefon wären beide eine Auskunft über
   etwas, das es dort nicht gibt — und die Ziffer nähme dem Wort Platz weg,
   den es auf 320 Pixeln nicht hat. */
.tastenhilfe { display: none; }

@media (hover: hover) and (pointer: fine) {
  .tastenhilfe {
    display: inline; margin-left: auto;
    font-size: .78rem; color: var(--ink-3);
    letter-spacing: .01em; white-space: nowrap;
  }
  .karten-legen .wortkarte[data-ziffer]::before {
    content: attr(data-ziffer);
    margin-right: .45rem; font-weight: 700; font-size: .78em;
    color: var(--ink-3); font-variant-numeric: tabular-nums;
  }
  /* Gelegt ist gelegt: Im Ziel führt die Ziffer nicht mehr irgendwohin. */
  .karten-ziel .wortkarte[data-ziffer]::before { content: none; }
}
.karten-ziel {
  border: 2px dashed var(--linie-kraeftig); border-radius: var(--rund);
  padding: .7rem; min-height: 3.4rem; display: flex; flex-wrap: wrap; gap: .45rem;
  background: var(--bg-tief);
}

/* --- Schnellsuche --------------------------------------------------------
   Ein <dialog>, kein eigenes Overlay: Der Browser sperrt die Seite dahinter,
   faengt die Tabulatortaste ein und macht die Esc-Taste von selbst richtig.
   Das alles noch einmal zu schreiben hiesse, es an drei Stellen falsch zu
   machen.

   Sie sitzt oben und nicht in der Mitte: Ein Feld, das mittig aufgeht,
   springt beim Tippen mit der wachsenden Trefferliste. */
.schnellsuche {
  width: min(38rem, calc(100vw - 2rem));
  margin: 8vh auto auto;
  padding: 0;
  border: 1px solid var(--linie-kraeftig);
  border-radius: var(--rund);
  background: var(--karte);
  color: var(--ink);
  box-shadow: var(--schatten-2, var(--schatten-1));
  overflow: hidden;
}
.schnellsuche::backdrop {
  background: rgba(10, 12, 16, .5);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.ss-kopf {
  display: flex; align-items: center; gap: .6rem;
  padding: .7rem .8rem; border-bottom: 1px solid var(--linie);
}
.ss-feld {
  flex: 1; font: inherit; font-size: 1.05rem; color: var(--ink);
  background: transparent; border: 0; padding: .35rem .2rem;
}
.ss-feld:focus { outline: none; }
.ss-zu {
  flex: none; font-size: .75rem; letter-spacing: .04em;
  border: 1px solid var(--linie-kraeftig); border-radius: var(--rund-s);
  padding: .15rem .45rem; color: var(--ink-3);
}
.ss-liste { max-height: min(24rem, 52vh); overflow-y: auto; padding: .4rem; }
.ss-zeile {
  display: flex; align-items: center; gap: .7rem; width: 100%;
  text-align: left; font: inherit; color: var(--ink);
  background: transparent; border: 0; border-radius: var(--rund-s);
  padding: .5rem .6rem; cursor: pointer;
}
/* Ein Zeiger, der der Tastatur folgt, und einer, der der Maus folgt, wären
   zwei Zeiger. Beide setzen dasselbe Attribut, also gibt es immer nur den
   einen — und `:hover` steht hier deshalb absichtlich nicht. */
.ss-zeile[data-aktiv] { background: var(--marke-weich); }
.ss-text { flex: 1; min-width: 0; display: grid; }
.ss-text .thema-name { font-weight: 600; }
.ss-text .thema-kurz,
.ss-zeile .thema-stand {
  color: var(--ink-3); font-size: .82rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ss-zeile .thema-stand { flex: none; max-width: 9rem; }
.ss-mehr { border-top: 1px solid var(--linie); border-radius: 0; margin-top: .3rem; }
.ss-stand {
  margin: 0; padding: .55rem .9rem; font-size: .78rem;
  border-top: 1px solid var(--linie); background: var(--bg-tief);
}

@media (max-width: 30rem) {
  .schnellsuche { margin-top: 3vh; }
  .ss-zeile .thema-stand { display: none; }
}

.aufloesung {
  border-radius: var(--rund); padding: 1.1rem 1.2rem; margin-top: 1.2rem;
  background: var(--karte-2); border: 1px solid var(--linie);
}
.aufloesung[data-stand="richtig"] { background: var(--ok-weich); border-color: transparent; }
.aufloesung[data-stand="falsch"] { background: var(--fehler-weich); border-color: transparent; }
.aufloesung-kopf { display: flex; align-items: center; gap: .5rem; font-weight: 700; margin-bottom: .6rem; }
.aufloesung-kopf svg { width: 20px; height: 20px; }

/* --- Diktat: der Satz, Wort für Wort ------------------------------------
   Die Marken sitzen auf dem gesprochenen Satz, nicht auf dem geschriebenen.
   Ein durchgestrichenes Wort ist deshalb genau eines: das, was zu viel
   geschrieben wurde. Alles andere ist das, was hätte dastehen sollen, und
   das durchzustreichen hieße das Gegenteil.

   Die Farbe ist nie die einzige Auskunft: `title` sagt es in Worten, und
   Unterstreichung, Rahmen und Durchstreichung unterscheiden die vier Fälle
   auch für jemanden, der Rot und Grün nicht trennt. */
/* --- Textanalyse: die nicht gefundenen Wörter --------------------------- */
.wortwolke { display: flex; flex-wrap: wrap; gap: .4rem; margin: .8rem 0 0; }
.wort-marke {
  background: var(--bg-tief); border: 1px solid var(--linie);
  border-radius: var(--rund-s); padding: .15rem .5rem; font-size: .9rem;
}

/* --- Schreibprüfer: die Befunde ------------------------------------------
   Drei Sicherheitsgrade, und der Unterschied zwischen ihnen ist der ganze
   Grund, warum dieses Werkzeug vertretbar ist. Er darf deshalb nicht nur
   in der Farbe stecken: Jede Marke traegt ihr Wort — Fehler, Schreibung,
   Hinweis —, und die drei Faelle unterscheiden sich zusaetzlich in der
   Farbe des linken Randes. Wer Rot und Gelb nicht trennt, liest das Wort. */
.befund-liste { list-style: none; padding: 0; margin: .9rem 0 0; }
.befund {
  border-left: 3px solid var(--linie-kraeftig);
  background: var(--karte-2);
  border-radius: 0 var(--rund-s) var(--rund-s) 0;
  padding: .75rem 1rem;
  margin: 0 0 .7rem;
}
.befund > :first-child { margin-top: 0; }
.befund > :last-child { margin-bottom: 0; }
.befund-ist-fehler     { border-left-color: var(--fehler); }
.befund-ist-schreibung { border-left-color: var(--warn); }
.befund-ist-hinweis    { border-left-color: var(--akzent); }

.befund-kopf { display: flex; align-items: baseline; gap: .55rem;
               flex-wrap: wrap; margin: 0 0 .35rem; }
.befund-marke {
  font-size: .72rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; border-radius: var(--rund-s);
  padding: .1rem .45rem; flex: none;
}
.befund-fehler     { background: var(--fehler-weich); color: var(--fehler); }
.befund-schreibung { background: var(--warn-weich);   color: var(--warn); }
.befund-hinweis    { background: var(--akzent-weich); color: var(--akzent-ink); }

/* Der Fundort. `mark` ist hier keine Hervorhebung im Sinne von „wichtig",
   sondern eine Ortsangabe: Das ist die Stelle, die gemeint ist. */
.befund-stelle {
  background: var(--bg-tief); border-radius: var(--rund-s);
  padding: .4rem .6rem; margin: 0 0 .45rem;
  font-size: .95rem; overflow-wrap: anywhere;
}
.befund-stelle mark {
  background: var(--warn-weich); color: inherit;
  border-bottom: 2px solid var(--warn); border-radius: 2px;
  padding: 0 .1em;
}
.befund-was { margin: 0 0 .3rem; }
.befund-quelle { margin: 0; font-size: .9rem; }

/* Der Kasten fuer „nichts gefunden". Er sagt ausdruecklich, dass das nicht
   „fehlerfrei" heisst — sonst waere er die unehrlichste Stelle der Seite. */
.kasten-gut { background: var(--ok-weich); border-color: transparent; }

/* --- Schreibprüfer: das Quellenband ---------------------------------------
   Die Seiten, auf denen die Regeln stehen — sichtbar und ohne dass jemand
   etwas prüfen lassen muss. Der Prüfer holt sich seine Verweise von hier;
   damit stehen sie im fertigen HTML und werden von `links` mitgeprüft. */
.quellenband { display: flex; flex-wrap: wrap; gap: .45rem; margin: .9rem 0 0; }
.quellen-marke {
  background: var(--bg-tief); border: 1px solid var(--linie);
  border-radius: var(--rund-s); padding: .25rem .6rem;
  font-size: .9rem; text-decoration: none; color: var(--ink-2);
}
.quellen-marke:hover { border-color: var(--marke); color: var(--marke-ink); }

/* --- Häufige Fragen ------------------------------------------------------
   Jede Frage ist ein eigener Block mit eigener Sprungmarke: Wer über eine
   Suchmaschine kommt, landet auf der Frage und nicht auf dem Seitenanfang. */
.frage {
  border-left: 3px solid var(--linie-kraeftig);
  padding: .1rem 0 .1rem 1.1rem;
  margin: 1.4rem 0;
}
.frage:target { border-left-color: var(--marke); }
.frage h3 { font-size: 1.05rem; margin: 0 0 .5rem; }
.frage-antwort { max-width: var(--lesebreite); }
.frage-antwort p { margin-bottom: 0; }
.frage-weiter {
  margin: .6rem 0 0; font-size: .9rem;
  max-width: var(--lesebreite);
}

/* --- Falsche Freunde: der Beleg unter der Zeile ---------------------------
   Der Beispielsatz gehört zur Zeile darüber und nicht in eine eigene Spalte:
   Fünf Spalten passen auf kein Telefon, und der Satz ist länger als die
   vier Wörter über ihm zusammen. */
.falle-beleg > td {
  padding-top: 0; border-top: 0;
  font-size: .9rem; color: var(--ink-2);
}
.falle-beleg .ziel, .falle-beleg .de, .falle-beleg .zeile-still {
  display: block;
}
.falle-tabelle td:first-child { font-weight: 600; }

.diktat-marken {
  display: flex; flex-wrap: wrap; gap: .25rem .4rem;
  margin: 0 0 .8rem; font-size: 1.05rem; line-height: 1.9;
}
.diktat-wort { border-radius: var(--rund-s); padding: .05rem .3rem; }
.diktat-wort[data-stand="tipp"] {
  background: var(--warn-weich);
  text-decoration: underline dotted; text-underline-offset: .22em;
}
.diktat-wort[data-stand="falsch"] { background: var(--fehler-weich); }
.diktat-wort[data-stand="fehlt"] {
  background: var(--fehler-weich);
  border: 1px dashed var(--fehler); padding: 0 .27rem;
}
.diktat-wort[data-stand="zuviel"] {
  background: var(--bg-tief); color: var(--ink-2);
  text-decoration: line-through;
}
.diktat-legende {
  display: flex; flex-wrap: wrap; gap: .35rem .6rem;
  align-items: center; margin: 0 0 .8rem; font-size: .82rem;
}

/* Ein Satz braucht zwei Zeilen. Ein einzeiliges Feld schiebt beim Tippen
   den Anfang aus dem Bild, und gerade beim Diktat will man das Geschriebene
   noch einmal ansehen, bevor man prüft. */
.antwort-feld-satz {
  min-height: 4.2rem; resize: vertical; line-height: 1.6;
}

.uebung-fuss {
  position: sticky; bottom: 0; z-index: 20;
  display: flex; gap: .7rem; align-items: center; flex-wrap: wrap;
  padding: .8rem 1.1rem;
  border-top: 1px solid var(--linie);
  background: color-mix(in srgb, var(--karte) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.uebung-fuss .zeile-still { margin-right: auto; }

.fortschrittsband {
  height: 5px; background: var(--bg-tief); border-radius: var(--rund-voll);
  overflow: hidden; margin-bottom: 0;
}
.fortschrittsband > i {
  display: block; height: 100%; background: var(--marke);
  transition: width .35s ease-out;
}

/* --- Hinweis auf eine neue Fassung ---------------------------------------
   Unten und schmal, nicht oben und breit: Wer gerade eine Übungsrunde spielt,
   soll nicht neu geladen werden und auch nicht dazu gedrängt werden. Die
   Leiste sagt Bescheid und wartet. */
.neue-fassung {
  position: fixed; z-index: 60;
  left: 50%; transform: translateX(-50%);
  bottom: max(1rem, env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: .7rem; flex-wrap: nowrap;
  max-width: calc(100vw - 2rem);
  padding: .55rem .6rem .55rem 1rem;
  border: 1px solid var(--linie-kraeftig); border-radius: var(--rund-voll);
  background: var(--karte); color: var(--ink);
  box-shadow: var(--schatten-2);
  font-size: .88rem;
}
.neue-fassung > span { white-space: nowrap; overflow: hidden;
                       text-overflow: ellipsis; }

/* Das Fortschrittsband beim Mitnehmen steht als <span> in einem <p>-Umfeld;
   ohne das hier wäre es ein Inlinekasten und damit ohne Höhe. Derselbe
   Fehler wie bei der Auflösung im Fortschrittsfaden, nur andersherum. */
[data-rolle="mitnehmen-band"] { display: block; margin: .6rem 0 .4rem; }

/* Die Fläche hinter der Modusauswahl.

   `position: relative` auf der Hülle und `absolute` auf dem Canvas: Die
   Kästen sollen darüberliegen, nicht daneben. Und `pointer-events: none`,
   weil eine Zierfläche, die Klicks schluckt, die Knöpfe unbedienbar macht —
   das ist der Fehler, den ein Hintergrund genau einmal macht.

   Die Stärke ist ein Token, damit hell und dunkel verschieden viel davon
   vertragen: Auf Papier steht ein Strich sofort da, auf dunklem Grund ist
   er bei derselben Deckkraft kaum zu sehen. */
/* Die Kacheln sind undurchsichtig, und das bleiben sie: Ein Text auf einer
   Fläche, die sich bewegt, ist der sicherste Weg, den Kontrast zu verlieren.
   Sichtbar wird die Bewegung deshalb im Rahmen um das Raster und in den
   Fugen dazwischen — dort steht kein Wort, dem sie schaden könnte.

   Der Rand ist Innenabstand und kein negativer Aussenabstand. Ein negativer
   Aussenabstand zieht den Kasten über die Spalte hinaus, und auf 320px ist
   das genau die Stelle, an der eine Seite anfängt, seitwärts zu scrollen. */
.moduswahl {
  position: relative;
  padding: 1.15rem;
  border-radius: var(--rund);
  background: var(--bg-tief);
}
.moduswahl-grund {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 0; border-radius: var(--rund);
}
.moduswahl .modusliste { position: relative; z-index: 1; }

.modusliste {
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
}
.modus {
  display: block; text-align: left; width: 100%;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1rem 1.1rem; cursor: pointer;
  font: inherit; color: var(--ink); text-decoration: none;
  transition: border-color .15s, transform .12s, box-shadow .2s;
}
.modus:hover { border-color: var(--marke); transform: translateY(-2px); box-shadow: var(--schatten-1); }
.modus b { display: block; font-family: var(--schrift-titel); font-size: 1.05rem; margin-bottom: .15rem; }
.modus span { color: var(--ink-3); font-size: .9rem; }

/* Vertiefung und Ausnahmen — zwei Aufklapper mit verschiedenen Aufgaben.

   Die Vertiefung ist Fliesstext und liest sich wie der Rest der Seite. Die
   Ausnahmen sind eine Liste, und jede Ausnahme hat dieselbe Gestalt: wenn —
   dann — Beispiel — warum. Dieselbe Gestalt ist hier der ganze Nutzen: Fünf
   Ausnahmen nebeneinander zeigen, dass drei davon denselben Grund haben,
   und das sieht man nur, wenn sie gleich gebaut sind.

   `summary` bekommt ein sichtbares Ziel von mindestens 44px Höhe — ein
   Aufklapper, den man auf dem Telefon dreimal antippen muss, ist keiner. */
.vertiefung, .ausnahmen {
  border: 1px solid var(--linie); border-radius: var(--rund);
  background: var(--karte); margin: .8rem 0; max-width: var(--lesebreite);
}
.vertiefung > summary, .ausnahmen > summary {
  cursor: pointer; padding: .85rem 1rem; min-height: 44px;
  display: flex; align-items: center; gap: .5rem;
  font-family: var(--schrift-titel); color: var(--ink);
  border-radius: var(--rund);
}
.vertiefung > summary:hover, .ausnahmen > summary:hover { color: var(--marke-ink); }
/* Das Warnzeichen kommt aus `zeichen.js` und bringt keine eigene Größe mit —
   in einem Flex-Kasten ohne Vorgabe wächst es auf die Höhe der Zeile mal
   Seitenverhältnis, und das waren hier 150 Pixel. Ein Symbol, das größer ist
   als seine Überschrift, ist kein Symbol mehr, sondern ein Bild. */
.ausnahmen > summary svg {
  flex: 0 0 auto; width: 1.15em; height: 1.15em; color: var(--warn);
}
.vertiefung[open] > summary, .ausnahmen[open] > summary {
  border-bottom: 1px solid var(--linie);
  border-radius: var(--rund) var(--rund) 0 0;
}
.vertiefung-inhalt { padding: .2rem 1rem 1rem; }
.vertiefung-inhalt p { max-width: none; }

.ausnahmeliste { list-style: none; margin: 0; padding: .4rem 1rem 1rem; }
.ausnahme + .ausnahme {
  margin-top: .9rem; padding-top: .9rem; border-top: 1px dashed var(--linie);
}
.ausnahme-wenn {
  margin: 0 0 .15rem; font-weight: 600; color: var(--ink);
}
.ausnahme-wenn::before {
  content: 'Wenn '; color: var(--ink-3); font-weight: 400;
}
.ausnahme-dann { margin: 0 0 .45rem; color: var(--ink-2); }
.ausnahme-dann::before {
  content: 'dann '; color: var(--ink-3);
}
.ausnahme-warum {
  margin: .45rem 0 0; color: var(--ink-3); font-size: .92rem;
}

/* --- 8. Auswertung ------------------------------------------------------- */

.kennzahlen {
  display: grid; gap: .9rem;
  grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
}
.kennzahl {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1rem; text-align: center;
}
.kennzahl b {
  display: block; font-family: var(--schrift-titel); font-size: 2rem;
  line-height: 1.1; color: var(--marke-ink); font-weight: 600;
}
.kennzahl span { font-size: .85rem; color: var(--ink-3); }

.balkenliste { display: grid; gap: .6rem; margin: 1rem 0; }
.balken-zeile { display: grid; grid-template-columns: 9rem 1fr 3rem; gap: .7rem; align-items: center; font-size: .92rem; }
.balken-spur { height: .7rem; background: var(--bg-tief); border-radius: var(--rund-voll); overflow: hidden; }
.balken-spur > i { display: block; height: 100%; background: var(--marke); border-radius: var(--rund-voll); }
/* nowrap, weil „0/1166" sonst zu „0/116" und einer einsamen „6" in der
   naechsten Zeile wird. Eine Zahl, die umbricht, ist eine andere Zahl. */
.balken-zahl { text-align: right; color: var(--ink-3);
               font-variant-numeric: tabular-nums; white-space: nowrap; }

.kalender { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; max-width: 22rem; }
.kalender i {
  aspect-ratio: 1; border-radius: 3px; background: var(--bg-tief);
  display: block;
}

.werbeplatz {
  border: 1px dashed var(--linie-kraeftig); border-radius: var(--rund);
  padding: 1rem; text-align: center; color: var(--ink-3); font-size: .85rem;
  margin: 2rem 0; background: var(--bg-tief);
}

/* --- 9. Kleinigkeiten ---------------------------------------------------- */

.hinweisband {
  background: var(--warn-weich); border-bottom: 1px solid var(--linie);
  padding: .7rem 0; font-size: .92rem;
}


.ladeplatz {
  background: linear-gradient(90deg, var(--bg-tief) 25%,
    color-mix(in srgb, var(--bg-tief) 60%, var(--karte)) 50%, var(--bg-tief) 75%);
  background-size: 200% 100%;
  animation: wandern 1.4s linear infinite;
  border-radius: var(--rund-s); height: 1em;
}
@keyframes wandern { to { background-position: -200% 0; } }

@media (max-width: 780px) {
  .navi-schalter { display: block; }
  .hauptnavi {
    display: none; width: 100%; flex-direction: column; align-items: stretch;
    gap: .1rem; padding: .6rem 0 1rem;
  }
  .hauptnavi.offen { display: flex; }
  .kopf-innen { flex-wrap: wrap; }
  .navi-werkzeuge { margin: .5rem 0 0; }
  .leiter-sprosse { grid-template-columns: 2.8rem 1fr; }
  .leiter-zahl { grid-column: 2; }
  .balken-zeile { grid-template-columns: 6.5rem 1fr 2.7rem; font-size: .85rem; }
}

@media (max-width: 400px) {
  .thema-zeile { grid-template-columns: auto minmax(0, 1fr); }
  /* .8rem statt .75rem: Auf dem Telefon waren das 12 Pixel, und genau dort
     wird die Zeile am ehesten unterwegs gelesen. */
  .thema-zeile .thema-stand { grid-column: 2; font-size: .8rem; }
  .leiter-sprosse { grid-template-columns: 2.8rem minmax(0, 1fr); }
}

@media (max-width: 380px) {
  body { font-size: 1rem; }
  .huelle { padding: 0 .85rem; }
  .uebung-koerper { padding: 1.1rem .9rem; }
  .karte, .kasten { padding: 1rem; }
  .formtabelle td:first-child { width: auto; white-space: normal; }
}

@media print {
  .kopf, .fuss, .uebung-fuss, .vorfuehrung, .buehne-grund, .grundflaeche,
  .werbeplatz,
  .navi-werkzeuge, .sprungmarke { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .karte, .kasten { border: 1px solid #ccc; box-shadow: none; break-inside: avoid; }
  a { color: #000; text-decoration: underline; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- 12. Wortschatz, Verben, Redewendungen -------------------------------
   Die Landingpages. Drei Bausteine tragen fast alles: die Wortzeile (ein
   Wort mit Übersetzung, Wortart, Stufe und Beispielsatz), die Wendungskarte
   und die Verbtabelle.

   Eine Regel, die hier mehrfach greift und die auf dieser Seite schon
   einmal Geld gekostet hat: Rasterspalten brauchen `minmax(min(…), 1fr)`.
   Zwanzig Rem sind genau 320 Pixel, und ohne `min()` kann eine Spalte nicht
   schmaler werden als ihre Vorgabe — das Telefon scrollt dann seitwärts. */

.wortlisten {
  display: grid; gap: .9rem; margin-bottom: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
}
.wortliste-karte {
  display: block; text-decoration: none; color: var(--ink);
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1.1rem;
  box-shadow: var(--schatten-1);
  transition: transform .14s, box-shadow .2s, border-color .2s;
}
.wortliste-karte:hover {
  transform: translateY(-2px); box-shadow: var(--schatten-2);
  border-color: var(--linie-kraeftig); color: var(--ink);
}
.wl-titel {
  display: block; font-family: var(--schrift-titel);
  font-size: 1.06rem; margin: .5rem 0 .25rem;
}
.wl-kurz { display: block; color: var(--ink-3); font-size: .92rem;
           line-height: 1.5; }
.wl-zahl { display: block; margin-top: .6rem; color: var(--ink-3);
           font-size: .85rem; }

/* Die Kategorien — dieselbe Karte wie eine Wortliste, aber mit dem
   Stufenband statt eines Stufenschilds. Ein Schild ginge hier nicht: Eine
   Kategorie hat keine Stufe, sie reicht durch alle sechs, und genau das
   soll man sehen, bevor man sie öffnet. Eine Wortzahl allein verschweigt
   es — 340 Wörter, die alle auf C1 stehen, sind für jemanden auf A2 keine
   Kategorie, sondern eine Wand. */
.kat-liste {
  display: grid; gap: .9rem; margin-bottom: 1.4rem;
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
}
.kat-karte {
  display: block; text-decoration: none; color: var(--ink);
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1.1rem;
  box-shadow: var(--schatten-1);
  transition: transform .14s, box-shadow .2s, border-color .2s;
}
.kat-karte:hover {
  transform: translateY(-2px); box-shadow: var(--schatten-2);
  border-color: var(--linie-kraeftig); color: var(--ink);
}
.kat-titel {
  display: block; font-family: var(--schrift-titel);
  font-size: 1.12rem; margin-bottom: .3rem;
}
.kat-kurz { display: block; color: var(--ink-3); font-size: .95rem;
            line-height: 1.5; }
.kat-zahl { display: block; margin-top: .55rem; color: var(--ink-3);
            font-size: .85rem; }

/* Sechs Abschnitte, breit nach Anteil. `flex` traegt die Anzahl, damit die
   Breiten sich von selbst auf hundert Prozent summieren — mit Prozenten
   gerechnet fehlt am Ende je nach Rundung ein Pixel oder eines zu viel. */
.kat-band {
  display: flex; height: .42rem; margin-top: .8rem;
  border-radius: var(--rund-voll); overflow: hidden;
  background: var(--bg-tief);
}
.kat-band-teil { display: block; background: var(--stufe-farbe, var(--marke)); }
.seitenkopf .kat-band { display: inline-flex; width: 7rem;
                        vertical-align: middle; margin: 0 .2rem 0 0; }

.wortliste { display: grid; gap: .55rem; margin-bottom: 1.6rem; }

.wortzeile {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund-s); padding: .8rem .95rem;
}
/* Ein Raster mit **einer** Vorlage für alle Zeilen — das ist der ganze
   Unterschied zwischen einer Liste, die man überfliegen kann, und einer,
   die man lesen muss.

   Vorher war das hier `display: flex` mit `flex-wrap`, und damit setzte
   jede Zeile ihre vier Angaben dort ab, wo die vorherige aufgehört hatte:
   „ADVERB" stand bei jedem Wort woanders, die Stufe wanderte mit. Beim
   Suchen liest niemand Zeilen, sondern Spalten; ohne Spalten gibt es
   nichts zu überfliegen.

   `minmax(0, …)` an beiden Textspalten, weil eine Rasterspalte sonst
   mindestens so breit wird wie ihr längstes Wort und die Zeile aufschiebt
   — dieselbe Falle wie vorher, nur an anderer Stelle. Und die Stufe steht
   ganz rechts an der Kante: Sie ist die einzige Angabe, nach der jemand
   die Liste durchsieht, ohne den Text zu lesen. */
.wortzeile-kopf {
  display: grid; align-items: baseline; gap: .3rem .8rem;
  grid-template-columns:
    var(--wz-bild, 1.9rem) minmax(0, 11rem) minmax(0, 1fr) auto auto;
}
.merkbild-leer { display: block; }

/* Auf dem Telefon ist für fünf Spalten kein Platz. Zwei Reihen, aber
   weiterhin ausgerichtet: Wort und Stufe oben, Bedeutung und Wortart
   darunter — und nicht einfach `flex-wrap`, denn dann stünde alles
   wieder woanders. */
@media (max-width: 34rem) {
  .wortzeile-kopf {
    grid-template-columns: var(--wz-bild, 1.6rem) minmax(0, 1fr) auto;
  }
  .wortzeile-kopf .wort-de { grid-column: 2; }
  .wortzeile-kopf .wort-art { grid-column: 3; text-align: right; }
}

/* --- Kompakt oder vollständig ---------------------------------------------

   Die Voreinstellung hier ist **vollständig**, und das ist der Punkt:
   Ohne JavaScript gibt es keinen Umschalter, und ein Beispielsatz, der
   dann zugeklappt und ohne Knopf dastünde, wäre nicht erreichbar.
   `main.js` schaltet auf kompakt, sobald es laufen kann.

   Versteckt wird mit CSS und nicht durch Weglassen: Die Volltextsuche
   liest die gebaute Seite, und die Suche des Browsers findet nur, was im
   Dokument steht. */
[data-dichte="kompakt"] .wortzeile-mehr { display: none; }
[data-dichte="kompakt"] .wortzeile {
  padding: .3rem .6rem; border-radius: 0;
  border-width: 0 0 1px 0; background: none;
}
[data-dichte="kompakt"] .wortliste { gap: 0; }
[data-dichte="kompakt"] .wortzeile-kopf { --wz-bild: 1.2rem; gap: .2rem .7rem; }
[data-dichte="kompakt"] .merkbild { width: 1.2rem; height: 1.2rem; }
[data-dichte="kompakt"] .wort-en { font-size: 1rem; }

.dichte-schalter {
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  margin: 0 0 .9rem;
}
/* .8rem und nicht .78rem: Gemessen waren es 12,48 Pixel, und `layout`
   verlangt zwölfeinhalb — unter dieser Grenze wird ein Etikett auf einem
   Telefon zu einem grauen Strich, den man für Dekoration hält. Dieselbe
   Rechnung steht schon bei `.wort-art`; sie gilt hier genauso. */
.dichte-marke {
  font-size: .8rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3); margin-right: .2rem;
}
.dichte-schalter button {
  font: inherit; font-size: .88rem; padding: .3rem .75rem;
  border: 1px solid var(--linie); border-radius: 999px;
  background: var(--karte); color: var(--ink-2); cursor: pointer;
}
.dichte-schalter button[aria-pressed="true"] {
  background: var(--marke); border-color: var(--marke);
  color: var(--knopf-ink);
}
/* --- Merkbilder -----------------------------------------------------------

   `flex-shrink: 0`, weil eine Zeichnung in einer Flexzeile sonst als Erstes
   zusammengedrückt wird — auf dem Telefon war das Bild dann ein Strich.
   Und `--ink-3` statt `--ink`: Das Bild ist die Beigabe, das Wort ist die
   Sache. Ein Piktogramm in voller Textfarbe zieht den Blick vom Wort weg,
   das man eigentlich lesen soll. */
.merkbild {
  width: 1.9rem; height: 1.9rem; flex: 0 0 auto;
  color: var(--ink-3); align-self: center;
}
.merkbild-gross {
  display: flex; justify-content: center; margin-bottom: .6rem;
  color: var(--ink-3);
}
.merkbild-gross .merkbild { width: 3.4rem; height: 3.4rem; }

.wort-en {
  font-family: var(--schrift-titel); font-size: 1.05rem; font-weight: 600;
  color: var(--marke-ink);
}
.wort-de { color: var(--ink); }
/* .82rem und nicht .78rem: Gemessen waren es 12,48 Pixel, und unter
   12,5 Pixeln liest ein Etikett auf einem Telefon niemand mehr mit — es
   wird zu einem grauen Strich, den man für Dekoration hält. Der Unterschied
   kostet in der Zeile nichts, weil die Wortart ohnehin auf eigener Höhe
   sitzt. */
.wort-art {
  font-size: .82rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-3);
}
.wortzeile-bsp {
  margin-top: .5rem; padding-top: .5rem; border-top: 1px solid var(--linie);
  display: grid; gap: .15rem; font-size: .93rem;
}
.wortzeile-bsp .ziel { color: var(--ink-2); }
.wortzeile-bsp .de { color: var(--ink-3); }
.wort-hinweis {
  margin: .5rem 0 0; font-size: .88rem; color: var(--ink-3);
  border-left: 2px solid var(--linie-kraeftig); padding-left: .6rem;
  max-width: var(--lesebreite);
}
.wortart-kopf {
  font-size: 1.05rem; margin: 1.6rem 0 .7rem;
  display: flex; align-items: baseline; gap: .5rem;
}
.wortart-kopf span { font-weight: 400; color: var(--ink-3); font-size: .9rem; }

.gw-filter { margin-bottom: 1.6rem; }
.gw-listenkopf {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .7rem;
  margin-top: 2.2rem;
  /* Ein deutsches Kompositum bricht nicht von selbst.
     „Entwicklungszusammenarbeit" ist bei 320px allein 336 Pixel breit und
     schob die ganze Seite 31 Pixel nach rechts — sichtbar wurde das erst,
     als eine Wortliste diesen Namen bekam. `flex-wrap` half nicht: Es bricht
     zwischen Kindern, nicht innerhalb eines Wortes. */
  overflow-wrap: anywhere;
}

/* Verbtabelle: die Beispielzeile hängt unter ihrer Verbzeile und trägt
   deshalb keinen eigenen Rahmen — sie gehört zur Zeile darüber. */
.verbtabelle td, .verbtabelle th { vertical-align: baseline; }
.verbtabelle .verb-bsp td {
  padding-top: 0; border-top: 0; color: var(--ink-3);
}
.verbtabelle .verb-bsp .satzpaar { margin: 0 0 .3rem; }
.verb-gruppe { margin-top: 2.4rem; }

.wendungsliste { display: grid; gap: .7rem; }
.wendung {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund-s); padding: .95rem 1.1rem;
}
.wendung-kopf {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem;
  margin-bottom: .4rem;
}
/* Auch hier das Lesemaß: Eine Redewendung mit ihrer Erklärung ist
   Fließtext, und auf einem breiten Schirm lief sie über 1110 Pixel. */
.wendung-bedeutung { margin: 0 0 .35rem; max-width: var(--lesebreite); }
.wendung-deutsch {
  margin: 0 0 .5rem; font-size: .93rem; color: var(--ink-2);
  max-width: var(--lesebreite);
}
.wendung-deutsch span { color: var(--ink-3); }
.wendung-gruppe { margin-top: 2.4rem; }

/* Das Zeitenraster ist die einzige Tabelle der Seite, die auf einem Telefon
   wirklich nicht passt — vier Spalten mit Formen darin. Sie scrollt in
   ihrem Rahmen, wie jede andere auch, und bekommt eine Mindestbreite, damit
   die Zellen nicht zu vier Buchstaben je Zeile zusammenfallen. */
.zeitenraster { min-width: 34rem; }
.zeitenraster th[scope="row"] { white-space: nowrap; }
.zeit-bsp {
  display: block; margin-top: .2rem; font-size: .88rem; color: var(--ink-3);
}

/* Der Anfängerweg: eine nummerierte Liste, in der die Nummer etwas wiegt. */
.anf-liste { list-style: none; padding: 0; margin: 0; display: grid;
             gap: .8rem; }
.anf-schritt {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund); padding: 1.1rem 1.2rem;
}
.anf-kopf {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem;
  margin-bottom: .45rem;
}
.anf-nummer {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.9rem; height: 1.9rem; flex: 0 0 auto;
  border-radius: 50%; background: var(--marke); color: var(--knopf-ink);
  font-family: var(--schrift-titel); font-size: .95rem;
}
.anf-kopf a { font-size: 1.08rem; display: inline-block; padding: .3rem 0; }
.anf-warum { margin: 0; color: var(--ink-2); }
.anf-vokabeln { margin: .6rem 0 0; font-size: .93rem; color: var(--ink-3); }

.quiz-ergebnis h3 { margin: 1.4rem 0 .5rem; font-size: 1.05rem; }

/* --- 13. Vorlesen --------------------------------------------------------
   Der Knopf hängt hinter dem englischen Satz oder Wort, an dem er hängt.
   Zwei Dinge, die er nicht darf: die Zeile aufblähen und beim Umbruch
   allein in der nächsten Zeile landen.

   `vertical-align: middle` statt `baseline`, weil ein SVG keine Grundlinie
   hat und sonst zu tief sitzt; und `line-height: 0`, damit der Knopf die
   Zeilenhöhe des Absatzes nicht anhebt — ein Knopf von 1.4rem in einer
   Zeile von 1.6 macht sonst jede zweite Zeile höher als die erste.

   Sichtbar wird er erst, wenn das Skript festgestellt hat, dass es
   überhaupt eine englische Stimme gibt: data-vorlesbar am <html>. Ein Knopf,
   der nichts tut, ist schlimmer als keiner.

   `data-vorlesbar` und nicht `data-vorlesen` — das zweite bedeutet an einem
   Element „sprich diesen Text statt deines eigenen". Ein Name mit zwei
   Bedeutungen hat das Skript einmal versuchen lassen, dem <html> einen
   Knopf danebenzustellen. */

.vorlesen { display: none; }

:root[data-vorlesbar="ja"] .vorlesen {
  display: inline-flex; align-items: center; justify-content: center;
  vertical-align: middle; line-height: 0;
  width: 1.55rem; height: 1.55rem; margin-left: .35rem; padding: 0;
  border: 1px solid transparent; border-radius: var(--rund-voll);
  background: transparent; color: var(--ink-3); cursor: pointer;
  transition: color .15s, background .15s, border-color .15s;
}
:root[data-vorlesbar="ja"] .vorlesen:hover,
:root[data-vorlesbar="ja"] .vorlesen:focus-visible {
  color: var(--marke-ink); background: var(--marke-weich);
  border-color: var(--linie);
}
:root[data-vorlesbar="ja"] .vorlesen[data-spricht] {
  color: var(--marke-ink); background: var(--marke-weich);
}
.vorlesen svg { width: 15px; height: 15px; }

/* Beim Drucken hat ein Lautsprecher nichts verloren. */
@media print { .vorlesen { display: none !important; } }

/* Der Anhören-Knopf in einer Höraufgabe. Größer als der kleine Lautsprecher
   neben einem Satz: Hier ist er nicht Zugabe, sondern die Aufgabe selbst —
   ohne ihn steht auf dem Schirm nichts, womit sich arbeiten ließe. */
.hoerknopf {
  display: inline-flex; align-items: center; gap: .55rem;
  margin: .2rem 0 1rem;
}
.hoerknopf svg { width: 20px; height: 20px; }
.hoerknopf[data-spricht] {
  border-color: var(--marke); color: var(--marke-ink);
  background: var(--marke-weich);
}

/* --- Grammatikregister ---------------------------------------------------
   Der dritte Zugang zur Grammatik: nach dem Zweifel und nach dem Alphabet.
   Die Filterleiste liegt `hidden` im HTML und wird von register.js
   aufgedeckt — sichtbar ist nur, was auch funktioniert.               */

.gr-einstieg {
  display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 2.2rem); align-items: center;
  margin: 0 0 2.2rem; padding: clamp(1.1rem, 3vw, 1.8rem);
  border: 1px solid var(--linie); border-radius: var(--rund-l);
  background:
    linear-gradient(135deg,
      color-mix(in srgb, var(--marke) 7%, var(--karte)) 0%,
      var(--karte) 62%);
  box-shadow: var(--schatten-1);
}
.gr-einstieg h2 { margin: 0 0 .5rem; font-size: 1.25rem; }
.gr-einstieg p { margin: 0 0 1rem; color: var(--ink-2); max-width: 46ch; }
.gr-einstieg-proben {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .45rem;
}
.gr-einstieg-proben a {
  display: inline-block; padding: .42rem .72rem;
  border: 1px solid var(--linie-kraeftig); border-radius: var(--rund-voll);
  background: var(--karte); color: var(--ink-2);
  font-size: .86rem; text-decoration: none;
  transition: border-color .16s, color .16s, box-shadow .16s, transform .16s;
}
.gr-einstieg-proben a:hover {
  border-color: var(--marke); color: var(--marke-ink);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--marke) 14%, transparent);
  transform: translateY(-1px);
}
@media (max-width: 46rem) {
  .gr-einstieg { grid-template-columns: 1fr; }
}

.reg-leiste {
  position: sticky; top: var(--kopf-hoehe, 3.6rem); z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem .8rem;
  margin: 0 0 1.6rem; padding: .7rem .8rem;
  border: 1px solid var(--linie); border-radius: var(--rund);
  background: color-mix(in srgb, var(--karte) 88%, transparent);
  backdrop-filter: blur(10px) saturate(1.3);
  box-shadow: var(--schatten-1);
}
.reg-suchfeld {
  display: flex; align-items: center; gap: .5rem; flex: 1 1 18rem;
  padding: .5rem .75rem;
  border: 1px solid var(--linie-kraeftig); border-radius: var(--rund-voll);
  background: var(--bg-tief);
  transition: border-color .16s, box-shadow .16s;
}
.reg-suchfeld:focus-within {
  border-color: var(--marke);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--marke) 16%, transparent);
}
.reg-lupe { display: flex; color: var(--ink-3); }
.reg-suchfeld input {
  flex: 1; min-width: 0; border: 0; background: none; color: var(--ink);
  font: inherit; font-size: .95rem; outline: none;
}
.reg-knoepfe { display: flex; flex-wrap: wrap; gap: .3rem; }
.reg-knopf {
  padding: .34rem .6rem; font-size: .8rem; font-weight: 600;
  border: 1px solid var(--linie-kraeftig); border-radius: var(--rund-voll);
  background: var(--karte); color: var(--ink-2); cursor: pointer;
  transition: border-color .16s, color .16s, background .16s;
}
.reg-knopf:hover { border-color: var(--ink-3); color: var(--ink); }
.reg-knopf.reg-an {
  border-color: var(--stufe-farbe, var(--marke));
  color: var(--knopf-ink);
  background: var(--stufe-farbe, var(--marke));
}
.reg-zaehler {
  margin: 0; font-size: .82rem; color: var(--ink-3);
  font-variant-numeric: tabular-nums; min-width: 6ch;
}

.reg-abschnitt { margin: 0 0 2.4rem; }
.reg-abschnitt > h2 { margin-bottom: .3rem; }
.reg-abschnitt > p { margin-bottom: 1.1rem; }

.reg-fragen { display: grid; gap: .5rem; }
.reg-frage {
  display: flex; gap: .8rem; align-items: flex-start;
  padding: .85rem 1rem; text-decoration: none;
  border: 1px solid var(--linie); border-radius: var(--rund);
  background: var(--karte); color: inherit;
  transition: border-color .16s, box-shadow .16s, transform .16s;
}
.reg-frage:hover, .reg-frage:focus-visible {
  border-color: color-mix(in srgb, var(--marke) 45%, var(--linie));
  box-shadow: var(--schatten-2); transform: translateY(-1px);
}
.reg-frage-text { display: block; min-width: 0; }
.reg-frage-titel {
  display: block; font-weight: 600; color: var(--ink); margin-bottom: .2rem;
}
.reg-frage-antwort {
  display: block; color: var(--ink-2); font-size: .92rem; line-height: 1.5;
}
.reg-frage-ziel {
  display: block; margin-top: .35rem;
  font-size: .78rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--marke-ink);
}
.reg-frage i, .reg-thema i { font-style: italic; }

.reg-themen {
  display: grid; gap: .4rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr));
}
.reg-thema {
  display: flex; gap: .7rem; align-items: flex-start;
  padding: .6rem .8rem; text-decoration: none;
  border: 1px solid transparent; border-radius: var(--rund-s);
  color: inherit;
  transition: border-color .16s, background .16s;
}
.reg-thema:hover, .reg-thema:focus-visible {
  border-color: var(--linie); background: var(--karte-2);
}
.reg-thema-text { display: block; min-width: 0; flex: 1; }
.reg-thema-titel { display: block; font-weight: 600; color: var(--ink); }
.reg-thema-kurz {
  display: block; color: var(--ink-3); font-size: .86rem; line-height: 1.45;
}
.reg-thema-bereich {
  flex: 0 0 auto; align-self: center;
  font-size: .74rem; color: var(--ink-3); text-align: right; max-width: 9rem;
}
@media (max-width: 40rem) { .reg-thema-bereich { display: none; } }

.reg-nichts {
  padding: 1.1rem; border: 1px dashed var(--linie-kraeftig);
  border-radius: var(--rund); color: var(--ink-2); text-align: center;
}
.reg-weiter { margin-top: 1.6rem; }

/* --- Dranbleiben: Jahreskalender, Wochenrückblick, Serienschutz ----------- */

.jk-rahmen {
  display: grid; grid-template-columns: auto 1fr; gap: .3rem .45rem;
  overflow-x: auto; padding-bottom: .4rem;
}
.jk-ecke { grid-column: 1; grid-row: 1; }
.jk-monate {
  grid-column: 2; grid-row: 1;
  display: grid; grid-auto-flow: column; grid-auto-columns: 13px;
  color: var(--ink-3); min-width: max-content;
}
/* Der Monatsname ist breiter als seine Spalte und darf sie verlassen. Ohne
   das bricht „Aug" auf drei Zeilen zu „Au / g" um — die Spalte ist elf
   Pixel breit, der Name nicht.

   Die Größe stand bei .68rem und damit bei 10,88 Pixeln. Das ist unter der
   Grenze, ab der ein Etikett auf einem Telefon zu einem grauen Strich
   wird, den man für Dekoration hält — `layout` misst genau das und hat es
   gefunden. 12,8 Pixel passen weiterhin: Zwischen zwei Beschriftungen
   liegen mindestens drei Spalten, also 39 Pixel, und „Aug" ist bei dieser
   Größe rund 27 breit. */
.jk-monat {
  white-space: nowrap; overflow: visible; font-size: .8rem;
}
.jk-tage {
  grid-column: 1; grid-row: 2;
  display: grid; grid-template-rows: repeat(7, 13px);
  font-size: .8rem; color: var(--ink-3); align-items: center;
}
.jk-spalten { grid-column: 2; grid-row: 2; min-width: max-content; }
.jk-raster { display: grid; grid-auto-flow: column; gap: 2px; }
.jk-woche { display: grid; grid-template-rows: repeat(7, 11px); gap: 2px; }
.jk-zelle {
  width: 11px; height: 11px; border-radius: 2px;
  background: var(--bg-tief); border: 1px solid var(--linie);
  transition: transform .12s;
}
.jk-zelle:hover { transform: scale(1.45); }
.jk-leer { background: none; border-color: transparent; }
.jk-s0 { background: var(--bg-tief); }
.jk-s1 { background: color-mix(in srgb, var(--marke) 28%, var(--bg-tief));
         border-color: color-mix(in srgb, var(--marke) 30%, var(--linie)); }
.jk-s2 { background: color-mix(in srgb, var(--marke) 62%, var(--bg-tief));
         border-color: color-mix(in srgb, var(--marke) 55%, var(--linie)); }
.jk-s3 { background: var(--marke); border-color: var(--marke); }
.jk-fuss {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: .6rem; margin-top: .9rem;
}
.jk-summe { margin: 0; color: var(--ink-2); font-size: .9rem; }
.jk-legende { display: flex; align-items: center; gap: 3px; }
.jk-legende .jk-zelle:hover { transform: none; }
.jk-legende-text { font-size: .72rem; color: var(--ink-3); margin: 0 .3rem; }

.wr-zahlen {
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.wr-zahl {
  padding: .8rem .9rem; border: 1px solid var(--linie);
  border-radius: var(--rund-s); background: var(--karte-2);
}
.wr-wert {
  display: block; font-family: var(--schrift-titel); font-size: 1.9rem;
  line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums;
}
.wr-titel { display: block; color: var(--ink-3); font-size: .84rem; }
.wr-diff { display: block; margin-top: .35rem; font-size: .8rem; font-weight: 600; }
.wr-hoch { color: var(--ok-ink); }
.wr-runter { color: var(--akzent-ink); }
.wr-gleich { color: var(--ink-3); font-weight: 400; }
.wr-satz { margin: 1rem 0 0; color: var(--ink-2); max-width: 52ch; }

.ss-punkte { display: flex; gap: .4rem; align-items: center; }
.ss-punkt {
  width: 1.05rem; height: 1.05rem; border-radius: 50%;
  border: 2px solid var(--linie-kraeftig);
}
.ss-frei { background: var(--ok); border-color: var(--ok); }
.ss-weg { background: none; }
.ss-satz { margin: .7rem 0 .3rem; color: var(--ink-2); }

.erin-zeile {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: .8rem;
  margin-top: 1rem;
}
.erin-feld { display: flex; flex-direction: column; gap: .3rem;
             font-size: .84rem; color: var(--ink-3); }
.erin-feld input {
  padding: .5rem .6rem; border: 1px solid var(--linie-kraeftig);
  border-radius: var(--rund-s); background: var(--bg-tief); color: var(--ink);
  font: inherit;
}
/* Sieben Kacheln nebeneinander, und auf 320 Pixeln passen sie nicht: Als
   Flex-Reihe mit fester Mindestbreite ragten sie drei Pixel über den Rand
   und machten die ganze Seite seitlich scrollbar. Ein Raster aus sieben
   gleichen Spalten mit `minmax(0, 1fr)` kann schrumpfen — die Kacheln
   werden auf einem schmalen Telefon enger und laufen nie über. */
.erin-tage {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: .25rem; border: 0; padding: 0; margin: 0;
}
.erin-tage label { position: relative; cursor: pointer; }
.erin-tage input { position: absolute; opacity: 0; width: 0; height: 0; }
.erin-tage span {
  display: block; padding: .5rem .2rem;
  text-align: center; font-size: .82rem; font-weight: 600;
  border: 1px solid var(--linie-kraeftig); border-radius: var(--rund-s);
  color: var(--ink-3); background: var(--karte);
  transition: background .14s, color .14s, border-color .14s;
}
.erin-tage input:checked + span {
  background: var(--marke); border-color: var(--marke); color: var(--knopf-ink);
}
.erin-tage input:focus-visible + span {
  outline: 2px solid var(--marke); outline-offset: 2px;
}
/* Ein Balken, dessen Zahl nicht trägt. Dieselbe Regel wie bei den Säulen:
   gezeigt, aber nicht als Aussage. */
.balken-blass { opacity: .55; }
.balken-blass .balken-spur i { background: var(--linie-kraeftig); }

/* ==========================================================================
   Der Feinschliff
   ==========================================================================

   Eine Schicht über allem, was schon da ist: Anhebung, Schein, Lichtsaum
   und ein einheitlicher Tastaturring. Sie ändert keine Farbe und keine
   Fläche — nur Schatten, Rahmen und Übergänge. Das ist Absicht und keine
   Zurückhaltung: `tools/thema_pruefen.mjs` misst den Kontrast jedes Textes
   gegen das, was wirklich dahinterliegt, und eine Politur, die eine Fläche
   umfärbt, müsste dort neu bestehen. Ein Schein liegt außerhalb der
   Fläche und kann den Text darauf nicht erreichen.

   Vier Regeln, unter denen das hier steht:

   1. **Im Ruhezustand ist der Schein fast nichts.** Eine Seite, auf der
      dreißig Karten leuchten, leuchtet nicht — sie flimmert. Der Schein
      ist die Antwort auf den Zeiger und nicht der Normalzustand.
   2. **Angehoben wird um einen Pixel.** Zwei sind schon eine Bewegung, und
      eine Bewegung bei jedem Überfahren macht eine Liste unruhig.
   3. **Der Tastaturring ist überall derselbe** und ist nicht der
      Zeigerschein. Wer mit der Tastatur navigiert, braucht eine Marke, die
      man nicht übersieht; wer mit der Maus fährt, einen Hinweis, den man
      kaum bemerkt.
   4. **`prefers-reduced-motion` schaltet die Übergänge ab**, nicht den
      Schein. Wer keine Bewegung will, will trotzdem sehen, worauf er
      zeigt. Das erledigt der Block weiter oben, der alle Übergangsdauern
      auf null setzt.                                                     */

/* --- Der Tastaturring, einmal für alles ---------------------------------- */

a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--marke);
  outline-offset: 2px;
  border-radius: var(--rund-s);
}

/* Die beiden aufklappbaren Bloecke auf einer Grammatikseite. Sie erben,
   was `vertiefung` und `ausnahmen` schon haben — eine dritte und vierte
   Gestalt fuer dieselbe Geste waere Unruhe und kein Unterschied. */
.mehr-beispiele { margin-top: .9rem; }
.mehr-beispiele > summary {
  cursor: pointer; color: var(--marke-ink); font-size: .93rem;
  padding: .35rem 0; list-style: none;
}
.mehr-beispiele > summary::-webkit-details-marker { display: none; }
.mehr-beispiele > summary::before { content: '+ '; }
.mehr-beispiele[open] > summary::before { content: '– '; }
.mb-inhalt { padding-top: .5rem; border-top: 1px solid var(--linie);
             margin-top: .35rem; }

.besonderheiten > summary svg {
  width: 19px; height: 19px; flex: none; color: var(--marke-ink);
}
.besonderheitenliste { list-style: none; margin: 0; padding: 0;
                       display: grid; gap: 1rem; }
.besonderheit + .besonderheit { border-top: 1px solid var(--linie);
                                padding-top: 1rem; }
.bes-titel { font-weight: 600; margin-bottom: .25rem; }

/* --- Flächen, die liegen ------------------------------------------------- */

.karte, .modus, .wortliste-karte, .kat-karte, .anl-karte,
.sprachkarte, .weg, .reg-frage, .gr-einstieg, .wendungskarte {
  /* `background-image` und nicht `background`: Die Flaechenfarbe steht
     weiter oben je Klasse und soll dort stehen bleiben. Ein Kurzform-
     `background` hier wuerde sie alle auf dieselbe Farbe ziehen. */
  background-image: var(--schein);
  box-shadow: var(--lift), var(--halo), var(--schein-hof), var(--saum);
  transition: box-shadow .18s ease, transform .18s ease,
              border-color .18s ease;
}

.modus:hover, .wortliste-karte:hover, .kat-karte:hover, .anl-karte:hover,
.sprachkarte:hover, .weg:hover, .reg-frage:hover,
.modus:focus-visible, .wortliste-karte:focus-visible,
.kat-karte:focus-visible, .anl-karte:focus-visible,
.sprachkarte:focus-visible, .weg:focus-visible,
.reg-frage:focus-visible {
  box-shadow: var(--lift-hi), var(--halo-hi), var(--schein-hof-hi),
              var(--saum);
  transform: translateY(-1px);
}

/* Eine Karte, die eine eigene Farbe trägt, leuchtet in ihrer eigenen Farbe.
   Elf Kategoriefarben und sechs Stufenfarben unter einem gemeinsamen
   grünen Schein wären elf beziehungsweise sechs getrübte Farben. */
.kat-karte, .leiter-sprosse, .gr-stufe, .stufe-kopf {
  --glanz-eigen: var(--stufe-farbe, var(--kat-farbe, var(--marke)));
}
.kat-karte:hover, .leiter-sprosse:hover, .gr-stufe:hover {
  /* Der weisse Hof steht hier VOR dem farbigen und damit hinter ihm: Zwei
     Schimmer nebeneinander waeren zwei, einer unter dem anderen ist Licht
     mit Farbe darin. */
  box-shadow:
    var(--lift-hi),
    var(--schein-hof-hi),
    0 0 0 1px color-mix(in srgb, var(--glanz-eigen) 40%, transparent),
    0 0 20px -8px color-mix(in srgb, var(--glanz-eigen) 70%, transparent),
    var(--saum);
}

/* --- Knöpfe --------------------------------------------------------------
   Der gefüllte Knopf bekommt einen Verlauf und eine Lichtkante oben. Beides
   ist so schwach, dass es nur zusammen wirkt — und beides sitzt INNEN, weil
   ein Verlauf auf der Fläche den Text darauf trägt und deshalb gemessen
   werden muss. Gemessen ist er: Die hellste und die dunkelste Stelle des
   Verlaufs liegen beide über 4,5:1 gegen --knopf-ink, weil er nur acht
   Prozent zwischen Anfang und Ende spannt.                                */

.knopf {
  background-image: linear-gradient(180deg,
    color-mix(in srgb, #fff 8%, transparent) 0%,
    transparent 55%,
    color-mix(in srgb, #000 6%, transparent) 100%);
  box-shadow: var(--lift), var(--halo);
  transition: box-shadow .18s ease, transform .18s ease, filter .18s ease;
}
.knopf:hover {
  box-shadow: var(--lift-hi),
              0 0 24px -8px color-mix(in srgb, var(--marke) 70%, transparent);
  transform: translateY(-1px);
  filter: saturate(1.06);
}
.knopf:active { transform: translateY(0); }

.knopf-2, .knopf-zweit, .knopf-still {
  transition: box-shadow .18s ease, border-color .18s ease,
              color .18s ease, background .18s ease, transform .18s ease;
}
.knopf-2:hover, .knopf-zweit:hover, .knopf-still:hover {
  box-shadow: var(--lift), var(--halo-hi);
  transform: translateY(-1px);
}

/* --- Zeilen und Listen ---------------------------------------------------
   Eine Zeile in einer langen Liste darf sich nicht heben — sonst springt
   beim Überfahren die halbe Liste. Sie bekommt stattdessen eine Kante in
   der Markenfarbe, die von links hereinwächst.                            */

.thema-zeile, .reg-thema, .sts-treffer, .wortzeile {
  position: relative;
  transition: background .16s ease, border-color .16s ease;
}
.thema-zeile::before, .reg-thema::before {
  content: ""; position: absolute; left: 0; top: 8%; bottom: 8%;
  width: 2px; border-radius: 2px;
  background: var(--marke);
  transform: scaleY(0); transform-origin: center;
  transition: transform .18s ease;
}
.thema-zeile:hover::before, .reg-thema:hover::before,
.thema-zeile:focus-visible::before, .reg-thema:focus-visible::before {
  transform: scaleY(1);
}

/* --- Aufklappbares -------------------------------------------------------
   Das Dreieck dreht sich mit. Ohne das dreht es sich sprunghaft, und ein
   sprunghaftes Dreieck ist das erste, was an einer Oberfläche billig
   aussieht.                                                               */

.aus-karte > summary, .vertiefung > summary {
  transition: background .16s ease;
}
.aus-karte > summary::marker, .vertiefung > summary::marker { color: var(--ink-3); }

/* Der Kopf hat weiter oben schon eine Regel fuer den gescrollten Zustand;
   hier steht deshalb nichts dazu. Zwei Regeln fuer denselben Zustand sind
   zwei Wahrheiten, und die spaetere gewinnt aus dem falschen Grund. */
/* Die deutsche Fassung über einem zu legenden Satz. Sie ist die Aufgabe und
   nicht ein Hinweis — deshalb in der Leseschrift und nicht in der stillen. */
.ordnen-deutsch {
  font-family: var(--schrift-titel); font-size: 1.15rem;
  margin: 0 0 .3rem; color: var(--ink);
}

/* --------------------------------------------------------------------------
   Lesetexte

   Der Text steht in einer schmalen Spalte — rund 66 Zeichen, nicht die
   Breite der Karte. Alles andere auf dieser Seite ist zum Nachschlagen
   gebaut; das hier ist zum Lesen, und eine Zeile über die halbe
   Bildschirmbreite verliert man beim Umbruch.
   -------------------------------------------------------------------------- */
.lesetext { position: relative; max-width: 40rem; font-size: 1.08rem; line-height: 1.85; }
.lesetext p { margin: 0 0 1.1rem; }
.lesetext p:last-child { margin-bottom: 0; }

/* Ein anklickbares Wort darf nicht aussehen wie ein Verweis. Die Seite ist
   voll von Verweisen, und dreihundert unterstrichene Wörter in einem
   Absatz wären keine Hilfe, sondern ein Muster. Es zeigt sich erst unter
   dem Zeiger — und auf dem Telefon, wo es keinen gibt, beim Antippen. */
.lw { cursor: pointer; border-radius: 3px; }
.lw:hover, .lw:focus-visible { background: var(--marke-weich); outline: none; }
.lw-offen { background: var(--marke-weich); box-shadow: 0 0 0 1px var(--marke); }

.lw-karte {
  position: absolute; z-index: 5; min-width: 12rem; max-width: 18rem;
  padding: .6rem .75rem; border-radius: 10px;
  background: var(--karte); color: var(--ink);
  border: 1px solid var(--linie-kraeftig); box-shadow: var(--schatten-3);
  font-size: .92rem; line-height: 1.45;
}
.lw-karte p { margin: 0; }
.lw-wort { font-weight: 600; }
.lw-de { margin-top: .15rem !important; }
.lw-quelle { color: var(--ink-3); font-size: .82rem; margin-top: .3rem !important; }
.lw-stufe {
  display: inline-block; padding: 0 .35rem; border-radius: 4px;
  border: 1px solid var(--linie-kraeftig); font-size: .75rem;
}

/* Der Absatz, in dem die Antwort steht. Ein Strich am Rand und kein
   Farbfeld: Der Satz bleibt lesbar, die Stelle ist trotzdem zu finden. */
.lp-treffer {
  border-left: 3px solid var(--marke); padding-left: .7rem; margin-left: -.85rem;
}

.lesezahlen {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: .6rem; margin: 1.4rem 0 0;
}
.lesezahlen > div {
  padding: .6rem .7rem; border: 1px solid var(--linie); border-radius: 10px;
  background: rgba(var(--tint), .03);
}
.lesezahlen dt { font-size: .78rem; color: var(--ink-3); margin: 0; }
.lesezahlen dd {
  margin: .2rem 0 0; font-size: 1.15rem; font-family: var(--schrift-titel);
  font-variant-numeric: tabular-nums;
}

.lesekarten {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: .8rem; margin-bottom: 1.6rem;
}
.lesekarte {
  display: block; padding: .9rem 1rem; border-radius: 12px;
  border: 1px solid var(--linie); background: rgba(var(--tint), .03);
  color: inherit; text-decoration: none;
}
.lesekarte:hover { border-color: var(--marke); box-shadow: var(--schatten-2); }
.lesekarte h3 { margin: .35rem 0 .3rem; font-size: 1.05rem; }
.lesekarte p:last-child { margin: 0; color: var(--ink-2); font-size: .92rem; }

.lesefragen { display: grid; gap: .9rem; }
.lesefrage {
  padding: .9rem 1rem; border: 1px solid var(--linie); border-radius: 12px;
  background: rgba(var(--tint), .03);
}
.lf-frage { margin: 0 0 .6rem; }
.lf-antworten { display: grid; gap: .4rem; }
.lf-antwort {
  text-align: left; padding: .55rem .7rem; border-radius: 9px;
  border: 1px solid var(--linie-kraeftig); background: transparent;
  color: inherit; font: inherit; cursor: pointer;
}
.lf-antwort:hover:not(:disabled) { border-color: var(--marke); }
.lf-antwort:disabled { cursor: default; opacity: 1; }
.lf-richtig { border-color: var(--ok); background: var(--ok-weich); }
.lf-falsch { border-color: var(--fehler); background: var(--fehler-weich); }
.lf-beleg {
  margin: .7rem 0 0; padding-left: .7rem; border-left: 3px solid var(--linie-kraeftig);
  color: var(--ink-2); font-style: italic;
}
.lf-stand { margin-top: 1rem; color: var(--ink-3); }

/* Vom nachgeschlagenen Wort zurück in die Abfrage: der Weg auf die
   Wortliste und der Knopf, der sie auf die Merkliste legt. */
.lw-wege { display: flex; gap: .4rem; margin-top: .5rem !important; flex-wrap: wrap; }
.lw-weg {
  display: inline-block; padding: .25rem .5rem; border-radius: 7px;
  border: 1px solid var(--linie-kraeftig); background: transparent;
  color: inherit; font: inherit; font-size: .82rem; cursor: pointer;
  text-decoration: none;
}
.lw-weg:hover { border-color: var(--marke); }

/* Das Band der Wortlisten unter dem Text trägt eine Zahl je Liste. */
.quellenband .quellen-marke span {
  margin-left: .3rem; padding: 0 .3rem; border-radius: 5px;
  background: rgba(var(--tint), .10); font-variant-numeric: tabular-nums;
}

/* Der Lesestand: was von diesem Text schon sitzt. Dieselben Kacheln wie
   die Messwerte darüber — es ist dieselbe Art von Auskunft, nur über den
   Leser statt über den Text. */
.lesestand { margin-top: 1.6rem; }
.lesestand .lesezahlen { margin-top: .8rem; }
.lesekarte-gelesen { border-color: var(--marke); }
.lese-haken {
  margin-left: .4rem; padding: 0 .35rem; border-radius: 5px;
  background: var(--marke-weich); color: var(--marke-ink); font-size: .78rem;
}

/* Wie viel eines Textes jemand schon kennt — auf der Karte, neben Stufe
   und Länge. Still gesetzt: Es ist eine Auskunft und keine Note. */
.lese-anteil {
  margin-left: .4rem; padding: 0 .35rem; border-radius: 5px;
  border: 1px solid var(--linie-kraeftig); font-size: .78rem;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Der Filter über der Grammatikliste

   Zwei Reihen Chips, und sie sollen wie ein Werkzeug aussehen und nicht wie
   eine Navigation: klein, ruhig, mit der Zahl daneben. Gewählt ist, was
   Farbe hat — `aria-pressed` trägt dieselbe Aussage für alle, die die Farbe
   nicht sehen.
   -------------------------------------------------------------------------- */
.gfilter {
  border: 1px solid var(--linie); border-radius: 12px;
  background: rgba(var(--tint), .03);
  padding: .8rem .9rem; margin: 0 0 1.6rem;
  display: grid; gap: .55rem;
}
.gfilter-reihe { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
/* Mindestens 32px hoch und keine Schrift unter 12,5px: Beides fordert die
   Gruppe `layout`, und beides ist hier keine Schikane — die Chips werden auf
   einem Telefon mit dem Daumen getroffen, und die Zahl daneben ist eine
   Auskunft und keine Verzierung. Die erste Fassung kam auf 28px und 12,48px
   und wurde gemeldet. */
.gfilter-schild {
  font-size: .82rem; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-3); margin-right: .35rem; min-width: 4.2rem;
}
.gchip {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .4rem .7rem; min-height: 34px; border-radius: 999px; font: inherit;
  font-size: .9rem; line-height: 1.2; cursor: pointer;
  border: 1px solid var(--linie-kraeftig); background: transparent;
  color: var(--ink-2);
}
.gchip span {
  font-size: .82rem; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.gchip:hover { border-color: var(--marke); color: var(--ink); }
.gchip[aria-pressed="true"] {
  background: var(--marke); border-color: var(--marke); color: var(--knopf-ink);
}
.gchip[aria-pressed="true"] span { color: var(--knopf-ink); opacity: .8; }
.gchip[data-stufe][aria-pressed="true"] {
  background: var(--stufe-farbe, var(--marke));
  border-color: var(--stufe-farbe, var(--marke));
}
.gfilter-stand { margin: .2rem 0 0; color: var(--ink-3); font-size: .9rem; }

/* --------------------------------------------------------------------
   Glas auf den grossen Kaesten

   Nur auf den grossen: Ein Chip von zwei Zentimetern Breite mit
   Unschaerfe darunter kostet dasselbe wie eine ganze Karte und sieht
   nach nichts aus. `backdrop-filter` ist die teuerste Eigenschaft in
   diesem Stylesheet — sie gehoert dorthin, wo man sie sieht.

   Die Reihenfolge ist Absicht: Diese Regeln stehen am Ende der Datei,
   damit sie das `background: var(--karte)` der Kastenregeln ueberschreiben,
   ohne dass dafuer eine hoehere Spezifitaet noetig waere. Ein
   `!important` waere die andere Loesung und die schlechtere — es nimmt
   der naechsten Aenderung die Moeglichkeit, es anders zu wollen.
   -------------------------------------------------------------------- */
/* **Die Vorführung ist kein Glaskasten**, und sie stand zuerst mit in
   dieser Liste.

   Sie sitzt als Einzige auf der Bühne, also über dem kräftigen Canvas —
   und ihr Inhalt ist eine Übungsaufgabe in kleiner Schrift. Bei siebzig
   Prozent Deckung schlägt der Grund durch, und `thema` hat auf der dunklen
   Fassung 1,67:1 gemessen, wo 4,5 nötig sind: an vier Stellen, alle
   innerhalb dieses einen Kastens.

   Glas ist eine Oberfläche für Karten, die man ansieht. Ein Kasten, in dem
   gelesen wird, braucht einen Grund, der steht. Er behält den Schein und
   den Saum und bekommt seine Deckung zurück. */
.vorfuehrung {
  background: var(--karte);
  box-shadow: var(--schatten-2), var(--halo), var(--glas-saum);
}

.sprachkarte,
.weg,
.aw-karte {
  background: rgba(var(--glas), var(--glas-deckung));
  backdrop-filter: blur(var(--glas-unschaerfe)) saturate(var(--glas-saettigung));
  -webkit-backdrop-filter: blur(var(--glas-unschaerfe)) saturate(var(--glas-saettigung));
  box-shadow: var(--schatten-2), var(--halo), var(--glas-saum);
}

.sprachkarte:hover, .sprachkarte:focus-visible,
.weg:hover, .weg:focus-visible {
  box-shadow: var(--schatten-3), var(--halo-hi), var(--glas-saum);
}

/* Wo es keine Unschaerfe gibt, gibt es auch keine Durchsicht: Eine
   durchscheinende Flaeche ohne den Weichzeichner darunter ist kein Glas,
   sondern ein Text auf einem unruhigen Grund. Dann lieber deckend. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .sprachkarte, .weg, .aw-karte { background: var(--karte); }
}

/* Wer wenig Bewegung will, will auch keinen wandernden Hintergrund durch
   seine Kaesten schimmern sehen. */
@media (prefers-reduced-transparency: reduce) {
  .sprachkarte, .weg, .aw-karte {
    background: var(--karte);
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
}

/* Der Herausgeber ganz oben auf dem Impressum: ruhig, nicht klein
   gedruckt. Wer diese Seite aufschlaegt, sucht genau das. */
.impressum-herausgeber {
  margin: 0 0 1.2rem; color: var(--ink-2); font-size: 1.02rem;
}


/* Die Endung in einer Formtabelle.
   Farbe **und** Gewicht, nicht nur Farbe: Wer Rot und Gruen nicht
   auseinanderhaelt, sieht sonst eine Tabelle ohne jede Hervorhebung. Die
   Marke traegt die Farbe, weil sie auf beiden Fassungen gemessen ist —
   ein eigener Ton waere ein zweiter, den `pruefen.sh thema` erst wieder
   prueft, wenn jemand daran denkt. */
.formtabelle .endung {
  color: var(--marke-ink); font-weight: 700;
}

/* --- Der Zeitstrahl ---------------------------------------------------------

   Die Achse läuft über tausend Einheiten und nicht über hundert, damit das
   Seitenverhältnis von selbst stimmt. Der erste Entwurf rechnete in
   Hundertstel und stellte `preserveAspectRatio="none"` — bei zwölf Spuren
   ergab das ein Bild von knapp viertausend Pixeln Höhe, und bei ungleicher
   Streckung wäre aus jedem Punkt eine Ellipse geworden.

   Das Bild ist ein `role="img"`; bedient wird die Liste darunter. Wer mit
   der Maus über eine Zeile fährt, sieht ihre Spur aufleuchten — auf
   Zeigergeräten, wie überall sonst auf dieser Seite. */
.zeitstrahl-block { margin: 1.4rem 0 2rem; }
.zeitstrahl {
  width: 100%; height: auto; display: block;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--rund-s); padding: .4rem 0;
}
.zs-achse { stroke: var(--linie-kraeftig); stroke-width: 1.5; }
.zs-jetzt {
  stroke: var(--marke); stroke-width: 1.5; stroke-dasharray: 4 4;
  opacity: .75;
}
.zs-marke {
  font-size: 13px; fill: var(--ink-3); font-family: var(--schrift);
}
.zs-jetzt-text { fill: var(--marke-ink); font-weight: 600; }
.zs-grund { stroke: var(--linie); stroke-width: 1; }
.zs-punkt { fill: var(--marke); stroke: none; }
.zs-bezug { fill: none; stroke: var(--ink-3); stroke-width: 1.2; }
.zs-spanne { stroke: var(--marke); stroke-width: 7; stroke-linecap: round; }
.zs-bis { stroke: var(--marke); stroke-width: 7; stroke-linecap: butt; }
.zs-band {
  stroke: var(--marke); stroke-width: 5; stroke-dasharray: 10 7;
  opacity: .8; stroke-linecap: butt;
}
/* Beim Hervorheben treten die anderen zurück, statt dass eine lauter
   wird: Elf gedämpfte Spuren und eine normale liest sich als „diese hier";
   eine grelle unter elf normalen liest sich als Fehler.

   Die hervorgehobene bekommt eine Klasse und wird nicht über ihren Index
   im Stylesheet angesprochen — CSS kann ein `data-spur` nicht gegen einen
   Wert am Vorfahren halten, und zwölf Regeln zu schreiben wäre eine
   Tabelle neben einer abgeleiteten. */
.zs-spur { opacity: .55; transition: opacity .12s; }
.zeitstrahl-block[data-hell] .zs-spur { opacity: .16; }
.zeitstrahl-block[data-hell] .zs-spur.zs-an { opacity: 1; }
.zs-zeile.zs-an { background: var(--karte-2); }

.zs-legende {
  display: flex; flex-wrap: wrap; gap: .3rem 1.1rem;
  margin: .6rem 0 1rem; font-size: .84rem; color: var(--ink-3);
}
.zs-legende > span { display: inline-flex; align-items: center; gap: .4rem; }
.zs-zeichen { display: inline-block; width: 1.1rem; height: .5rem; }
.zs-z-punkt {
  width: .5rem; height: .5rem; border-radius: 50%; background: var(--marke);
}
.zs-z-spanne { background: var(--marke); border-radius: 999px; height: .32rem; }
.zs-z-bis { background: var(--marke); height: .32rem; }
.zs-z-band {
  height: .3rem;
  background: repeating-linear-gradient(90deg, var(--marke) 0 .3rem,
              transparent .3rem .5rem);
}
.zs-z-bezug {
  width: .5rem; height: .5rem; border-radius: 50%;
  border: 1.5px solid var(--ink-3);
}

.zs-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.zs-zeile {
  display: grid; gap: .1rem .9rem; padding: .45rem .6rem;
  border-bottom: 1px solid var(--linie);
  grid-template-columns: minmax(0, 15rem) minmax(0, 11rem) minmax(0, 1fr);
  align-items: baseline;
}
.zs-zeile > a, .zs-zeile > span:first-child { font-weight: 600; }
.zs-zeile > a {
  display: inline-flex; align-items: center; min-height: 32px;
}
.zs-form { color: var(--ink-2); font-size: .93rem; }
.zs-wann { color: var(--ink-3); font-size: .93rem; }
@media (max-width: 46rem) {
  .zs-zeile { grid-template-columns: minmax(0, 1fr) auto; }
  .zs-wann { grid-column: 1 / -1; }
}

/* --- Die Stufenseite, nach Familien -----------------------------------------

   Nebeneinander und nicht untereinander: Auf einer einzelnen Stufe hat ein
   Bereich oft ein oder zwei Themen, und in einer Spalte wird daraus eine
   Kolonne aus Überschriften. `auto-fill` mit einer Mindestbreite statt
   einer festen Spaltenzahl — auf dem Telefon bleibt es eine Spalte, ohne
   dass dafür eine eigene Regel nötig wäre. */
.stufe-familien {
  display: grid; gap: 1.6rem 2rem; margin-bottom: 2rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr));
  align-items: start;
}
.stufe-familie { min-width: 0; }
.stufe-familie-kopf {
  display: flex; align-items: center; gap: .5rem;
  margin: 0 0 .7rem; font-size: 1.18rem;
  padding-bottom: .35rem; border-bottom: 1px solid var(--linie-kraeftig);
}
.stufe-familie-kopf .zeile-still { margin-left: auto; font-size: .82rem; }
.stufe-familie .bereich-block { margin: 0 0 1rem; }
.stufe-familie .bereich-kopf h3 {
  margin: 0; font-size: 1rem; font-family: var(--schrift-titel);
}

/* --- Die Inhaltsleiste der Grammatik ----------------------------------------

   Am breiten Fenster eine Spalte links, klebend, mit eigener Rolle: Wer
   ein Thema liest, sieht daneben, wo es sitzt. Auf dem Telefon steht sie
   **unter** dem Text — `order: 2` —, denn hundert Verweise vor dem ersten
   Satz sind keine Navigation, sondern eine Mauer.

   Es ist ein `<details open>`: Die Zusammenfassung ist am Rand überflüssig
   und wird dort ausgeblendet, auf dem Telefon ist sie der Griff zum
   Zuklappen. Beides ohne eine Zeile JavaScript, und nichts ist je
   verborgen, ohne dass ein Griff daneben liegt. */
.mit-gnav { display: grid; gap: 1.4rem 2.2rem; }
.mit-gnav > .gnav { order: 2; }
.mit-gnav > .dokument { order: 1; min-width: 0; }

.gnav { font-size: .92rem; }
.gnav-kopf {
  cursor: pointer; font-family: var(--schrift-titel); font-weight: 600;
  padding: .55rem .8rem; border: 1px solid var(--linie);
  border-radius: var(--rund-s); background: var(--karte);
}
.gnav-familie { margin-bottom: 1.1rem; }
.gnav-familie-kopf {
  display: flex; align-items: center; gap: .45rem;
  margin: 0 0 .35rem; font-size: .95rem;
  padding-bottom: .25rem; border-bottom: 1px solid var(--linie);
}
.gnav-familie-kopf .gfam-zeichen svg { width: 1em; height: 1em; }
.gnav-bereich {
  margin: .55rem 0 .2rem; font-size: .8rem; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-3);
}
.gnav-themen { list-style: none; margin: 0; padding: 0; }
/* Zweiunddreißig Pixel hoch, weil ein Ziel, das man mit dem Daumen
   treffen soll, so hoch sein muss. `layout` besteht darauf, und in einer
   Leiste mit hundertzwanzig Verweisen ist es besonders wahr. */
.gnav-themen a {
  display: flex; align-items: center; gap: .4rem; min-height: 32px;
  padding: .25rem .35rem; border-radius: var(--rund-s);
  color: var(--ink-2); text-decoration: none; line-height: 1.35;
}
.gnav-themen a:hover { background: var(--karte-2); color: var(--ink); }
.gnav-themen a[aria-current="page"] {
  background: var(--karte-2); color: var(--ink); font-weight: 600;
  box-shadow: inset 2px 0 0 var(--marke);
}
.gnav-stufe {
  margin-left: auto; font-size: .8rem; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

@media (min-width: 64rem) {
  .mit-gnav { grid-template-columns: 15.5rem minmax(0, 1fr); }
  .mit-gnav > .gnav { order: 0; }
  .mit-gnav > .gnav > summary { display: none; }
  .gnav > .gnav-inhalt {
    position: sticky; top: 5rem; max-height: calc(100vh - 7rem);
    overflow-y: auto; padding-right: .4rem;
  }
}
