/* Routetree — Gestaltungssystem
 *
 * Dauerhaft dunkel, auf Wunsch von Niklas. Das Werkzeug wird abends am
 * Kuechentisch und am Spieltag am Rand des Platzes bedient; ein einziges
 * Thema haelt die Oberflaeche berechenbar und spart den Umschalter.
 *
 * Die Farben sind keine Erfindung, sondern die Notation der Zeichnung:
 * Petrol steht in Diagramm und Oberflaeche fuer Deckung und Bedienung,
 * Gold fuer den Ball, Ziegelrot fuer die Defense. Der AUSDRUCK bleibt
 * hell -- Papier hat kein dunkles Thema, die Druckfarben stehen fest in
 * designer/render.py.
 */

:root {
  /* --- Grundflaechen. Dunkel, mit einem Hauch Petrol im Neutralton. */
  --flaeche:        oklch(0.175 0.012 240);
  --flaeche-panel:  oklch(0.215 0.014 240);
  --flaeche-hoch:   oklch(0.252 0.014 240);
  --flaeche-tief:   oklch(0.148 0.012 240);

  /* --- Schrift */
  --ink:            oklch(0.945 0.006 240);
  --ink-leise:      oklch(0.795 0.010 240);
  --ink-still:      oklch(0.655 0.012 240);

  /* --- Linien */
  --linie:          oklch(0.305 0.014 240);
  --linie-stark:    oklch(0.405 0.016 240);

  /* --- Bedeutung. Identisch mit der Diagrammnotation. */
  --petrol:         oklch(0.755 0.078 220);
  /* Der Akzent der Marke IST Petrol. Bis heute benutzte die Startseite
     `--akzent`, ohne dass es definiert war -- sie fiel damit still auf
     Gold zurueck, also auf die WARNFARBE. Ein Fehler, den man nicht
     sieht, weil beides fuer sich gut aussieht. */
  --akzent:         oklch(0.755 0.078 220);
  --petrol-tief:    oklch(0.825 0.070 220);
  --auf-petrol:     oklch(0.16 0.012 240);
  --petrol-hell:    oklch(0.285 0.036 222);
  --petrol-rand:    oklch(0.405 0.050 222);
  --gold:           oklch(0.790 0.105 78);
  --gold-hell:      oklch(0.285 0.040 70);
  --ziegel:         oklch(0.715 0.115 32);
  --ziegel-hell:    oklch(0.275 0.045 32);

  /* --- Zustaende */
  --gut:            oklch(0.735 0.115 155);
  --warnung:        oklch(0.790 0.105 78);
  --fehler:         oklch(0.720 0.140 27);
  --fehler-hell:    oklch(0.270 0.055 27);

  /* --- Schrift: zwei Familien mit klarer Aufgabenteilung.
     Barlow liest sich in kleinen Groessen ruhig und ist fuer Beschriftung
     gezeichnet worden, nicht fuer Fliesstext im Roman. Genau das ist der
     Fall hier: kurze Zeilen, viele Zahlen, oft im Hellen auf dem Platz.
     Barlow Condensed traegt die Marke und die Ueberschriften. Schmal
     laufende Grotesk ist die Schriftsprache des Sports, von der
     Anzeigetafel bis zum Trikot, und sie bringt lange deutsche Woerter
     wie „Mannschaftseinstellungen" in einer Zeile unter.
     Beide liegen im Projekt, nicht bei Google -- siehe schrift.css. */
  /* „Barlow Ersatz" steht DIREKT hinter dem Original und vor allem
     anderen (Pruefbericht 10.10.2026, Befund 5). Es ist keine Schrift,
     sondern eine Massangabe: die Umrisse der Systemschrift, gezwungen
     auf Barlows Hoehe und Breite. Solange Barlow unterwegs ist, steht
     der Text damit schon an der richtigen Stelle; beim Tausch rueckt
     nichts mehr. Definiert in `schrift.css`. */
  --schrift: "Barlow", "Barlow Ersatz", ui-sans-serif, system-ui,
             -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
             sans-serif;
  --schrift-marke: "Barlow Condensed", "Barlow Condensed Ersatz",
                   "Barlow", "Barlow Ersatz", ui-sans-serif, system-ui,
                   sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --t-xs:   0.6875rem;
  --t-sm:   0.8125rem;
  --t-base: 0.9375rem;
  --t-md:   1.0625rem;
  --t-lg:   1.25rem;
  --t-xl:   1.5rem;

  /* Rund statt eckig -- durchgaengig, nicht nur an Kacheln. */
  --r1: 8px;
  --r2: 12px;
  --r3: 18px;
  --r4: 26px;
  --rund: 999px;

  --schatten-1: 0 1px 2px oklch(0 0 0 / .32);
  --schatten-2: 0 2px 6px oklch(0 0 0 / .36), 0 10px 28px oklch(0 0 0 / .32);

  /* --- Ebenen. Benannt, nie willkuerliche Zahlen. */
  --z-inhalt: 1;
  --z-haftend: 20;
  --z-menue: 40;
  --z-hinweis: 60;

  --tempo: 180ms;
  --kurve: cubic-bezier(0.22, 1, 0.36, 1);

  /* Formularelemente und Bildlaufleisten sollen mitziehen. */
  color-scheme: dark;
}

/* --- Grundlagen ---------------------------------------------------- */

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

/* `hidden` MUSS GEWINNEN, und dafuer braucht es `!important`.
 *
 * Die Browservorgabe ist `[hidden] { display: none }` -- Spezifitaet
 * (0,1,0). Jede eigene Regel mit einer Klasse davor ist spezifischer:
 * `.hilfe-liste dt { display: flex }` ist (0,1,1) und schlaegt sie.
 * Das Element bleibt sichtbar, obwohl ein Skript es ausgeblendet hat,
 * und das sieht nicht nach einem Stilfehler aus, sondern nach einem
 * kaputten Filter.
 *
 * GENAU DAS IST HIER SCHON ACHTMAL PASSIERT. In `editor.css` stehen
 * acht handgeschriebene Pflaster derselben Sorte -- `.wz[hidden]`,
 * `.block[hidden]`, `.toast[hidden]`, `.zeichenhilfe[hidden]`,
 * `.abspielleiste[hidden]`, `.hinweisleiste[hidden]`,
 * `.sperrleiste[hidden]`, `.regelleiste[hidden]` --, jedes mit einem
 * Kommentar, der dieselbe Ursache beschreibt. Das neunte fiel am
 * 10.09.2026 beim Filter der Hilfeseite auf: Die Suche fand zwei von
 * 121 Eintraegen und zeigte trotzdem alle an.
 *
 * Acht Pflaster sind der Beweis, dass die Wunde eine Regel braucht.
 * `!important` ist hier nicht Gewalt, sondern die Aussage: `hidden`
 * heisst weg, ohne Ausnahme. (Dieselbe Zeile steht aus demselben Grund
 * in jedem verbreiteten Stil-Grundgeruest.)
 *
 * Die acht bleiben stehen: Sie schaden nicht, und sie sind der Beleg
 * fuer diesen Kommentar. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--flaeche);
  color: var(--ink);
  font-family: var(--schrift);
  font-size: var(--t-base);
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;

  /* DIE SEITE FUELLT DEN BILDSCHIRM, damit die Fusszeile unten steht.
     Ohne das endete eine kurze Seite -- Anmelden, Passwort, eine
     Meldung -- mitten im Bild, und darunter lag ein leeres Feld in
     einer anderen Farbe. Gemeldet am 27.08.2026: „der footer haengt
     mitten im bildschirm".
     `100dvh` und nicht `100vh`: Auf dem Handy zaehlt `vh` die
     Adressleiste mit, die beim Scrollen verschwindet -- die Seite
     springt dann. `dvh` misst, was wirklich da ist. */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* Der Inhalt waechst, die Fusszeile bleibt unten. `.werkbank` gehoert
   dazu: Der Editor hat kein `<main>`, sondern seine eigene Flaeche --
   und die soll erst recht die volle Hoehe haben.

   UND DER INHALT DEHNT DIE SEITE NICHT AUF.

   `body` ist ein Flex-Container (siehe oben). Ein Flex-Kind bekommt
   dadurch `min-width: auto`, und das heisst: die Mindestbreite seines
   breitesten Inhalts. Auf `/flag-football-regeln/` ist das eine
   Tabelle mit acht Spalten und `min-width: 544px` je Zelle. `main`
   wurde damit 833 px breit in einem 390-px-Fenster, und die GANZE
   Seite schob sich mit: Ueberschrift, Fliesstext, Fusszeile. Der
   Rahmen mit `overflow-x: auto` konnte nicht scrollen, weil er selbst
   mitgedehnt wurde.

   Gemessen am 10.10.2026 auf 24 von 62 Pfaden, also 144 von 357
   Adressen. Es traf ausgerechnet die Regelvergleiche, die ueber
   Suchmaschinen gefunden werden sollen. Dieselbe Ursache erzeugte den
   schlechtesten Layout-Sprung der Seite (CLS 0,561).

   `min-width: 0` nimmt die Vorgabe zurueck, `max-width: 100%` ist der
   Deckel dagegen, dass eine kuenftige feste Breite dasselbe wieder
   anrichtet. `test_kein_querscrollen.py` misst es nach. */
body > main,
body > .werkbank { flex: 1 0 auto; min-width: 0; max-width: 100%; }

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -0.012em;
             text-wrap: balance; }
h1 { font-size: var(--t-xl); }
h2 { font-size: var(--t-lg); }
h3 { font-size: var(--t-md); }
p { margin: 0 0 0.75rem; max-width: 68ch; text-wrap: pretty; }

a { color: var(--petrol); text-underline-offset: 2px; }

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

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

/* --- Kopfleiste ----------------------------------------------------- */

.kopfleiste {
  position: sticky; top: 0; z-index: var(--z-haftend);
  display: flex; align-items: center; gap: 1rem;
  padding: 0.55rem 1rem;
  background: var(--flaeche-panel);
  border-bottom: 1px solid var(--linie);
}

/* DIE SICHERE ZONE DES GERAETS (10.09.2026).
 *
 * `base.html` setzt `viewport-fit=cover`, und das Manifest sagt
 * `standalone`. Beides zusammen heisst: In der installierten Fassung
 * geht die Seite unter die Statusleiste und unter den Balken am unteren
 * Rand -- der klebende Kopf lag dort halb unter der Uhrzeit, und die
 * unterste Zeile der Fusszeile hinter dem Homebalken.
 *
 * `viewport-fit=cover` OHNE `safe-area-inset` ist genau dieser Fehler.
 * Wer den Rand nicht selbst zurueckgibt, hat ihn dem Geraet geschenkt.
 *
 * `max(...)` und nicht `+`: Am Browser ohne Kerbe ist der Wert 0, und
 * dann soll der gewohnte Innenabstand stehen bleiben, nicht null. */
.kopfleiste {
  padding-top: max(0.55rem, env(safe-area-inset-top));
  padding-left: max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
}

/* Die Marke: Zeichen und Wort, immer zusammen.
   Das Zeichen nimmt seine Farbe ueber `currentColor` vom Text, damit es
   in Kopfleiste, Fusszeile und auf hellem Grund ohne eigene Fassung
   funktioniert. */
.marke {
  display: flex; align-items: center; gap: 0.5rem;
  color: var(--petrol); text-decoration: none; white-space: nowrap;
}
.marke-zeichen { width: 1.35rem; height: 1.35rem; flex: none; }
.marke-wort {
  font-family: var(--schrift-marke);
  font-weight: 700; font-size: 1.28rem; line-height: 1;
  letter-spacing: 0.002em; color: var(--ink);
}
.marke .marke-zusatz {
  font-family: var(--schrift-marke);
  font-weight: 600; font-size: 0.86rem; line-height: 1;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-still); align-self: center;
}
.marke.klein .marke-zeichen { width: 1.1rem; height: 1.1rem; }
.marke.klein .marke-wort { font-size: 1.05rem; }

/* Auf schmalen Geraeten faellt der Zusatz weg, bevor die Leiste bricht. */
@media (max-width: 620px) { .marke .marke-zusatz { display: none; } }

/* --- Fusszeile ------------------------------------------------------- */

.fussleiste {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 0.75rem 1.5rem;
  margin-top: 3rem; padding: 1.25rem clamp(0.9rem, 3vw, 2rem);
  /* Der Homebalken liegt sonst auf der letzten Zeile -- und dort
     stehen „Verträge hier kündigen" und „Vertrag widerrufen". */
  padding-bottom: max(1.25rem, env(safe-area-inset-bottom));
  border-top: 1px solid var(--linie);
  background: var(--flaeche-tief);
  font-size: var(--t-sm);
}
.fussleiste nav { display: flex; gap: 1.25rem; flex-wrap: wrap; }
/* ZWEI GRUPPEN, UND MAN SIEHT ES (10.09.2026). Die erste muss von
   Rechts wegen hier stehen (Impressum, Datenschutz und die beiden
   Pflichtschaltflächen aus § 312k und § 356a), die zweite steht hier,
   weil sie nützt. Der Unterschied ist ein Trenner und etwas Ruhe --
   nicht zwei Kästen: Eine Fußzeile mit Rahmen sieht aus wie ein
   Formular. */
.fuss-pflicht { font-weight: 500; }
.fuss-dienst { color: var(--ink-leise); }
.fuss-dienst::before {
  content: ""; align-self: stretch; width: 1px;
  background: var(--linie); margin-right: .25rem;
}
@media (max-width: 46rem) {
  /* Auf dem Telefon stehen sie untereinander -- ein senkrechter
     Trenner zwischen zwei umgebrochenen Reihen zeigt nach nirgendwo. */
  .fuss-dienst::before { display: none; }
}
.fussleiste a:not(.marke) { color: var(--ink-still); text-decoration: none; }
.fussleiste a:not(.marke):hover { color: var(--ink); text-decoration: underline; }

/* Auf den Druckseiten hat die Fusszeile nichts verloren. */
@media print { .fussleiste { display: none; } }

.kopf-pfad {
  display: flex; align-items: center; gap: 0.4rem; min-width: 0;
  font-size: var(--t-sm); color: var(--ink-leise);
}
.kopf-pfad a { color: var(--ink-leise); text-decoration: none; }
.kopf-pfad a:hover { color: var(--ink); text-decoration: underline; }
.kopf-pfad .jetzt { color: var(--ink); font-weight: 600;
                    overflow: hidden; text-overflow: ellipsis;
                    white-space: nowrap; }
.kopf-rechts { margin-left: auto; display: flex; align-items: center;
               gap: 0.4rem; }

/* DER HILFEKNOPF (R28). Fragezeichen und Wort.

   Auf dem Telefon faellt das WORT weg, nicht das Zeichen: In der
   Kopfleiste ist jeder Buchstabe Platz, den die Zeichenflaeche
   verliert -- und ein Fragezeichen versteht man ohne Uebersetzung.
   Der `title` bleibt in beiden Faellen stehen, und ein
   Vorleseprogramm liest ihn. */
.hilfeknopf { gap: 0.35rem; }
@media (max-width: 46rem) {
  .hilfeknopf .wort { display: none; }
}

/* DIE GANZE SEITE WAR BREITER ALS DER BILDSCHIRM.

   Gemeldet von Niklas am 28.08.2026 mit Bildschirmfoto: „Also der Editor
   in der Handy Web Version ist richtig kacke." Auf dem Bild ist der Kopf
   rechts abgeschnitten („nickynice1", „Abmelden" hinter der Kante), und
   alles liegt seitlich versetzt.

   DIE URSACHE IST DIESE ZEILE DARUEBER: `.kopf-rechts` ist ein `flex`
   ohne Umbruch. Im Editor haengen dort sechs Dinge nebeneinander --
   Spieleransicht, Als PDF, Als Bild, Play loeschen, der Kontoname und
   Abmelden. Auf einem breiten Bildschirm passt das; auf 390 Pixeln
   schiebt es die ganze Seite auseinander.

   Ein Umbruch waere die naheliegende Antwort und die falsche: Der Kopf
   klebt oben (`position: sticky`) und waere dann drei Zeilen hoch -- auf
   einem Telefon ein Drittel der Zeichenflaeche. Also ein Streifen, der
   sich seitlich schieben laesst, wie die Registerleiste eines Browsers.
   Nichts wird abgeschnitten, nichts waechst in die Hoehe, und die Seite
   bleibt so breit wie der Bildschirm.

   **WARUM SIE HIER STEHT UND NICHT IN `editor.css`.** Genau dort stand
   sie zuerst, und das war der Fehler: Die Kopfleiste gehoert allen
   Seiten. Die Spieleransicht -- dieselbe Leiste, vier Knoepfe -- war
   danach immer noch 134 Pixel zu breit. Gemerkt hat das niemand; die
   Ueberlaufmessung in `rundgang.py` hat es gemessen. */
@media (max-width: 820px) {
  .kopfleiste { max-width: 100%; gap: 0.6rem; }
  .kopfleiste > * { min-width: 0; }

  /* DIE MARKE SCHRUMPFT NICHT MIT.
     `min-width: 0` daruber erlaubt jedem Kind, kleiner zu werden als
     sein Inhalt. Die Marke hat aber `white-space: nowrap` und kein
     `overflow: hidden` -- sie wurde also nicht kuerzer, sondern lief
     aus ihrem eigenen Kasten heraus und LEGTE SICH UEBER die Knoepfe
     daneben. Auf der ersten Messung stand „Routetree" quer ueber
     „Spread Mesh". Kein Ueberlauf mehr, und trotzdem falsch. */
  .kopfleiste > .marke { flex: 0 0 auto; }

  .kopf-rechts {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    flex: 1 1 auto;
    /* VON LINKS, nicht von rechts. Ein Streifen mit `flex-end` steht
       beim Aufschlagen am ENDE -- sichtbar waere „Abmelden", und der
       erste Knopf laege ausserhalb des Bildes. Von links gelesen steht
       das Wichtigste zuerst, und der Rest ist einen Wisch entfernt. */
    justify-content: flex-start;
    padding-bottom: 0.15rem;

    /* UND EIN ZEICHEN, DASS ES WEITERGEHT (10.09.2026).
     *
     * `scrollbar-width: none` nimmt den einzigen Hinweis darauf weg,
     * dass der Streifen schiebbar ist -- richtig, denn ein Balken im
     * Kopf sieht nach Fehler aus. Nur blieb danach GAR NICHTS: Am
     * rechten Rand endete ein Knopf mitten im Wort und sah aus, als
     * fehle etwas.
     *
     * Eine weiche Maske macht daraus „da geht es weiter". Sie liegt
     * nur an der Seite, an der wirklich noch etwas kommt: Die beiden
     * Verläufe hängen an der Scroll-Position (`scroll-timeline` gibt
     * es nicht überall), deshalb der einfache, immer richtige Weg --
     * rechts ausblenden, solange der Streifen breiter ist als sein
     * Platz. Ist er es nicht, greift `mask` auf voller Breite und
     * ändert nichts.
     *
     * `mask` maskiert, es zeichnet nicht: Auf Geräten ohne
     * Unterstützung sieht es aus wie vorher. */
    mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 1.6rem),
                                transparent 100%);
    -webkit-mask-image: linear-gradient(to right, #000 0,
                                        #000 calc(100% - 1.6rem),
                                        transparent 100%);
  }
  .kopf-rechts::-webkit-scrollbar { display: none; }
  .kopf-rechts > * { flex: 0 0 auto; }
  /* Der letzte Knopf braucht Luft, sonst frisst die Maske sein Wort. */
  .kopf-rechts > :last-child { margin-right: 1.4rem; }
}

/* --- Schaltflaechen -------------------------------------------------- */

.knopf {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4rem;
  min-height: 34px; padding: 0 0.75rem;
  font: inherit; font-size: var(--t-sm); font-weight: 600;
  color: var(--ink);
  background: var(--flaeche-hoch);
  border: 1px solid var(--linie-stark);
  border-radius: var(--rund);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--tempo) var(--kurve),
              border-color var(--tempo) var(--kurve),
              color var(--tempo) var(--kurve);
}
.knopf:hover { background: var(--flaeche-tief); border-color: var(--ink-still); }
.knopf:active { background: var(--flaeche-tief); transform: translateY(0.5px); }
.knopf[disabled], .knopf[aria-disabled="true"] {
  opacity: 0.5; cursor: not-allowed; pointer-events: none;
}

.knopf.haupt {
  color: var(--auf-petrol); background: var(--petrol);
  border-color: var(--petrol);
}
.knopf.haupt:hover { background: var(--petrol-tief); border-color: var(--petrol-tief); }

.knopf.leise { background: transparent; border-color: transparent;
               color: var(--ink-leise); }
.knopf.leise:hover { background: var(--flaeche-tief); color: var(--ink); }

.knopf.klein { min-height: 28px; padding: 0 0.5rem; font-size: var(--t-xs); }

/* --- Formularfelder -------------------------------------------------- */

.feld { display: flex; flex-direction: column; gap: 0.25rem; }
.feld > label {
  font-size: var(--t-xs); font-weight: 650; color: var(--ink-leise);
  letter-spacing: 0.02em;
}

/* Nebensache im Label (Wertebereich) und erklaerende Zeile unter einem Feld.
   Bewusst zurueckgenommen: Die Erklaerung soll da sein, wenn jemand sie sucht,
   und sonst nicht mit dem Wert um Aufmerksamkeit streiten. */
.feld > label .feldnebensache {
  font-weight: 400; color: var(--ink-still); letter-spacing: 0;
}
.feld > label .feldnebensache::before { content: "· "; }
.feldhinweis {
  margin: 0; font-size: var(--t-xs); line-height: 1.35; color: var(--ink-still);
}
/* Bewusst --ziegel und nicht --ziegel-hell: letzteres ist mit Helligkeit
   0,275 eine dunkle Toenung fuer Flaechen und waere als Schrift auf dem
   dunklen Grund nicht zu lesen. */
.feldhinweis.fehler { color: var(--ziegel); font-weight: 600; }
input[aria-invalid="true"], select[aria-invalid="true"] {
  border-color: var(--ziegel);
}
input[aria-invalid="true"]:focus { outline-color: var(--ziegel); }

input:not([type="file"], [type="checkbox"], [type="radio"], [type="range"],
           [type="color"], [type="submit"], [type="button"], [type="reset"],
           [type="image"], [type="hidden"]),
select, textarea {
  font: inherit; font-size: var(--t-sm);
  color: var(--ink);
  background: var(--flaeche-hoch);
  border: 1px solid var(--linie-stark);
  border-radius: var(--r2);
  padding: 0.4rem 0.55rem;
  min-height: 34px;
  width: 100%;
  transition: border-color var(--tempo) var(--kurve);
}
input:hover, select:hover, textarea:hover { border-color: var(--ink-still); }
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--petrol); outline-offset: 0; border-color: var(--petrol);
}
input::placeholder, textarea::placeholder { color: var(--ink-still); }
textarea { min-height: 76px; resize: vertical; line-height: 1.5; }

/* --- Etiketten ------------------------------------------------------- */

.chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.1rem 0.4rem;
  font-size: var(--t-xs); font-weight: 650;
  border: 1px solid var(--linie-stark); border-radius: var(--r1);
  color: var(--ink-leise); background: var(--flaeche-hoch);
  white-space: nowrap;
}
.chip .punkt { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.chip.warn { color: var(--gold); border-color: var(--gold);
             background: var(--gold-hell); }

/* --- Seiten ---------------------------------------------------------- */

/* `min(1080px, 100%)` UND NICHT `1080px`.
   `body` ist ein Flex-Container, `main` also ein Flex-Kind mit
   `flex: 1 0 auto`: Es nimmt die Breite seines Inhalts. `max-width:
   1080px` erlaubt das bis 1080 und greift auf einem 390-px-Telefon
   deshalb nie. Auf `/flag-football-regeln/` wurde `main` so 732 px
   breit, und die ganze Seite schob sich waagerecht mit.
   Gemessen am 10.10.2026 auf 24 von 62 Pfaden. `100%` ist der
   fehlende zweite Deckel; `min()` behaelt den ersten fuer grosse
   Bildschirme. */
.seite { max-width: min(1080px, 100%); margin: 0 auto;
         padding: 1.75rem 1rem 4rem; }
.seitenkopf { display: flex; align-items: flex-end; gap: 1rem;
              margin-bottom: 1.25rem; flex-wrap: wrap; }
.seitenkopf .wachsen { flex: 1 1 auto; min-width: 0; }
.seitenkopf p { margin: 0.15rem 0 0; color: var(--ink-leise);
                font-size: var(--t-sm); }

/* --- Listen statt Kacheln -------------------------------------------- */

.liste { border: 1px solid var(--linie); border-radius: var(--r3);
         overflow: hidden; background: var(--flaeche-hoch); }
.liste > * + * { border-top: 1px solid var(--linie); }

.zeile {
  display: flex; align-items: center; gap: 0.85rem;
  padding: 0.7rem 0.9rem;
  text-decoration: none; color: inherit;
  transition: background var(--tempo) var(--kurve);
}
a.zeile:hover { background: var(--flaeche-panel); }
.zeile .titel { font-weight: 600; }
.zeile .unter { font-size: var(--t-sm); color: var(--ink-leise); }
.zeile .wachsen { flex: 1 1 auto; min-width: 0; }
.zeile .nummer {
  font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-still);
  font-variant-numeric: tabular-nums; min-width: 2ch; text-align: right;
}

/* --- Leerzustand: erklaert, statt nur festzustellen ------------------ */

.leerzustand {
  border: 1px dashed var(--linie-stark); border-radius: var(--r3);
  padding: 2rem 1.5rem; text-align: center; background: var(--flaeche-panel);
}
.leerzustand h3 { margin-bottom: 0.3rem; }
.leerzustand p { margin: 0 auto 1rem; color: var(--ink-leise);
                 max-width: 46ch; font-size: var(--t-sm); }

/* --- Meldungen -------------------------------------------------------- */

.meldung {
  display: flex; align-items: flex-start; gap: 0.5rem;
  padding: 0.6rem 0.75rem; border-radius: var(--r2);
  font-size: var(--t-sm);
  border: 1px solid var(--linie-stark); background: var(--flaeche-panel);
}
.meldung.fehler { color: var(--fehler); border-color: var(--fehler);
                  background: var(--fehler-hell); }
/* Die WARNUNG, nachgereicht am 10.09.2026 mit der Kaufstrecke.

   Der erste Anlauf hiess `.hinweis` -- eine zweite Meldungsklasse neben
   dieser, also zwei Arten, dasselbe zu sagen, und in einem halben Jahr
   zwei, die verschieden aussehen. `test_klassen_haben_regeln.py` hat es
   gefunden, bevor es soweit kam.

   Gold ist im ganzen Haus die Warnfarbe; sie steht fuer „lies das", der
   Ziegelton fuer „hier ist etwas kaputt". Der Testbetrieb ist genau das
   Erste: Es funktioniert alles, nur wird kein Geld abgebucht. */
.meldung.warnung { color: var(--gold); border-color: var(--gold);
                   background: var(--gold-hell); }

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

/* ======================================================================
   Oberflaechen — Glaskacheln
   ----------------------------------------------------------------------
   Auf Wunsch von Niklas: runde, spiegelnde Kacheln statt Formularseiten.
   Damit Glas ueberhaupt wirkt, braucht der Hintergrund etwas zum Brechen —
   deshalb zwei sehr schwache Lichtquellen hinter allem. Ohne die waere
   der Weichzeichner reine Behauptung.
   ====================================================================== */

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(58rem 40rem at 12% -8%,
      oklch(0.755 0.078 220 / .16), transparent 62%),
    radial-gradient(46rem 34rem at 96% 4%,
      oklch(0.790 0.105 78 / .10), transparent 60%),
    radial-gradient(70rem 50rem at 50% 118%,
      oklch(0.715 0.115 32 / .07), transparent 64%);
}
body > * { position: relative; z-index: var(--z-inhalt); }

/* --- die Kachel selbst ------------------------------------------------ */

.kachel {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  padding: 1.15rem 1.2rem;
  border-radius: var(--r3);
  background: linear-gradient(
      160deg,
      oklch(1 0 0 / .075) 0%,
      oklch(1 0 0 / .028) 42%,
      oklch(1 0 0 / .012) 100%);
  border: 1px solid oklch(1 0 0 / .085);
  backdrop-filter: blur(18px) saturate(1.25);
  -webkit-backdrop-filter: blur(18px) saturate(1.25);
  box-shadow:
    0 1px 0 0 oklch(1 0 0 / .11) inset,
    0 18px 40px -22px oklch(0 0 0 / .8);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  transition: transform var(--tempo) var(--kurve),
              border-color var(--tempo) var(--kurve),
              box-shadow var(--tempo) var(--kurve);
}

/* DAS VORSCHAUBILD IN DER KACHEL (R111.2).

   Feste Hoehe und `object-fit: contain`: Ein Play ist mal breit und mal
   hoch (eine Go-Route ueber dreissig Yards gegen einen Screen), und ein
   Raster aus Kacheln unterschiedlicher Hoehe springt beim Scrollen.
   Beschnitten wird nicht -- ein Bild, aus dem unbemerkt ein Stueck
   Route fehlt, ist schlimmer als ein kleineres.

   Der eigene Grund dahinter: Die Zeichnung ist auf Papier gedacht und
   traegt dunkle Linien; auf der Glaskachel verschwaende sie sonst. */
/* ZEICHEN UND WORT AUF EINEM KNOPF (R109.7/R111.3).

   Dieselbe Regel wie in den Editorleisten, nur fuer die Knoepfe
   ausserhalb: Zeichen UND Wort, und das Wort weicht erst am Telefon.
   Der Name bleibt dabei im `aria-label` und im `title` -- ein Zeichen
   ohne Wort im Vorleser ist fuer einen blinden Trainer ein Knopf ohne
   Zweck, und das faellt niemandem auf, der sieht. */
.knopf.mitzeichen {
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.knopf.mitzeichen .zeichen { font-size: 1.05em; line-height: 1; }

@media (max-width: 560px) {
  .knopf.mitzeichen .wort { display: none; }
  .knopf.mitzeichen .zeichen { font-size: 1.25em; }
}

.kachelbild {
  width: 100%; height: 132px; object-fit: contain;
  border-radius: var(--r1);
  background: var(--flaeche-panel);
  border: 1px solid var(--linie);
}

/* Der Lichtstreifen auf der Oberkante — das, was Glas zu Glas macht. */
.kachel::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent, oklch(1 0 0 / .38) 22%, oklch(1 0 0 / .38) 78%, transparent);
  pointer-events: none;
}

a.kachel:hover, button.kachel:hover {
  transform: translateY(-2px);
  border-color: oklch(1 0 0 / .17);
  box-shadow:
    0 1px 0 0 oklch(1 0 0 / .15) inset,
    0 26px 52px -24px oklch(0 0 0 / .9);
}
a.kachel:active, button.kachel:active { transform: translateY(0); }

/* Teamfarbe als Schimmer in der Ecke, gesetzt per --ton. */
.kachel.getoent::before {
  content: "";
  position: absolute;
  width: 15rem; height: 15rem;
  right: -6rem; top: -7rem;
  border-radius: 50%;
  background: radial-gradient(circle, var(--ton, transparent) 0%, transparent 68%);
  opacity: .5;
  pointer-events: none;
}

/* --- Umsortieren ------------------------------------------------------ */

/* Der Griff liegt in der Ecke und meldet sich erst, wenn die Kachel dran
   ist -- er soll den Play nicht ueberstrahlen. Sichtbar bleibt er, sobald
   er den Tastaturfokus hat, sonst waere er blind bedienbar. */
.griff {
  position: absolute;
  top: 0.55rem; right: 0.55rem;
  z-index: 2;
  display: grid; place-items: center;
  width: 1.9rem; height: 1.9rem;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--r2);
  background: transparent;
  color: var(--ink-still);
  font-size: 1rem; line-height: 1;
  cursor: grab;
  opacity: 0;
  touch-action: none;          /* sonst scrollt der Finger die Seite */
  transition: opacity var(--tempo) var(--kurve),
              background var(--tempo) var(--kurve);
}
.kachel:hover .griff, .griff:focus-visible { opacity: 1; }
.griff:hover, .griff:focus-visible {
  background: var(--flaeche-hoch); border-color: var(--linie-stark);
  color: var(--ink);
}
.griff:active { cursor: grabbing; }

.kachel.wandert {
  opacity: .55;
  border-color: var(--petrol);
  transform: none;
}
.kachelraster.sortiert .kachel { cursor: grabbing; }
/* Waehrend des Zugs darf kein Text markiert werden, sonst faerbt sich beim
   Ziehen die halbe Seite blau. */
.kachelraster.sortiert { user-select: none; -webkit-user-select: none; }

/* Die Frage nach den Nummern. Sie bleibt stehen, bis sie beantwortet ist --
   eine Meldung, die von selbst verschwindet, waere hier das Gegenteil von
   dem, was sie soll. */
.aktionsleiste {
  position: sticky; bottom: 1rem;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1rem;
  margin-top: 1.25rem;
  padding: 0.85rem 1.1rem;
  border: 1px solid var(--petrol);
  border-radius: var(--r3);
  background: var(--flaeche-hoch);
  backdrop-filter: blur(18px) saturate(1.25);
  -webkit-backdrop-filter: blur(18px) saturate(1.25);
  box-shadow: 0 18px 40px -20px oklch(0 0 0 / .85);
}
.aktionsleiste[hidden] { display: none; }
.aktionsleiste .leistentext {
  flex: 1 1 18rem; margin: 0; font-size: var(--t-sm); color: var(--ink-leise);
}
.aktionsleiste .leistentext strong { color: var(--ink); }
.aktionsleiste .leistenknoepfe { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.sortiermeldung {
  position: sticky; bottom: 1rem;
  margin: 1rem 0 0;
  padding: 0.7rem 1rem;
  border: 1px solid var(--linie-stark);
  border-radius: var(--r3);
  background: var(--flaeche-hoch);
  font-size: var(--t-sm); color: var(--ink-leise);
}

.kachelraster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17.5rem), 1fr));
  gap: 1rem;
}

/* --- Wappen ------------------------------------------------------------ */

.wappen {
  width: 3.25rem; height: 3.25rem;
  border-radius: var(--r2);
  display: grid; place-items: center;
  flex: 0 0 auto;
  overflow: hidden;
  background: oklch(1 0 0 / .07);
  border: 1px solid oklch(1 0 0 / .1);
  font-weight: 700; font-size: var(--t-md);
  letter-spacing: -0.02em;
  color: var(--ink);
}
.wappen img { width: 100%; height: 100%; object-fit: contain; padding: 4px; }
.wappen.gross { width: 4.75rem; height: 4.75rem; font-size: var(--t-xl);
                border-radius: var(--r3); }
.wappen.klein { width: 2.1rem; height: 2.1rem; font-size: var(--t-xs);
                border-radius: var(--r1); }

/* --- Kachelinhalt ------------------------------------------------------ */

.kachelkopf { display: flex; align-items: center; gap: 0.8rem; }
.kachelkopf .wachsen { flex: 1 1 auto; min-width: 0; }
.kacheltitel {
  font-size: var(--t-md); font-weight: 650; letter-spacing: -0.015em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kachelunter { font-size: var(--t-sm); color: var(--ink-still); }

/* NUR INNERHALB VON `.zahlen`, und das ist keine Kosmetik.
   `.zahl` stand hier ungebunden -- und dieselbe Klasse traegt die
   Kostentabelle des Angebots (`_angebot_posten.html`), dort als
   „rechtsbuendige Zahlenspalte". Die Regel machte aus jeder `<th>` und
   `<td>` ein Flex-Element in Spaltenrichtung; damit hoert die Zelle auf,
   eine Tabellenzelle zu sein, und „Menge / Einzelpreis / Summe" fielen
   treppenfoermig untereinander. Gefunden am 27.08.2026 auf der
   Angebotsseite.
   Eingegrenzt statt umbenannt: Die Vorlage erzeugt auch das PDF, das
   eingereicht wird -- an der wird nicht ohne Not gedreht. */
.zahlen { display: flex; gap: 1.25rem; margin-top: auto; padding-top: 0.35rem; }
.zahlen .zahl { display: flex; flex-direction: column; gap: 0.1rem; }
.zahlen .zahl b {
  font-size: var(--t-lg); font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.zahlen .zahl span { font-size: var(--t-xs); color: var(--ink-still); }

/* --- Kachel als Aktion (gestrichelt) ---------------------------------- */

.kachel.aktion {
  align-items: center; justify-content: center; text-align: center;
  min-height: 9.5rem;
  border-style: dashed;
  border-color: oklch(1 0 0 / .16);
  background: oklch(1 0 0 / .018);
}
.kachel.aktion::after { display: none; }
.kachel.aktion:hover { border-color: var(--petrol); background: oklch(1 0 0 / .045); }
.kachel.aktion .zeichen {
  width: 2.6rem; height: 2.6rem; border-radius: var(--rund);
  display: grid; place-items: center;
  background: var(--petrol); color: var(--auf-petrol);
  font-size: 1.35rem; font-weight: 400; line-height: 1;
}

/* --- Seitenkopf mit Wappen -------------------------------------------- */

.buehnenkopf {
  display: flex; align-items: center; gap: 1.1rem;
  padding: 1.6rem 1.35rem;
  border-radius: var(--r4);
  background: linear-gradient(160deg,
    oklch(1 0 0 / .07), oklch(1 0 0 / .015));
  border: 1px solid oklch(1 0 0 / .09);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  margin-bottom: 1.5rem;
  position: relative; overflow: hidden;
  flex-wrap: wrap;
}
.buehnenkopf .wachsen { flex: 1 1 14rem; min-width: 0; }
.buehnenkopf h1 { font-size: clamp(1.35rem, 3.4vw, 1.85rem); }
.buehnenkopf .unterzeile {
  color: var(--ink-leise); font-size: var(--t-sm); margin-top: 0.2rem;
}
.buehnenkopf .aktionen { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* --- Abschnittsüberschrift -------------------------------------------- */

.abschnitt {
  display: flex; align-items: baseline; gap: 0.7rem;
  margin: 2.1rem 0 0.85rem;
}
.abschnitt h2 { font-size: var(--t-md); font-weight: 650; }
.abschnitt .zaehler {
  font-size: var(--t-xs); color: var(--ink-still);
  font-variant-numeric: tabular-nums;
}
.abschnitt .rest { flex: 1 1 auto; height: 1px;
                   background: linear-gradient(90deg, var(--linie), transparent); }

/* --- Wegweiser (dreistufig) ------------------------------------------- */

.wegweiser {
  display: grid; gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  margin: 0.5rem 0 0;
  counter-reset: schritt;
  padding: 0;
  list-style: none;
}
.wegweiser li {
  counter-increment: schritt;
  display: flex; gap: 0.7rem; align-items: flex-start;
  padding: 0.85rem 0.95rem;
  border-radius: var(--r2);
  background: oklch(1 0 0 / .035);
  border: 1px solid oklch(1 0 0 / .07);
  margin: 0;
  font-size: var(--t-sm);
}
.wegweiser li::before {
  content: counter(schritt);
  flex: 0 0 auto;
  width: 1.55rem; height: 1.55rem; border-radius: var(--rund);
  display: grid; place-items: center;
  background: var(--petrol); color: var(--auf-petrol);
  font-size: var(--t-xs); font-weight: 700;
}
.wegweiser b { display: block; color: var(--ink); }
.wegweiser span { color: var(--ink-still); }

/* --- Formulare in Glas ------------------------------------------------- */

.formkarte {
  max-width: 34rem; margin: 0 auto;
  padding: 1.5rem 1.5rem 1.35rem;
  border-radius: var(--r4);
  background: linear-gradient(160deg, oklch(1 0 0 / .07), oklch(1 0 0 / .02));
  border: 1px solid oklch(1 0 0 / .09);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  box-shadow: 0 24px 60px -30px oklch(0 0 0 / .9);
}
.formkarte.breit { max-width: 46rem; }

/* DIE SCHULSEITE IST KEINE FORMULARSEITE, sondern eine Textseite mit
   einem Formular darin -- und darauf war `.formkarte` nicht gebaut.

   `.formkarte` hat `max-width: 34rem; margin: 0 auto`. Das ist richtig,
   wo das Formular ALLEIN steht (Anmelden, Registrieren): Dort zentriert
   es sich im leeren Raum. Auf der Schulseite steht es unter drei
   Textkaesten, die die vollen 1080 px von `.seite` fuellen -- und
   zentriert sich darin selbst. Ergebnis: Seine linke Kante sitzt rund
   270 px rechts von der Textkante, und die Seite sieht verrutscht aus.
   Genau so gemeldet am 27.08.2026.

   Der Kasten bekommt deshalb hier die Breite der Nachbarn. Die FELDER
   bleiben schmal: Ein Eingabefeld ueber 1080 px ist kein Gewinn,
   sondern erschwert das Zielen und das Lesen des Getippten. */
.schulseite .formkarte { max-width: none; margin-inline: 0; }
.schulseite .formkarte .formfelder { max-width: 34rem; }
.formkarte + .formkarte { margin-top: 1.15rem; }
.formfelder { display: flex; flex-direction: column; gap: 1.05rem; }

/* Registrierung: das Formular und daneben, was man dafuer bekommt.
   Auf dem Handy untereinander, und zwar Formular zuerst -- wer auf
   „Kostenlos ausprobieren" getippt hat, ist ueberzeugt und will
   ausfuellen, nicht noch einmal lesen. */
.anmeldespalten { display: grid; gap: 1.35rem; align-items: start; }
.anmeldespalten .formkarte { margin: 0; max-width: none; }
.formkarte.leise {
  background: oklch(1 0 0 / .035);
  box-shadow: none;
}
.formkarte.leise h2 { margin: 0 0 .85rem; font-size: 1.05rem; }
.formkarte.leise .hinweistext { margin: .9rem 0 0; }
@media (min-width: 62rem) {
  .anmeldespalten {
    grid-template-columns: minmax(0, 34rem) minmax(0, 23rem);
    justify-content: center; gap: 2rem;
  }
}

/* Der Abo-Vorschlag stellt gegenueber, statt zu behaupten: worum es
   geht, was die Demo hergibt, was ein Abo daraus macht. Drei Spalten
   bleiben auch auf dem Handy drei Spalten -- untereinander verliert die
   Gegenueberstellung genau das, wofuer sie da ist. Statt umzubrechen
   wird die Schrift kleiner. */
.abovergleich { margin: 1.35rem 0 0; }
.abovergleich > div {
  display: grid; align-items: baseline; gap: 0.5rem;
  /* VIER SPALTEN SEIT DEM 10.09.2026: Beschriftung, Demo, Standard,
     Premium. Vorher drei -- "Mit Abo" war eine Spalte fuer zwei
     Stufen, und der einzige Unterschied zwischen ihnen kam deshalb
     gar nicht vor. */
  grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  padding: 0.5rem 0; border-top: 1px solid var(--linie);
}
.abovergleich > div:first-child { border-top: 0; padding-top: 0; }
.abovergleich dt { color: var(--ink-leise); }
.abovergleich dd { margin: 0; color: var(--ink-still); }
/* Die rechte Spalte ist die Aussage. Petrol und nicht Gold: Gold ist in
   diesem System die Warnfarbe, und ein Angebot ist keine Warnung. */
.abovergleich dd.ja { color: var(--ink); font-weight: 550; }
.abokopf dd {
  font-size: var(--t-xs); text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--ink-still);
}
.aborechnung {
  margin: 0.9rem 0 0; padding: 0.55rem 0.8rem;
  border-left: 3px solid var(--petrol);
  background: oklch(1 0 0 / .04);
  border-radius: 0 var(--r1) var(--r1) 0;
}
@media (max-width: 34rem) {
  .abovergleich > div { font-size: var(--t-sm); }
}

/* Nur fuer Vorleseprogramme: Die Kategoriezeile traegt ihre Beschriftungen
   in der Kopfzeile der Liste, jedes Feld einzeln zu beschriften wuerde die
   Zeile zerreissen -- verschwinden darf die Beschriftung deshalb trotzdem
   nicht. */
.nurvorleser {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --- Drucken ---------------------------------------------------------- */

.druckfelder {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  align-items: start;
}
.eigenmass {
  margin-top: 1rem; padding-top: 0.9rem;
  border-top: 1px solid var(--linie);
}
.eigenmass > summary {
  cursor: pointer; font-size: var(--t-sm); color: var(--ink-leise);
  list-style: none;
}
.eigenmass > summary::-webkit-details-marker { display: none; }
.eigenmass > summary::before { content: "▸ "; color: var(--ink-still); }
.eigenmass[open] > summary::before { content: "▾ "; }
.eigenmass > summary:hover { color: var(--ink); }

/* --- Textliste --------------------------------------------------------- */
/*
 * Zwischen Kachelraster und PDF fehlte die schnellste Form: alles auf
 * einmal, zum Ueberfliegen und Weiterschicken.
 */
.textliste .playzeile { align-items: flex-start; gap: 0.75rem; }
.listennummer {
  min-width: 2.2rem; text-align: right; flex: 0 0 auto;
  font-family: var(--mono); font-weight: 700; color: var(--ink-leise);
  font-variant-numeric: tabular-nums;
}
.textliste .titel a { color: var(--ink); text-decoration: none; }
.textliste .titel a:hover { text-decoration: underline; }
.textliste .wege {
  display: flex; flex-wrap: wrap; gap: 0.3rem 0.5rem; margin-top: 0.25rem;
}
.textliste .weg {
  font-size: var(--t-xs); color: var(--ink-leise);
  padding: 0.05rem 0.4rem; border-radius: var(--rund);
  background: oklch(1 0 0 / .05);
}
.textliste .ohne { font-size: var(--t-xs); color: var(--ink-still); }

/* --- Spieleransicht --------------------------------------------------- */
/*
 * Gross, ruhig, ohne Werkzeuge. Ueberladene Diagramme sind laut den
 * Coach-Quellen der haeufigste Fehler in Jugend-Playbooks -- deshalb
 * tritt hier alles zurueck, was nicht die eigene Position ist, statt
 * ganz zu verschwinden: Wer nur seinen Weg sieht, verliert den Bezug
 * zur Aufstellung.
 */
.spieleransicht { max-width: 62rem; }
.spielerkopf { margin-bottom: 1rem; }
.spielerkopf h1 { display: flex; align-items: baseline; gap: 0.6rem; }
.playnummer {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 2.2rem; height: 2.2rem; padding: 0 0.4rem;
  border-radius: var(--r2); background: var(--petrol);
  color: var(--auf-petrol); font-size: var(--t-lg); font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.positionswahl {
  display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 0.9rem;
}
/* Grosse Trefferflaechen: Das hier wird mit dem Daumen bedient, im
   Stehen, am Platz. */
.posknopf {
  min-width: 3rem; min-height: 44px; padding: 0 0.9rem;
  font: inherit; font-size: var(--t-md); font-weight: 700;
  color: var(--ink-leise); background: var(--flaeche-hoch);
  border: 1px solid var(--linie-stark); border-radius: var(--rund);
  cursor: pointer;
}
.posknopf[aria-pressed="true"] {
  color: var(--auf-petrol); background: var(--petrol); border-color: var(--petrol);
}

.spielerfeld {
  background: var(--flaeche-panel); border: 1px solid var(--linie);
  border-radius: var(--r3); padding: 0.6rem; text-align: center;
}
.spielerfeld svg { width: 100%; height: auto; max-height: 72vh; }
/* Zurueckgetreten, nicht weg. */
.spielerfeld [data-spieler].zurueck { opacity: .16; }
.spielerfeld [data-spieler] {
  transition: opacity var(--tempo) var(--kurve);
}

.aufgabenliste { margin-top: 1.4rem; }
.aufgaben { list-style: none; margin: 0.6rem 0 0; padding: 0;
            display: flex; flex-direction: column; gap: 2px; }
.aufgaben li {
  display: flex; align-items: baseline; gap: 0.75rem;
  padding: 0.55rem 0.7rem; border-radius: var(--r2);
  background: oklch(1 0 0 / .03);
}
.aufgaben li.zurueck { opacity: .38; }
.aufgaben .pos {
  min-width: 2.4rem; font-weight: 700; font-size: var(--t-md);
  color: var(--ink);
}
.aufgaben .wastun { font-size: var(--t-base); }
.aufgaben .art { color: var(--ink-still); font-size: var(--t-sm); }
.aufgaben .ohne { color: var(--ink-still); }
.spielerhinweise { margin-top: 1.4rem; }
.spielerhinweise p { font-size: var(--t-md); line-height: 1.6; }

/* --- Kader und Zugaenge ------------------------------------------------ */

.zugangszeile { flex-wrap: wrap; gap: 0.5rem; }
/* Der Kader traegt vier Angaben und bis zu zwei Formulare in einer Zeile.
   Ausrichtung oben, nicht mittig: Sonst haengt der Rollenkasten neben dem
   Balken in der Luft, sobald eine Zeile hoeher wird als die anderen. */
.kaderzeile { flex-wrap: wrap; gap: 0.5rem; align-items: flex-start; }
.kaderzeile .lernzahl { align-self: center; }
/* Ohne Trennlinie und mit wenig Luft: In einer Kaderzeile waere die
   Linie von `.eigenmass` ein zweiter Zeilentrenner. */
.namenszelle { margin-top: 0.45rem; padding-top: 0; border-top: none; }
.namenszelle > form { margin-top: 0.4rem; }
.namenszelle input { max-width: 16rem; min-height: 28px; font-size: var(--t-xs); }
.zugangsform {
  display: flex; align-items: center; gap: 0.4rem; margin: 0; flex-wrap: wrap;
}
.zugangsform select { width: auto; min-height: 28px; font-size: var(--t-xs); }

/* --- Einladungen ------------------------------------------------------ */

.einladungsform {
  display: flex; align-items: flex-end; flex-wrap: wrap; gap: 0.75rem;
}
.einladungsform .feld { flex: 0 1 12rem; }
.einladungszeile { align-items: flex-start; }
.einladungszeile .linkzeile {
  display: flex; gap: 0.4rem; margin: 0.4rem 0 0.3rem; max-width: 34rem;
}
.einladungszeile .einladungslink {
  font-family: var(--mono); font-size: var(--t-xs);
}
/* Der Zustand steht als Wort neben der Rolle. Farbe ist Zugabe, nicht die
   Information -- wer sie nicht unterscheidet, liest trotzdem "widerrufen". */
.zustand {
  margin-left: 0.5rem; padding: 0.05rem 0.4rem;
  border-radius: var(--rund); border: 1px solid var(--linie-stark);
  font-size: var(--t-xs); font-weight: 600; color: var(--ink-still);
  vertical-align: 1px;
}
.zustand.offen { color: var(--gut, var(--petrol)); border-color: currentColor; }
.zustand.widerrufen, .zustand.abgelaufen { color: var(--ink-still); }

/* --- Kategorien ------------------------------------------------------- */

.kategorienliste { display: flex; flex-direction: column; gap: 0.5rem; }
.kategoriezeile {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.55rem 0.7rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--linie);
  border-radius: var(--r2);
  background: oklch(1 0 0 / .022);
}
.kategoriezeile .feld { gap: 0; }
.kategoriezeile .feld.wachsen { flex: 1 1 11rem; min-width: 0; }
.kategoriezeile .farbfeld { width: 7rem; font-family: var(--mono); }
.kategoriezeile .zeilenzahl {
  font-size: var(--t-xs); color: var(--ink-still); white-space: nowrap;
}
.kategoriezeile .zeilenknoepfe { display: flex; gap: 0.3rem; }
.punkt.gross {
  width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto;
  box-shadow: 0 0 0 1px oklch(1 0 0 / .18);
}
.knopf.gefahr:hover:not(:disabled) {
  border-color: var(--ziegel); color: var(--ziegel);
}
.knopf:disabled { opacity: .35; cursor: default; }
.formfuss {
  display: flex; gap: 0.6rem; justify-content: flex-end;
  margin-top: 1.35rem; padding-top: 1.1rem;
  border-top: 1px solid var(--linie);
  flex-wrap: wrap;
}
.hinweistext { font-size: var(--t-xs); color: var(--ink-still); margin: 0; }

/* Die Zahl der Varianten an einer Druckausgabe (R56).
   Vorbild ist der Druckbildschirm von Playmaker X („11 Styles"), und
   das Gute daran ist nicht die Schraegstellung, sondern die Auskunft:
   Man sieht vor dem Aufklappen, ob es dort ueberhaupt etwas zu waehlen
   gibt.
   Als Pille und nicht als Fliesstext -- sie ist eine Angabe und kein
   Satz, und sie soll die Erklaerung darunter nicht verdraengen. */
/* Das Vorschaubild an einer Druckausgabe (R55).
   Es zeigt, was herauskommt, BEVOR man es erzeugt -- vorher war die
   Druckseite eine Liste aus Namen und Erklaerungen, und wer
   „Wristcoach-Einlage" noch nie gesehen hat, wusste nach dem Lesen so
   viel wie vorher.
   Hoehe begrenzt und nicht Breite: Die Blaetter sind teils hoch, teils
   quer, und eine feste Breite machte aus dem Call Sheet einen
   Briefmarkenstreifen. */
.druckvorschau {
  display: block;
  max-height: 220px;
  width: auto;
  max-width: 100%;
  margin: 0 0 1.1rem;
  border-radius: var(--r1);
  background: #FFFFFF;
}

.variantenzahl {
  display: inline-block;
  margin: 0 0 0.7rem;
  padding: 0.12rem 0.55rem;
  font-size: var(--t-xs);
  color: var(--ink-still);
  border: 1px solid var(--linie);
  border-radius: var(--rund);
}

/* Was die Demo hergibt. Ruhig und nicht rot: Eine Grenze ist kein Fehler
   des Benutzers, sondern eine Auskunft. Der linke Balken hebt sie aus dem
   uebrigen Kleingedruckten heraus, ohne die Seite zu alarmieren. */
.demohinweis {
  margin: 0.9rem 0;
  padding: 0.5rem 0.75rem;
  border-left: 3px solid var(--warnung);
  background: oklch(1 0 0 / .04);
  border-radius: 0 var(--r1) var(--r1) 0;
}
/* Die Warnung am Teamcode. Deutlicher als `.demohinweis`, weil hier
   nicht eine Grenze erklaert wird, sondern eine Entscheidung ansteht,
   die sich schlecht zuruecknehmen laesst: Ein weitergereichter Code ist
   weg. Trotzdem nicht rot -- rot ist in dieser Oberflaeche der
   Fehlschlag, und einen Code zu erzeugen ist keiner. */
.warntext {
  margin: 0 0 1rem;
  padding: 0.6rem 0.8rem;
  border-left: 3px solid var(--warnung);
  background: oklch(1 0 0 / .05);
  border-radius: 0 var(--r1) var(--r1) 0;
  font-size: var(--t-xs); color: var(--ink-leise);
}
.warntext strong { color: var(--ink); }

/* Der Code selbst wird abgetippt und vorgelesen. Deshalb Schreibmaschine
   (jede Stelle gleich breit) und gross genug, um ihn quer durch die
   Halle von einem Bildschirm abzulesen. */
.teamcodewert {
  font-family: var(--mono); font-size: var(--t-md);
  letter-spacing: 0.08em;
}
.codefeld {
  font-family: var(--mono); font-size: 1.15rem;
  letter-spacing: 0.14em; text-transform: uppercase;
}
.feldfehler {
  font-size: var(--t-xs); color: var(--fehler);
  background: var(--fehler-hell); border-radius: var(--r1);
  padding: 0.25rem 0.5rem; margin: 0;
}

input:not([type="file"], [type="checkbox"], [type="radio"], [type="range"],
           [type="color"], [type="submit"], [type="button"], [type="reset"],
           [type="image"], [type="hidden"]),
select, textarea {
  border-radius: var(--r2);
  background: oklch(1 0 0 / .045);
  border-color: oklch(1 0 0 / .12);
}

/* DAS AUFKLAPPMENUE MALT DER BROWSER SELBST, und es erbt nicht.
   Gefunden am 27.08.2026 auf der Angebotsseite: Beim Aufklappen von
   „Foerderprogramm" stand weisse Schrift auf weissem Grund, unlesbar.

   Ursache ist die Zeile darueber. `color-scheme: dark` steht zwar
   (Zeile 94) und wuerde native Bedienelemente dunkel zeichnen -- aber
   der `select` bekommt hier ausdruecklich `oklch(1 0 0 / .045)`, also
   fast durchsichtiges WEISS. Chromium leitet die Farbe der Optionsliste
   aus dem gesetzten Hintergrund des `select` ab und landet bei Weiss,
   waehrend die Schrift hell bleibt.

   Deshalb wird `option` ausdruecklich gesetzt, und zwar DECKEND: Eine
   halbdurchsichtige Flaeche hilft nicht, weil die Liste ausserhalb des
   Dokuments gezeichnet wird und dort nichts hinterlegt ist. */
select option {
  background-color: var(--flaeche-hoch);
  color: var(--ink);
}
input[type="file"] {
  font: inherit; font-size: var(--t-sm); color: var(--ink-leise);
  width: 100%;
}
input[type="file"]::file-selector-button {
  font: inherit; font-size: var(--t-sm); font-weight: 600;
  color: var(--ink); background: oklch(1 0 0 / .08);
  border: 1px solid oklch(1 0 0 / .14);
  border-radius: var(--rund);
  padding: 0.35rem 0.8rem; margin-right: 0.7rem;
  cursor: pointer;
}
input[type="file"]::file-selector-button:hover { background: oklch(1 0 0 / .13); }

/* --- Farbwahl im Formular --------------------------------------------- */

.farbzeile { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.farbzeile input.farbfeld { width: 7.5rem; font-family: var(--mono); }
.farbtupfer {
  width: 1.75rem; height: 1.75rem; border-radius: var(--rund);
  border: 1px solid oklch(1 0 0 / .2); padding: 0; cursor: pointer;
  transition: transform var(--tempo) var(--kurve);
}
.farbtupfer:hover { transform: scale(1.12); }

/* --- Spielformwahl beim Anlegen einer Mannschaft (T4) ------------------ */
/*
   Karten und kein Auswahlkasten: Der Unterschied zwischen „9 gegen 9"
   und „9 gegen 9, schmales Feld" steht im Hinweis. In einem
   zugeklappten Kasten liest ihn niemand.

   Zwei Spalten ab 34rem, darunter eine. Die Kachel ist ein `button`,
   damit Tastatur und Vorlesehilfe sie ohne Zutun bedienen -- `aria-
   pressed` sagt, welche gewaehlt ist.
*/
.formwahl { display: grid; gap: 0.5rem; }
@media (min-width: 34rem) {
  .formwahl { grid-template-columns: 1fr 1fr; }
  .formwahlgruppe { grid-column: 1 / -1; }
}
.formwahlgruppe {
  margin: 0.55rem 0 0; font-size: var(--t-sm); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-still);
}
.formwahlgruppe:first-child { margin-top: 0; }
.formkachel {
  display: flex; flex-direction: column; gap: 0.2rem; text-align: left;
  font: inherit; color: var(--ink); cursor: pointer;
  padding: 0.65rem 0.8rem; border-radius: var(--r2);
  background: oklch(1 0 0 / .03); border: 1px solid oklch(1 0 0 / .12);
  transition: border-color var(--tempo) var(--kurve),
              background var(--tempo) var(--kurve);
}
.formkachel:hover { background: oklch(1 0 0 / .06); }
.formkachel.gewaehlt {
  border-color: var(--akzent); background: var(--petrol-hell);
  box-shadow: inset 0 0 0 1px var(--akzent);
}
.formname { font-weight: 650; }
.formhinweis { font-size: var(--t-sm); color: var(--ink-still); line-height: 1.4; }

/* --- Logo-Vorschau ----------------------------------------------------- */

.logovorschau {
  display: flex; align-items: center; gap: 0.85rem;
  padding: 0.7rem; border-radius: var(--r2);
  background: oklch(1 0 0 / .03); border: 1px dashed oklch(1 0 0 / .12);
}

/* --- Meldungen --------------------------------------------------------- */

.meldungen { display: flex; flex-direction: column; gap: 0.5rem;
             margin-bottom: 1.1rem; }
.meldung {
  border-radius: var(--r2);
  background: oklch(1 0 0 / .05);
  border-color: oklch(1 0 0 / .1);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.meldung.erfolg { color: var(--gut); border-color: var(--gut); }

/* Betriebshinweis: steht ueber allem, gehoert aber nicht zum Inhalt.
   Deshalb ruhig statt rot -- eine Wartung ist kein Fehler des Benutzers. */
.betriebshinweis {
  margin: 0 auto 1.1rem;
  max-width: var(--breite, 72rem);
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--warnung);
  border-radius: var(--r2);
  background: oklch(1 0 0 / .05);
  color: var(--warnung);
  font-size: 0.92rem;
}

/* --- Listen runder ----------------------------------------------------- */

.liste {
  border-radius: var(--r3);
  background: oklch(1 0 0 / .035);
  border-color: oklch(1 0 0 / .08);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.liste > * + * { border-top-color: oklch(1 0 0 / .06); }
a.zeile:hover { background: oklch(1 0 0 / .05); }

.leerzustand {
  border-radius: var(--r4);
  border-color: oklch(1 0 0 / .13);
  background: oklch(1 0 0 / .025);
}

/* Wer weniger Bewegung will, bekommt keine Schwebeeffekte. */
@media (prefers-reduced-motion: reduce) {
  a.kachel:hover, button.kachel:hover { transform: none; }
}

/* Geraete ohne Weichzeichner bekommen eine kraeftigere Flaeche, damit die
   Kachel nicht durchsichtig und damit unlesbar wirkt. */
@supports not (backdrop-filter: blur(1px)) {
  .kachel, .buehnenkopf, .formkarte, .liste {
    background: var(--flaeche-panel);
  }
}

/* --- Der Passwort-Staerkebalken (R108, 10.09.2026) --------------------

   Niklas mit einem Bild des Registrierformulars und einem Kreis um die
   beiden Passwortfelder: „Passwort Indikator".

   VIER STRICHE UND KEIN VERLAUF. Ein Balken, der von Rot nach Gruen
   laeuft, ist bei einer Rot-Gruen-Schwaeche keine Auskunft; vier
   gefuellte Striche zaehlt man auch ohne Farbe. Das ist im ganzen Haus
   dieselbe Regel -- Farbe ist nie die einzige Information --, und sie
   gilt hier genauso wie bei den Linienarten im Diagramm.

   DAS WORT DANEBEN IST DIE EIGENTLICHE AUSKUNFT. „Noch 3 Zeichen" sagt,
   was zu tun ist; ein Balken sagt nur, dass etwas fehlt. Deshalb steht
   der Text rechts und nicht darunter: Er wird gelesen, der Balken nur
   gesehen.

   `aria-live="polite"` am Kasten: Ein Vorleseprogramm sagt die Aenderung
   an, ohne den Tippfluss zu unterbrechen. */
.pwstaerke {
  display: flex; align-items: center; gap: .55rem;
  margin: .4rem 0 0; min-height: 1.05rem;
}
.pwbalken { display: flex; gap: .22rem; flex: 0 0 auto; }
.pwbalken span {
  width: 1.55rem; height: .28rem; border-radius: 999px;
  background: var(--linie); transition: background var(--tempo) var(--kurve);
}
.pwwort { font-size: var(--t-xs); color: var(--ink-still); }

.pwstaerke.schwach .pwbalken span.voll { background: var(--fehler); }
.pwstaerke.schwach .pwwort { color: var(--fehler); }
.pwstaerke.mittel .pwbalken span.voll { background: var(--warnung); }
.pwstaerke.mittel .pwwort { color: var(--warnung); }
.pwstaerke.gut .pwbalken span.voll,
.pwstaerke.stark .pwbalken span.voll { background: var(--gut); }
.pwstaerke.gut .pwwort,
.pwstaerke.stark .pwwort { color: var(--gut); }

/* Schmale Seite fuer Formulare. */
.seite.schmal { max-width: 44rem; }

/* Der Pfad in der Kopfleiste ist der Weg zurueck.

   AUF DEM TELEFON FAELLT ER GANZ WEG (10.09.2026). Vorher blieb die
   letzte Stufe stehen, und genau die hat Niklas mit einem Bild
   gemeldet: „Ganz viele Seiten sind in der Handy Version oben im Header
   abgeschnitten." Auf dem Bild steht „Neues Playb…" -- abgeschnitten,
   ohne Nutzen, und daneben laeuft „Abmelde…" aus dem Bild.

   Die letzte Stufe SAGT NICHTS NEUES: Sie ist der Name der Seite, und
   der steht zwei Zentimeter darunter als Ueberschrift („Playbook
   anlegen"). Auf 390 Pixeln kostet sie ein Drittel der Kopfleiste, um
   etwas zu wiederholen -- und drueckt dafuer das Konto und den Ausgang
   aus dem Bild.

   Der Weg zurueck geht auf einem Telefon ohnehin ueber die
   Zurueck-Geste, nicht ueber eine Textzeile im Kopf. */
@media (max-width: 40rem) {
  .kopf-pfad { display: none; }
  .buehnenkopf { padding: 1.15rem 1rem; border-radius: var(--r3); }
  .buehnenkopf .aktionen { width: 100%; }
  .buehnenkopf .aktionen .knopf { flex: 1 1 auto; }
}

/* Titel und Unterzeile sind spans (damit sie in einem <a> stehen duerfen)
   und brauchen deshalb ausdrueckliche Blockdarstellung. */
.kachelkopf .wachsen { display: block; }
.kacheltitel, .kachelunter { display: block; }
.zahlen .zahl span { display: block; }

/* --- Dateiwahl mit eigener Beschriftung -------------------------------- */
/* Der native Knopf heisst je nach Browsersprache „Choose File" — in einer
   deutschen Oberflaeche stoert das. Das Feld bleibt bedienbar und fuer
   Screenreader sichtbar, nur optisch ersetzt. */
.dateiwahl { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.dateiwahl input[type="file"] {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.dateiwahl .auswahlknopf {
  display: inline-flex; align-items: center; min-height: 32px;
  padding: 0 0.85rem; border-radius: var(--rund);
  font-size: var(--t-sm); font-weight: 600; color: var(--ink);
  background: oklch(1 0 0 / .08); border: 1px solid oklch(1 0 0 / .14);
  cursor: pointer;
  transition: background var(--tempo) var(--kurve);
}
.dateiwahl .auswahlknopf:hover { background: oklch(1 0 0 / .14); }
.dateiwahl input[type="file"]:focus-visible + .auswahlknopf {
  outline: 2px solid var(--petrol); outline-offset: 2px;
}
.dateiname { font-size: var(--t-xs); color: var(--ink-still); }

/* --- Reiter für Offense / Defense ------------------------------------- */
.seitenreiter {
  display: inline-flex; gap: 3px; padding: 3px;
  border-radius: var(--rund);
  background: oklch(1 0 0 / .045); border: 1px solid oklch(1 0 0 / .08);
  margin-bottom: 1rem;
}
.seitenreiter a {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.3rem 0.8rem; border-radius: var(--rund);
  font-size: var(--t-sm); font-weight: 600; text-decoration: none;
  color: var(--ink-leise);
  transition: background var(--tempo) var(--kurve), color var(--tempo) var(--kurve);
}
.seitenreiter a:hover { color: var(--ink); background: oklch(1 0 0 / .06); }
.seitenreiter a[aria-current="true"] {
  color: var(--auf-petrol); background: var(--petrol);
}
.seitenreiter .anzahl { font-variant-numeric: tabular-nums; opacity: .75;
                        font-weight: 500; }

/* --- Platzmodus ------------------------------------------------------- */
/*
 * Sonne auf dem Display, Handy in der Hand, Spiel laeuft.
 *
 * Das dunkle Erscheinungsbild der App bleibt, wie festgelegt -- der
 * Platzmodus greift AUSSCHLIESSLICH die beiden Ansichten an, die auf dem
 * Platz gelesen werden: die Spieleransicht eines Plays und die Textliste
 * eines Playbooks. Alles andere, auch die Kopfleiste ringsum, bleibt
 * dunkel. Das ist kein Kompromiss, sondern hilft: Der helle Kasten hebt
 * sich vom dunklen Rand ab, das Auge findet ihn sofort.
 *
 * Zwei Dinge macht der Modus, und nur diese zwei:
 *
 *   Kontrast   Weisser Grund, schwarze Linien, dunklere Hilfslinien.
 *              Die Wege werden nachgedunkelt statt umgefaerbt, damit die
 *              Farbe weiter sagt, wer laeuft -- ein Gold, das drinnen gut
 *              aussieht, verschwindet draussen auf Weiss.
 *   Groesse    Symbole, Kuerzel und Wege wachsen. Das Feld bleibt gleich
 *              gross -- gezoomt wird nicht, sonst sieht man den Play nicht
 *              mehr im Ganzen.
 */

html.platz .spieleransicht,
html.platz .leseansicht {
  background: #F3F3EF;
  color: #10161C;
  border-radius: var(--r3);
  padding: 1rem 1.1rem 1.4rem;
  /* Der helle Kasten braucht Luft zum dunklen Rand, sonst sieht es aus
     wie ein Darstellungsfehler. */
  margin-top: 0.4rem;
}

html.platz .spieleransicht h1,
html.platz .spieleransicht h2,
html.platz .leseansicht h1,
html.platz .leseansicht h2 { color: #10161C; }

html.platz .spieleransicht .unterzeile,
html.platz .spieleransicht .hinweistext,
html.platz .leseansicht .unterzeile {
  color: #3C4650;
  font-size: var(--t-md);
}

/* Knoepfe: schwarz auf weiss statt leiser Grautoene. */
html.platz .posknopf {
  min-height: 50px; font-size: var(--t-lg);
  color: #10161C; background: #FFFFFF;
  border: 2px solid #10161C;
}
html.platz .posknopf[aria-pressed="true"] {
  color: #FFFFFF; background: #10161C; border-color: #10161C;
}

html.platz .spielerfeld {
  background: #FFFFFF; border: 2px solid #10161C; padding: 0.4rem;
}
html.platz .spielerfeld svg { max-height: 78vh; }
/* Zurueckgetreten, aber bei Sonne noch zu sehen -- 0.16 waere draussen
   dasselbe wie geloescht. */
html.platz .spielerfeld [data-spieler].zurueck { opacity: .34; }

/* --- Das Feld selbst.
   Die Regeln stechen die eingebettete Stilvorlage aus designer/render.py
   aus: gleiche Klassen, aber eine Stelle mehr im Selektor. */

html.platz .spielerfeld .grund { fill: #FFFFFF; }
/* Gezeichnet werden nur Fuenf-Yard-, Tor- und Mittellinie (siehe
   ``build_field`` in designer/render.py) -- Ein-Yard-Linien gibt es gar
   nicht. Die vorhandenen werden dunkler, nicht mehr. */
html.platz .spielerfeld .linie.fuenf { stroke: #9AA3AA; stroke-width: 1.4; }
html.platz .spielerfeld .linie.torlinie { stroke: #000000; stroke-width: 3; }
html.platz .spielerfeld .linie.mittellinie { stroke: #7A4C08; stroke-width: 2.6; }
html.platz .spielerfeld .seitenlinien { stroke: #000000; stroke-width: 3.2; }
html.platz .spielerfeld .los { stroke: #000000; stroke-width: 3.4; }
html.platz .spielerfeld .rushlinie { stroke: #0C3B49; stroke-width: 2.4; }
html.platz .spielerfeld .norunzone { fill-opacity: .105; }
html.platz .spielerfeld .beschriftung,
html.platz .spielerfeld .zonenname { fill: #333D46; font-size: 8px; }

/* Symbole wachsen um ein Drittel. Ueber die Groesse und nicht ueber den
   Radius: ``transform-box: fill-box`` skaliert um die eigene Mitte und
   nimmt die Strichstaerke mit, waehrend ``r`` als CSS-Eigenschaft nicht
   ueberall zu haben ist. Fuer das Defense-Kreuz an den Linien statt an
   der Gruppe -- beide Diagonalen haben dieselbe Mitte wie das Kreuz. */
html.platz .spielerfeld .spieler.offense,
html.platz .spielerfeld .spieler.defense line {
  transform-box: fill-box; transform-origin: center; transform: scale(1.34);
}
html.platz .spielerfeld .spieler.offense { stroke: #000000; stroke-width: 2.6; }
html.platz .spielerfeld .spieler.defense line { stroke: #7A2417; }
html.platz .spielerfeld .spielerlabel { fill: #000000; font-size: 12px; }
html.platz .spielerfeld .spielername { fill: #7A2417; font-size: 9px; }

/* Die Wege behalten ihre Farbe -- sie sagt, wer laeuft --, werden aber
   nachgedunkelt. Ein Gold, das drinnen gut aussieht, verschwindet
   draussen auf Weiss. */
html.platz .spielerfeld .laufweg,
html.platz .spielerfeld .zonenflaeche { filter: brightness(.66) saturate(1.35); }
html.platz .spielerfeld .laufweg { stroke-width: 4.4; }
html.platz .spielerfeld .laufweg-motion { stroke-width: 3.2; }
html.platz .spielerfeld .laufweg-block { stroke-width: 4.8; }
html.platz .spielerfeld .laufweg-zone { stroke-width: 3.2; }
/* Der Passweg ist fein gepunktet (2 8). Auf 4.4 haette er statt
   Punkten fette Klekse. */
html.platz .spielerfeld .laufweg-pass { stroke-width: 3.2; }

/* Der Saum unter den Wegen (siehe SAUM_BREITE in designer/render.py)
   waechst mit ihnen mit -- immer 2.2 breiter als der Weg darauf. Bliebe
   er auf seinem Mass, verschwaende er unter dem breiteren Weg, und
   ausgerechnet draussen auf dem Platz laege eine Route wieder
   ununterscheidbar auf der Seitenlinie.

   Und er wird WEISS: Der Rasen ist hier weiss und nicht #FBFBF9. */
html.platz .spielerfeld .laufweggrund { stroke: #FFFFFF; stroke-width: 6.6; }
html.platz .spielerfeld .laufweggrund-block { stroke-width: 7; }
html.platz .spielerfeld .laufweggrund-motion,
html.platz .spielerfeld .laufweggrund-zone,
html.platz .spielerfeld .laufweggrund-pass { stroke-width: 5.4; }

/* Wegnamen (Go, Out, Slant) liegen oft ueber einer Linie. Ein weisser
   Saum darunter haelt sie lesbar, ohne etwas zu verdecken. */
html.platz .spielerfeld .linienname {
  font-size: 9.5px; font-weight: 800;
  paint-order: stroke; stroke: #FFFFFF; stroke-width: 2.6;
  stroke-linejoin: round;
}

/* --- Die Aufgabenliste darunter. */
html.platz .aufgaben li {
  background: #FFFFFF; border: 1px solid #C4CBD1;
  padding: 0.7rem 0.8rem;
}
html.platz .aufgaben li.zurueck { opacity: .5; }
html.platz .aufgaben .pos { color: #10161C; font-size: var(--t-lg); }
html.platz .aufgaben .wastun { font-size: var(--t-md); color: #10161C; }
html.platz .aufgaben .art,
html.platz .aufgaben .ohne { color: #3C4650; }
html.platz .spielerhinweise p { color: #10161C; }
html.platz .playnummer { background: #10161C; color: #FFFFFF; }

/* --- Die Textliste. */
html.platz .leseansicht .zeile {
  background: #FFFFFF; border: 1px solid #C4CBD1;
}
html.platz .leseansicht .titel a { color: #10161C; font-size: var(--t-lg);
                                   font-weight: 700; }
html.platz .leseansicht .unter { color: #3C4650; font-size: var(--t-md); }
html.platz .leseansicht .listennummer { color: #10161C; font-size: var(--t-lg); }
html.platz .leseansicht .textliste .weg {
  color: #10161C; background: #E4E7E4; font-size: var(--t-sm);
}
html.platz .leseansicht .textliste .ohne { color: #3C4650; }

/* Die Reiter standen hell auf hell und waren damit weg. Aufgefallen ist
   das erst auf dem Bildschirmfoto -- die Regeln daneben griffen, diese
   eine nicht. */
html.platz .leseansicht .seitenreiter {
  background: #FFFFFF; border-color: #C4CBD1;
}
html.platz .leseansicht .seitenreiter a {
  color: #3C4650; font-size: var(--t-md);
  min-height: 40px; padding: 0 0.9rem;
}
html.platz .leseansicht .seitenreiter a[aria-current="true"] {
  color: #FFFFFF; background: #10161C;
}
html.platz .leseansicht .seitenreiter .anzahl { opacity: 1; }

/* Der Umschalter selbst. Sichtbar gedrueckt, damit niemand raet. */
.platzknopf[aria-pressed="true"] {
  background: var(--gold); color: var(--auf-petrol); border-color: var(--gold);
}

/* --- Lernmodus --------------------------------------------------------- */
/*
 * Ein Playbook nuetzt nichts, das nur der Trainer kennt. Geuebt wird
 * genau das, was auf dem Feld passiert: Diagramm sehen, Namen nennen.
 *
 * Bewusst ohne Zeitdruck, ohne Punkte, ohne Rangliste. Das hier sollen
 * Vierzehnjaehrige freiwillig aufmachen -- und eine Rangliste hat den
 * Nebeneffekt, dass die hinteren aufhoeren.
 */
.lernseite { max-width: 46rem; }
.lernkopf {
  display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 0.9rem;
}
.lernkopf h1 { margin: 0; }

.fortschrittsbalken {
  height: 10px; border-radius: 999px; overflow: hidden;
  background: oklch(1 0 0 / .07); border: 1px solid var(--linie);
}
.fortschrittsbalken.klein { height: 6px; margin-top: 0.4rem; max-width: 22rem; }
.fortschrittsbalken .gefuellt {
  height: 100%; background: var(--petrol);
  transition: width var(--tempo) var(--kurve);
}
.fortschrittstext {
  margin: 0.45rem 0 1.1rem; font-size: var(--t-sm); color: var(--ink-leise);
}
.fortschrittstext strong { color: var(--ink); }

.quizfeld {
  background: var(--flaeche-panel); border: 1px solid var(--linie);
  border-radius: var(--r3); padding: 0.6rem; text-align: center;
}
.quizfeld svg { width: 100%; height: auto; max-height: 58vh; }

/* Die Antworten sind das, was mit dem Daumen getroffen werden muss --
   eine Spalte, grosse Flaechen, keine engen Reihen. */
.quizantworten {
  display: grid; gap: 0.5rem; margin: 1rem 0 0.8rem;
  grid-template-columns: 1fr;
}
@media (min-width: 34rem) {
  .quizantworten { grid-template-columns: 1fr 1fr; }
}
.antwortknopf {
  min-height: 52px; justify-content: center; font-size: var(--t-md);
  font-weight: 600; text-align: center;
}
.lernfuss { margin-top: 0.4rem; }

/* Üben ohne Empfang (R111.6).
 *
 * Die Leiste steht ÜBER dem Feld und nicht unter den Antwortknöpfen:
 * Wer sie braucht, sucht sie vor dem Losfahren, nicht nach der ersten
 * Frage. Ohne JavaScript bleibt sie versteckt (`hidden` in der
 * Vorlage). */
.paketleiste {
  display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap;
  margin: 0 0 0.8rem; padding: 0.55rem 0.7rem;
  background: var(--flaeche-panel); border: 1px solid var(--linie);
  border-radius: var(--r3);
}
.paketstand {
  margin: 0; flex: 1 1 12rem; font-size: var(--t-sm);
  color: var(--ink-leise);
}
.paketknoepfe { display: flex; gap: 0.4rem; flex-wrap: wrap; }

/* Die Währungswahl auf der Preisseite (R133). Sie steht über den
   Kacheln und bleibt unauffällig: Wer in Euro zahlt, soll sie
   übersehen dürfen. */
.waehrungswahl {
  display: flex; gap: 0.5rem; justify-content: center;
  margin: 0 0 1rem; font-size: var(--t-sm);
}
.waehrungswahl a, .waehrungswahl .jetzt {
  padding: 0.25rem 0.6rem; border-radius: 999px;
  border: 1px solid var(--linie); color: var(--ink-leise);
  text-decoration: none;
}
.waehrungswahl .jetzt { color: var(--ink); border-color: var(--linie-stark); }

/* Die Frage am Platz steht an derselben Stelle wie die am Netz und
   sieht genauso aus (`.quizfeld`, `.quizantworten` darin) -- wer ohne
   Empfang übt, soll nicht merken, dass er in einem anderen Modus ist.
   Der Kasten selbst trägt deshalb nur den Abstand. */
.offlineueben { margin: 0 0 0.4rem; }

/* Der Satz nach der Antwort. Was er sagt, steht im Satz selbst
   (`lernen.rueckmeldung`, vom Server) -- die Farbe verstärkt ihn nur
   und trägt die Aussage nicht allein (WCAG 1.4.1). */
.paketsatz {
  margin: 0.2rem 0 0.8rem; font-size: var(--t-sm); min-height: 1.4em;
}
.paketsatz.richtig { color: var(--gut); }
.paketsatz.falsch { color: var(--fehler); }

.lernzeile { align-items: center; gap: 0.9rem; }
.lernzahl {
  font-family: var(--mono); font-weight: 700; font-size: var(--t-md);
  color: var(--ink); font-variant-numeric: tabular-nums; flex: 0 0 auto;
}
.lernzahl .von { color: var(--ink-still); font-weight: 500; }

/* --- Bibliothek -------------------------------------------------------- */
/*
 * Ein leeres Playbook ist eine unangenehme Startseite. Hier stehen die
 * Konzepte, die im 5 gegen 5 ueberall gespielt werden -- mit Zeichnung,
 * denn eine Liste aus Namen waere wertlos: „Snag" sagt niemandem etwas,
 * der es nicht schon kennt, und genau die sollen es kennenlernen.
 */
.bibliothek {
  display: grid; gap: 0.9rem; margin: 1rem 0 1.2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 52rem) {
  .bibliothek { grid-template-columns: 1fr 1fr; }
}
.bibkarte {
  display: block; cursor: pointer;
  background: var(--flaeche-panel); border: 1px solid var(--linie);
  border-radius: var(--r3); padding: 0.8rem 0.9rem 0.9rem;
  transition: border-color var(--tempo) var(--kurve);
}
.bibkarte:hover { border-color: var(--linie-stark); }
.bibkarte:has(input:checked) { border-color: var(--petrol); }
.bibkarte.schon-da { opacity: .72; }
.bibkopf { display: flex; align-items: flex-start; gap: 0.6rem; }
.bibkopf input { margin-top: 0.25rem; flex: 0 0 auto; }
.bibtitel { display: block; font-weight: 700; font-size: var(--t-md); }
.bibunter {
  display: block; font-size: var(--t-xs); color: var(--ink-still);
  margin-top: 0.1rem;
}
.bibfeld {
  margin: 0.7rem 0 0.6rem; border-radius: var(--r2); overflow: hidden;
  background: var(--flaeche-tief);
}
.bibfeld svg { width: 100%; height: auto; display: block; }
.bibhinweis {
  margin: 0; font-size: var(--t-sm); color: var(--ink-leise); line-height: 1.5;
}

/* Die Leiste am Fuss ist hier immer da, nicht nur nach einer Aenderung. */
.aktionsleiste.sichtbar { position: sticky; bottom: 0.6rem; }

.leerknoepfe {
  display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center;
  margin-bottom: 0.6rem;
}

/* --- Schlüssel für andere Programme ------------------------------------ */
/*
 * Der Klartext wird genau einmal gezeigt. Der Kasten muss deshalb
 * auffallen -- wer ihn ueberliest, legt gleich den naechsten Schluessel an.
 */
.einmalkasten {
  margin-top: 1rem; padding: 0.9rem 1rem;
  border: 1px solid var(--gold); border-radius: var(--r2);
  background: var(--gold-hell);
}
.einmaltitel {
  margin: 0 0 0.6rem; font-size: var(--t-sm); font-weight: 700; color: var(--ink);
}
.kennung { font-family: var(--mono); font-size: var(--t-xs); }
.beispiel {
  margin: 0.5rem 0; padding: 0.7rem 0.8rem; overflow-x: auto;
  background: var(--flaeche-tief); border: 1px solid var(--linie);
  border-radius: var(--r2);
  font-family: var(--mono); font-size: var(--t-xs); color: var(--ink-leise);
  line-height: 1.5;
}


/* --- Die oeffentliche Startseite -----------------------------------------
 *
 * Sie stand bis heute als 40-Zeilen-Block in `start.html` und benutzte
 * fast nichts vom Gestaltungssystem -- sie sah neben der Anwendung fremd
 * aus. Hier gehoert sie hin, neben alles andere.
 *
 * DUNKEL BLEIBT DUNKEL. Eine helle Verkaufsseite vor einer dunklen
 * Anwendung braeche das Versprechen und liesse jedes Bildschirmfoto wie
 * einen Fremdkoerper aussehen. Der einzige helle Bereich sind die
 * Druckseiten, und dort ist der Kontrast Absicht.
 */

.start { max-width: 68rem; margin: 0 auto; padding: 0 1.25rem 5rem; }
.start > section { margin-top: 5.5rem; }
.start > .buehne + .beweis { margin-top: 3.5rem; }
.start h2 { font-family: var(--schrift-marke); font-weight: 700;
            font-size: clamp(1.7rem, 3.4vw, 2.3rem); line-height: 1.05;
            letter-spacing: -.004em; margin: 0 0 .9rem; text-wrap: balance; }
.start .vorspann { color: var(--ink-leise); font-size: var(--t-md);
                   max-width: 44rem; }

/* --- Die Buehne der Startseite ---------------------------------------
 *
 * Randlos ueber die ganze Breite, obwohl sie in `.start` steht: Der
 * Griff dafuer ist `margin-inline: calc(50% - 50vw)`. Ohne ihn saesse
 * das Spielfeld in einer 68rem breiten Spalte und saehe aus wie ein
 * Kasten, nicht wie ein Platz.
 *
 * Die Leinwand liegt darunter, der Schleier darueber, der Text ganz
 * oben. Der Schleier ist keine Deko: Ohne ihn steht heller Text auf
 * wechselnden Linien, und die Lesbarkeit haengt davon ab, welcher Zug
 * gerade gezeichnet wird.
 */
/* AN DIE STARTSEITE GEBUNDEN, und das ist kein Schoenheitsfehler.
 *
 * Ungebunden traf diese Regel auch `.buehne` im EDITOR -- dort heisst so
 * die Zeichenflaeche zwischen den beiden Spalten. Das
 * `margin-inline: calc(50% - 50vw)` zog sie ueber die volle Fensterbreite
 * und damit UEBER die Playliste links und die Eigenschaften rechts: In
 * der Messung lag sie bei 1680 Pixeln Fensterbreite von -32 bis 1648,
 * die Spalten waren verdeckt und nur ihre letzten 32 Pixel blieben
 * sichtbar. Dazu schob das Polster die Werkzeugleiste nach unten.
 *
 * Aufgefallen ist es an den Verkaufsbildern (25.08.2026): Auf jedem war
 * die Playliste leer und am rechten Rand standen Wortreste. Der Fehler
 * war nicht im Bild, sondern in der Seite. */
.start .buehne {
  position: relative; isolation: isolate;
  margin-top: 0; margin-inline: calc(50% - 50vw);
  padding: clamp(4rem, 11vh, 7rem) max(1.25rem, calc(50vw - 33rem))
           clamp(3.5rem, 9vh, 5.5rem);
  min-height: min(84vh, 46rem);
  display: flex; flex-direction: column; justify-content: center;
  overflow: hidden;
  background: var(--flaeche-tief);
}
.buehnenfeld { position: absolute; inset: 0; width: 100%; height: 100%;
               display: block; z-index: -2; }
.buehnenschleier {
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg,
      oklch(0.148 0.012 240 / .96) 0%, oklch(0.148 0.012 240 / .86) 30%,
      oklch(0.148 0.012 240 / .22) 58%, oklch(0.148 0.012 240 / 0) 88%);
}
.start .buehne .augenbraue {
  font-family: var(--mono); font-size: var(--t-xs);
  letter-spacing: .15em; text-transform: uppercase;
  color: var(--petrol); margin: 0 0 1.1rem;
}
.start .buehne h1 {
  font-family: var(--schrift-marke); font-weight: 700;
  font-size: clamp(2.4rem, 5.6vw, 4.2rem); line-height: 1.0;
  letter-spacing: -.006em; margin: 0 0 1.1rem; max-width: 20ch;
  text-wrap: pretty;
}
.start .buehne h1 em { font-style: normal; color: var(--petrol); }
.start .buehne .vorspann { max-width: 42ch; }
.buehnenmasse, .buehnenzug {
  position: absolute; bottom: 1.5rem; z-index: 1; margin: 0;
  font-family: var(--mono); font-size: var(--t-xs);
  color: var(--ink-still); letter-spacing: .04em;
}
.buehnenmasse { left: max(1.25rem, calc(50vw - 33rem)); }
.buehnenzug { right: max(1.25rem, calc(50vw - 33rem)); text-transform: uppercase; }
.buehnenzug b { color: var(--petrol); font-weight: 400; }

@media (max-width: 60rem) {
  /* Hochkant kommt der Text von oben, nicht von links. */
  .buehnenschleier { background: linear-gradient(180deg,
      oklch(0.148 0.012 240 / .95) 0%, oklch(0.148 0.012 240 / .88) 58%,
      oklch(0.148 0.012 240 / .50) 100%); }
  .buehnenzug { display: none; }
  /* Und der Text steht oben, nicht in der Mitte: Zentriert blieb ueber
     der Ueberschrift ein Drittel Bildschirm leer, und wer scrollt, ohne
     etwas gelesen zu haben, scrollt weiter.

     `.start` DAVOR, aus demselben Grund wie oben -- und hier fehlte es
     bis zum 28.08.2026. Die ungebundene Regel traf `.buehne` im Editor,
     und `6vh` sind auf einem Telefon 50 Pixel: Genau so viel leerer
     Streifen stand dort zwischen Kopfleiste und Werkzeugleiste, auf dem
     kleinsten Schirm, wo er am meisten kostet.

     Der Kommentar acht Zeilen weiter oben beschreibt denselben Fehler
     und seine Behebung. Er wurde behoben und drei Zeilen spaeter noch
     einmal gemacht. Deshalb haelt `test_buehne_gebunden.py` die Regel
     jetzt fest, statt sich auf das Lesen zu verlassen. */
  .start .buehne { justify-content: flex-start; min-height: 0;
                   padding-top: clamp(2rem, 6vh, 3.5rem); }
}

/* Auf sehr schmalen Geraeten bricht die Augenbraue in zwei Zeilen und
   sieht aus wie ein Fehler. Dann reicht die kurze Fassung. */
@media (max-width: 26rem) {
  .start .buehne .augenbraue .lang { display: none; }
}

.buehnenknopfe { display: flex; gap: .7rem; flex-wrap: wrap;
                 margin-top: 1.7rem; }
.buehnenknopfe .knopf.leise {
  border-color: oklch(0.945 0.006 240 / .30);
  background: oklch(0.148 0.012 240 / .45);
  backdrop-filter: blur(3px);
}
.buehnenknopfe .knopf.leise:hover {
  border-color: oklch(0.945 0.006 240 / .55);
}
.knopf.gross { height: 44px; padding: 0 1.4rem; font-size: var(--t-base); }

/* DAS APP-STORE-ABZEICHEN (R135).

   APPLES FREIRAUM IST PFLICHT, keine Geschmacksfrage: Seine
   Marketingrichtlinien verlangen ringsum mindestens ein Zehntel der
   Abzeichenhoehe frei -- also rund 5px bei 47px. Der Abstand nach oben
   ist groesser, weil daueber die Knoepfe stehen.

   KEINE EIGENEN FARBEN, KEIN RAHMEN, KEIN SCHATTEN. Die Grafik wird
   nicht veraendert; sie darf nur skaliert werden, und auch das nur
   proportional. Ein Hauch Aufhellung beim Zeigen ist erlaubt, weil er
   die Grafik selbst nicht anfasst. */
.buehnenladen { margin: 1.1rem 0 0; padding: 0 .5rem .5rem 0; }
.buehnenladen a { display: inline-block; line-height: 0; }
.buehnenladen img { height: 47px; width: auto; }
.buehnenladen a:hover img { filter: brightness(1.12); }
.buehnenladen a:focus-visible {
  outline: 2px solid var(--akzent); outline-offset: 4px; border-radius: 8px;
}

/* Bilder: der 1px-Rand ist Pflicht. Ohne ihn zerfliesst eine dunkle
   Aufnahme im dunklen Seitengrund, und man sieht nicht, wo sie aufhoert. */
.beweis { margin: 0; }
/* `<picture>` ist von sich aus inline und waere damit nur so breit wie
   sein Inhalt. Ohne diese Zeile schrumpft jedes Bild, das seit dem
   10.10.2026 in einem `<picture>` steckt, auf seine eigene Breite statt
   die Spalte zu fuellen -- und zwar genau auf den Geraeten, die AVIF
   koennen. */
.beweis picture { display: block; }
.beweis img { display: block; width: 100%; height: auto;
              border-radius: var(--r3); border: 1px solid var(--linie);
              box-shadow: var(--schatten-2); }
.beweis figcaption { margin-top: .85rem; color: var(--ink-still);
                     font-size: var(--t-sm); max-width: 40rem;
                     line-height: 1.55; }

.zweispaltig { display: grid; gap: 2.5rem; align-items: center; }
.zweispaltig .wort p { margin: 0 0 .9rem; color: var(--ink-leise); }
.zweispaltig .wort .hervor { color: var(--ink); font-weight: 550;
                             border-left: 2px solid var(--akzent);
                             padding-left: .9rem; margin-top: 1.4rem; }
.bildunterzeile { color: var(--ink-still); font-size: var(--t-sm);
                  margin-top: .85rem; }

.zweihandys { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.beweis.handy img { border-radius: var(--r2); }

/* TELEFON UND UHR NEBENEINANDER (R140).

   Die Uhr ist SCHMALER gesetzt, nicht gleich gross: Ein Apple-Watch-
   Schirm ist 416 Punkte breit, ein iPhone 1290 -- beide auf dieselbe
   Spaltenbreite gezogen, waere die Uhr riesig und das Verhaeltnis
   gelogen. `align-items: end` stellt sie auf dieselbe Grundlinie, wie
   zwei Gegenstaende auf einem Tisch.

   Die runde Ecke ist GROSS (28%), und das ist der Unterschied zwischen
   „Bildschirmfoto einer Uhr" und „Uhr": Der Schirm der Apple Watch ist
   ein Rechteck mit sehr weichen Ecken. Prozent und nicht Pixel, damit
   es bei jeder Aufnahmegroesse stimmt. */
.geraete { display: grid; grid-template-columns: 1.85fr 1fr;
           gap: 1.6rem; align-items: end; }
.geraete .beweis.uhr img { border-radius: 28%; border: none;
                           box-shadow: var(--schatten-2); }

/* Auf dem Handy untereinander waere die Uhr so breit wie das Telefon.
   Sie behaelt deshalb ihren Platz in der Zeile und wird nur kleiner. */
@media (max-width: 34rem) {
  .geraete { grid-template-columns: 1.6fr 1fr; gap: 1rem; }
}

/* `.wegweiser` gibt es SCHON (Zeile 563) -- Nummernkreis, Flexzeile,
   fertig gestaltet. Hier stand kurzzeitig eine zweite Fassung, und beide
   haben sich gestritten: Die Schritte standen nebeneinander statt
   uebereinander, und die Nummer schrumpfte zu einem Punkt.
   Statt der Klasse bekommt das Markup einen Umschlag (`.schritttext`),
   damit aus zwei Flexkindern eins wird. */
.wegweiser .schritttext b { display: block; margin-bottom: .2rem; }
.wegweiser .schritttext span { display: block; line-height: 1.5; }
.start .wegweiser { margin-top: 1.6rem; }

.formate { display: grid; gap: 1rem; margin-top: 1.6rem;
           grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.formate article { padding: 1.15rem 1.25rem; border: 1px solid var(--linie);
                   border-radius: var(--r2); background: oklch(1 0 0 / .025); }
.formate h3 { font-size: var(--t-base); margin: 0 0 .45rem; }
.formate p { margin: 0; color: var(--ink-still); font-size: var(--t-sm);
             line-height: 1.55; }
.papier .nachsatz { margin-top: 1.4rem; color: var(--ink-leise);
                    max-width: 44rem; }

.sachlich .punkte { list-style: none; padding: 0; margin: 1.4rem 0 0;
                    display: grid; gap: .8rem; max-width: 48rem; }
.sachlich .punkte li { color: var(--ink-still); line-height: 1.6;
                       padding-left: 1.1rem; position: relative; }
.sachlich .punkte li::before { content: ""; position: absolute; left: 0;
                               top: .62em; width: .5rem; height: 2px;
                               background: var(--petrol); border-radius: 1px; }
.sachlich .punkte b { color: var(--ink); font-weight: 550; }
.sachlich.stand { border-top: 1px solid var(--linie); padding-top: 3rem; }

/* Das Geldband. Es erbt `.sachlich` vollstaendig und setzt nur die
   beiden Dinge, die es von einem Textabschnitt unterscheiden: Der
   Vorspann traegt die Zahlen und darf deshalb groesser stehen, und die
   Verweise sollen als Weg erkennbar sein, nicht als Fussnote im
   Fliesstext. */
.sachlich.geldband .vorspann { font-size: var(--t-lg); max-width: 42rem; }
.sachlich.geldband .punkte a { display: inline-block; margin-top: .15rem; }

/* Die Fragen sind Aufklapper (Niklas, 26.08.2026: „das würde ich
   übrigens so als faq machen und denn so dropdowns").

   `<details>` und NICHT ein Skript: Es klappt ohne JavaScript auf, der
   Browser kennt es, Vorleseprogramme kennen es, und die Suchmaschine
   liest den Inhalt auch zugeklappt. Ein selbstgebautes Aufklappen wäre
   mehr Arbeit und weniger wert.

   Zugeklappt ist die Voreinstellung: Zwölf Fragen als Fließtext sind
   eine Wand, und wer eine bestimmte sucht, scrollt an ihr vorbei. */
.fragen .fragenliste { margin: 1.6rem 0 0; max-width: 48rem; }
.fragen .frage { border-bottom: 1px solid var(--linie); }
.fragen .frage summary {
  font-weight: 550; padding: .95rem .2rem .95rem 1.6rem;
  cursor: pointer; position: relative; list-style: none;
}
/* Das eigene Dreieck weg -- Safari und Firefox zeichnen verschiedene. */
.fragen .frage summary::-webkit-details-marker { display: none; }
.fragen .frage summary::marker { content: ""; }
.fragen .frage summary::before {
  content: "+"; position: absolute; left: .2rem; top: .85rem;
  font-size: 1.1rem; line-height: 1; color: var(--ink-still);
}
.fragen .frage[open] summary::before { content: "−"; }
.fragen .frage summary:hover { color: var(--ink); }
/* Die Umrandung beim Tabben bleibt: Wer mit der Tastatur navigiert,
   muss sehen, wo er steht. */
.fragen .frage summary:focus-visible { outline: 2px solid var(--ink); }
.fragen .antwort {
  margin: 0 0 1.1rem 1.6rem; color: var(--ink-still); line-height: 1.6;
}

/* Der Aufruf am Ende der Startseite und der Fuss der Registrierung.
   Frueher hingen diese Regeln am Anfrageformular, das es seit dem
   21.08.2026 nicht mehr gibt. */
.feldzeile { display: flex; align-items: center; gap: 1rem;
             flex-wrap: wrap; margin-top: 1.4rem; }
.kleingedruckt { color: var(--ink-still); font-size: var(--t-xs);
                 margin: 1.1rem 0 0; line-height: 1.5; max-width: 44rem; }
/* Der Honigtopf gegen selbsttaetige Ausfueller. Nicht `display:none` --
   manche pruefen darauf; ausserhalb des Bildes bleibt er fuer sie ein
   normales Feld. */
input[name="webseite"] { position: absolute; left: -9999px;
                         width: 1px; height: 1px; }

/* Ab Tablet nebeneinander. Darunter bleibt alles untereinander -- auf
   dem Handy ist zweispaltig immer schlechter als einspaltig. */
@media (min-width: 60rem) {
  .zweispaltig { grid-template-columns: 1fr 1fr; }
  .zweispaltig.gedreht .wort { order: 2; }
  /* DIE BILDUNTERZEILE GEHOERT UNTER BEIDE SPALTEN (30.09.2026).

     Ohne diese Regel ist sie das DRITTE Rasterkind und landet damit in
     der rechten Spalte der ERSTEN Zeile -- neben dem Bild statt
     darunter. Der Fliesstext, der dort hingehoert, rutscht in die
     zweite Zeile und steht auf einmal unter den Bildern.

     Das trifft jeden `zweispaltig`-Abschnitt mit Unterzeile, also
     schon heute drei auf der Startseite. Aufgefallen ist es beim
     Ansehen des neuen Uhr-Abschnitts -- und dann sah der bestehende
     Abschnitt daneben genauso aus.

     `order: 3` schiebt sie ans Ende, `grid-column: 1 / -1` legt sie
     ueber die volle Breite. Beides zusammen, weil `order` allein sie
     zwar nach hinten, aber in eine halbe Spalte setzte. */
  .zweispaltig > .bildunterzeile { order: 3; grid-column: 1 / -1; }
}

/* --- Lernauftrag (A7) --------------------------------------------------- */
/*
 * Was der Coach jemandem aufgegeben hat, muss auf den ersten Blick von
 * dem zu unterscheiden sein, was einfach im Playbook steht. Petrol und
 * nicht Gold: Gold ist in dieser Marke die Warnfarbe, und eine Aufgabe
 * ist keine Warnung.
 */
.aufgabenmarke {
  display: inline-block; margin-left: 0.45rem; vertical-align: 1px;
  padding: 0.08rem 0.42rem; border-radius: 999px;
  font-size: var(--t-xs); font-weight: 700; letter-spacing: 0.02em;
  color: var(--petrol-tief); background: var(--petrol-hell);
  border: 1px solid var(--petrol-rand);
  /* Umbricht nicht: „Deine Aufgabe" auf zwei Zeilen in einer Kachel
     sieht aus wie ein zweiter Titel. */
  white-space: nowrap;
}
.aufgabenhinweis a { color: var(--petrol-tief); }

.fortschrittsbalken.aus-auftrag .gefuellt { background: var(--petrol-tief); }

.lernzahl .marker {
  display: block; margin-top: 0.1rem;
  /* Die Zahl darueber steht in Monospace, damit Ziffern untereinander
     stehen. Ein Wort in Monospace sieht dagegen nach Quelltext aus. */
  font-family: var(--schrift); font-size: var(--t-xs);
  font-weight: 600; color: var(--petrol-tief); letter-spacing: 0.02em;
}

/* Der Link in die Kaderzeile. Leise, weil er neben einem Namen steht und
   nicht neben einer Entscheidung. */
.aufgabenlink { margin-top: 0.5rem; }

/* Die Kreuzchenliste auf der Aufgabenseite. Die ganze Zeile ist der
   Schalter: Wer auf dem Telefon ein 16-Pixel-Kaestchen treffen muss,
   hakt daneben. */
.auftragsliste { display: grid; gap: 0.25rem; margin-bottom: 0.4rem; }
.auftragszeile {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.55rem 0.7rem; border-radius: var(--r3);
  border: 1px solid transparent; cursor: pointer;
  transition: background var(--tempo) var(--kurve);
}
.auftragszeile:hover { background: var(--flaeche-hoch); }
.auftragszeile:has(input:checked) {
  background: var(--petrol-hell); border-color: var(--petrol-rand);
}
.auftragszeile input { width: 20px; height: 20px; flex: 0 0 auto; }
.auftragszeile .titel { display: block; font-weight: 600; }
.auftragszeile .unter {
  display: block; font-size: var(--t-sm); color: var(--ink-leise);
}

/* Sprachwahl in der Fusszeile (R22).
   Fuenf Kuerzel nebeneinander, das aktive hervorgehoben. Sie sehen aus
   wie die Links daneben und verhalten sich auch so -- ein Knopf, der
   nach Knopf aussieht, zoege in der Fusszeile mehr Aufmerksamkeit auf
   sich als das Impressum, und das waere die falsche Rangfolge. */
.sprachwahl { display: flex; gap: 0.5rem; align-items: center; }
.sprachwahl form { margin: 0; }
.sprachwahl button,
.sprachwahl .jetzt {
  font: inherit; font-size: 0.72rem; letter-spacing: 0.06em;
  background: none; border: 0; padding: 0.15rem 0.1rem; cursor: pointer;
  color: var(--ink-still); text-decoration: none;
}
.sprachwahl button:hover { color: var(--ink); text-decoration: underline; }
.sprachwahl .jetzt { color: var(--ink); font-weight: 600; cursor: default; }

/* Der Umschalter in der KOPFZEILE (seit 27.08.2026 auch dort).

   Ein feiner Strich trennt ihn von den Zugangsknoepfen -- sonst liest
   sich „DE EN ES FR IT Anmelden" wie eine einzige Reihe, und das
   Sprachkuerzel neben dem Knopf sieht aus, als gehoerte es dazu. */
.sprachwahl.kopf { gap: 0.35rem; padding-right: 0.55rem; margin-right: 0.2rem;
                   border-right: 1px solid var(--linie); }

/* AUF SCHMALEN BILDSCHIRMEN NUR IN DER FUSSZEILE. Fuenf Kuerzel und
   zwei Knoepfe passen dort nicht nebeneinander; der Pfad wuerde
   umbrechen und die Kopfzeile zweizeilig. Verloren geht nichts -- die
   Fusszeile hat denselben Umschalter, und auf dem Handy ist der Weg
   dorthin kurz. */
@media (max-width: 46rem) {
  .sprachwahl.kopf { display: none; }
}

/* DIE SPRACHWAHL AUF DEM TELEFON (R29).

   Gemeldet von Niklas am 28.08.2026: „man sollte in der handy ansicht
   via dropdown menue im web auch die sprache auswaehlen" -- und im
   selben Atemzug, dass ihm die Fusszeile am Handy nicht gefaellt. Das
   eine ist der Grund fuer das andere: Fuenf Kuerzel, vier Verweise und
   die Marke brechen auf einem 390 Pixel breiten Geraet in drei Zeilen
   um.

   Fuenf Zwei-Buchstaben-Ziele sind ausserdem zu klein: Apples
   Mindestmass fuer eine Tippflaeche sind 44 Punkte.

   Deshalb die Reihe weg und EIN Auswahlfeld hin -- beides liegt im
   Dokument, umgeschaltet wird hier und nicht per JavaScript. */
.sprachfeld { display: none; }

/* DIE SPRACHWAHL AUF DER KONTOSEITE (R111.7).

   Dort ist sie KEIN Notbehelf fuer schmale Bildschirme, sondern der
   Ort, an dem man sie sucht -- die App hat sie seit R31 unter „Konto".
   Also auf JEDER Breite das Auswahlfeld und nicht die Reihe der
   Kuerzel: Ein Block mit einer Ueberschrift „Sprache" und fuenf
   Zwei-Buchstaben-Knoepfen darunter sieht aus wie eine Fussnote, kein
   Auswahlfeld wie die drei Bloecke darueber. */
.kontoblock .sprachwahl.konto { display: none; }
.kontoblock .sprachfeld {
  display: flex; align-items: center; gap: 0.5rem;
  flex-wrap: wrap; width: 100%;
}
.kontoblock .sprachfeld label {
  font-size: 0.78rem; color: var(--ink-still);
}
.kontoblock .sprachfeld select {
  font: inherit; font-size: 0.9rem;
  /* 44 Punkte hoch -- dieselbe Zahl wie ueberall, und aus demselben
     Grund: Apples Mindestmass fuer eine Tippflaeche. */
  min-height: 2.75rem; padding: 0.35rem 0.6rem;
  background: var(--flaeche-panel); color: var(--ink);
  border: 1px solid var(--linie); border-radius: 10px;
  flex: 1 1 10rem;
}
.kontoblock .sprachfeld button {
  font: inherit; font-size: 0.9rem; min-height: 2.75rem;
  padding: 0.35rem 0.9rem; cursor: pointer;
  background: var(--flaeche-panel); color: var(--ink);
  border: 1px solid var(--linie); border-radius: 10px;
}

@media (max-width: 46rem) {
  .sprachwahl.fuss { display: none; }

  .sprachfeld {
    display: flex; align-items: center; gap: 0.5rem;
    flex-wrap: wrap; width: 100%;
  }
  .sprachfeld label {
    font-size: 0.78rem; color: var(--ink-still);
  }
  .sprachfeld select {
    font: inherit; font-size: 0.85rem;
    /* 44 Punkte hoch, siehe oben. Ein Auswahlfeld, das man dreimal
       antippen muss, ist kein Fortschritt gegenueber fuenf Kuerzeln. */
    min-height: 2.75rem; padding: 0.35rem 0.6rem;
    background: var(--flaeche-panel); color: var(--ink);
    border: 1px solid var(--linie); border-radius: 10px;
    flex: 1 1 8rem;
  }
  .sprachfeld button {
    font: inherit; font-size: 0.85rem; min-height: 2.75rem;
    padding: 0.35rem 0.9rem; cursor: pointer;
    background: var(--flaeche-panel); color: var(--ink);
    border: 1px solid var(--linie); border-radius: 10px;
  }

  /* UND DIE FUSSZEILE SELBST.

     ZWEITER ANLAUF, nach dem Bildschirmfoto vom 28.08.2026. Der erste
     hat sie nur untereinander gestellt, und das Ergebnis war nicht
     besser: Fuenf Verweise fuellten eine Zeile, „Anmelden" stand
     allein darunter -- ein Waisenkind --, und darunter kam ein nacktes
     Auswahlfeld. Ein loser Haufen grauer Woerter.

     Jetzt drei Bloecke mit klarem Abstand: die Marke, die Verweise in
     ZWEI SPALTEN (sechs Verweise, drei saubere Zeilen, kein
     Waisenkind), und die Sprache als eigener, beschrifteter Block. */
  .fussleiste {
    flex-direction: column; align-items: stretch; gap: 1.6rem;
    padding: 1.75rem clamp(1rem, 4vw, 2rem) 2rem;
  }

  .fussleiste nav {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: 0.15rem 1rem;
  }
  .fussleiste nav a {
    /* 44 Punkte hoch, wie ueberall auf dem Telefon. */
    display: flex; align-items: center; min-height: 2.75rem;
    padding: 0 0; line-height: 1.2;
  }

  /* Die Sprachwahl bekommt eine eigene Zeile ueber dem Feld. Neben dem
     Feld sass sie eingequetscht am linken Rand und sah aus wie ein
     verrutschtes Formular. */
  .sprachfeld {
    flex-direction: column; align-items: stretch; gap: 0.45rem;
    padding-top: 1.1rem; border-top: 1px solid var(--linie);
  }
  .sprachfeld label {
    font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-leise);
  }
  .sprachfeld select {
    /* Das eigene Dreieck statt des systemeigenen: Ohne
       `appearance: none` sieht das Feld auf jedem Geraet anders aus --
       und auf keinem wie der Rest der Seite. */
    appearance: none; -webkit-appearance: none;
    width: 100%; flex: none;
    padding-right: 2.4rem;
    background-image:
      linear-gradient(45deg, transparent 50%, var(--ink-still) 50%),
      linear-gradient(135deg, var(--ink-still) 50%, transparent 50%);
    background-position:
      calc(100% - 1.15rem) calc(50% - 0.1rem),
      calc(100% - 0.8rem) calc(50% - 0.1rem);
    background-size: 0.35rem 0.35rem, 0.35rem 0.35rem;
    background-repeat: no-repeat;
  }
  .sprachfeld button { width: 100%; }
}

/* --- Die Preisseite (Runde 5) -----------------------------------------

   Drei Kacheln nebeneinander, auf schmalen Schirmen untereinander.
   `auto-fit` und nicht `repeat(3, 1fr)`: Bei 1080 px Textbreite passen
   drei bequem, bei 700 zwei und auf dem Handy eine -- ohne dass irgendwo
   eine Zahl fuer einen Bruchpunkt steht, die beim naechsten Schriftgrad
   nicht mehr passt.

   `align-items: stretch` ist die Vorgabe von Grid und bleibt es
   ausdruecklich: Drei Preiskacheln unterschiedlicher Hoehe sehen aus,
   als waere eine wichtiger. Genau deshalb traegt auch die Schulkachel
   ihr „kostenlos" an der Stelle, an der die anderen ihren Betrag haben. */
.preisraster {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr));
  gap: 1rem;
  margin-bottom: 1rem;
}

/* KEINE Hervorhebung der mittleren Kachel. Ueblich waere, die teurere
   als „beliebteste" zu markieren -- ein Verkaufstrick, der nicht zu
   einem Preismodell passt, dessen ganzer Sinn ist, dass ein Vorstand
   nicht rechnen muss. */
.preiskachel h2 { font-size: var(--t-md); }

.preiskachel .punkte { margin: 0; padding-left: 1.1rem; }
.preiskachel .punkte li { margin: 0.25rem 0; color: var(--ink-leise); }

/* Der Betrag traegt die Seite, also darf er gross sein -- aber nur er.
   `tabular-nums`, damit 8,00 und 15,00 untereinander dieselbe
   Ziffernbreite haben; sonst tanzen die Kommas. */
.preiszahl {
  margin: 0;
  font-size: clamp(1.9rem, 4.5vw, 2.5rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.preiszahl span {
  display: block;
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink-still);
}

/* „kostenlos" steht an derselben Stelle wie ein Betrag und ist trotzdem
   ein Wort -- also etwas kleiner, sonst sprengt es die Kachel. */
.preiszahl-frei { font-size: clamp(1.5rem, 3.4vw, 1.9rem); }

.preiszeile { margin: 0; color: var(--ink-leise); }

.preiskachel .knopf { margin-top: auto; align-self: flex-start; }

.preisabschluss { margin-bottom: 1rem; }
.preisabschluss .knopf { align-self: flex-start; }

/* Die Demo-Zeile auf der Startseite (10.09.2026).

   Der Weg zum Abo, von der Seite aus, auf der man arbeitet. Eine
   ZEILE und kein Kasten mit Rahmen: Sie soll gesehen werden und
   niemanden aufhalten -- eine Demo, an der man vorbei muss, ist eine
   Bezahlschranke. */
.demozeile {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: .8rem 1.2rem;
  margin: 0 0 1.6rem;
  padding: .9rem 1.1rem;
  border: 1px solid var(--linie);
  border-radius: var(--r2);
  background: var(--flaeche-panel);
}
.demozeile p { margin: 0; flex: 1 1 18rem; color: var(--ink-still); }
.demozeile b { color: var(--ink); }
.demozeile .aktionen { display: flex; flex-wrap: wrap; gap: .5rem; }

/* --- Monat oder Jahr (R118) --------------------------------------

   Zwei Links und kein Umschalter im Formular. Ein Umschalter
   muesste den Betrag im Browser neu rechnen -- eine zweite
   Preisrechnung, und die erste Abweichung faellt niemandem auf.
   Der aktive steht als `.haupt` da, damit ohne Farbsehen
   erkennbar bleibt, welche Zahlweise gerade gilt. */
.laufzeitwahl {
  display: flex; flex-wrap: wrap; gap: .6rem;
  margin: 0 0 1.2rem;
}
.laufzeitwahl .knopf { display: inline-flex; align-items: center; gap: .5rem; }
.laufzeitwahl .chip { font-size: .78rem; }

/* --- Die Hilfeseite (R28, nachgereicht am 01.09.2026) -------------------

   Niklas: „die hilfe seite sieht katastrophal aus." Er hat recht, und der
   Grund ist peinlich einfach: Die Vorlage benutzt sieben Klassen --
   `hilfeseite`, `hilfe-inhalt`, `hilfe-liste`, `hilfe-tabelle`,
   `linienmarke`, `endung`, `schlicht` -- und fuer KEINE stand hier eine
   Regel. Die Seite fiel damit auf die Browservorgaben zurueck:
   Definitionslisten ohne Abstand, eine Tabelle ohne Linien, alles in
   Serifen auf dunklem Grund.

   DIE LEHRE, und sie ist dieselbe wie sonst in diesem Projekt: Eine
   Klasse im HTML ist eine Behauptung. Ohne Regel dahinter ist sie eine
   leere. `test_hilfe.py` prueft ab jetzt, dass jede benutzte Klasse eine
   Regel hat -- fuer die ganze Seite, nicht nur fuer diese sieben. */

.hilfeseite h2 {
  margin: 2.6rem 0 .3rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--linie);
}
.hilfeseite section:first-of-type h2 { border-top: 0; padding-top: 0; }
.hilfeseite h3 {
  margin: 1.7rem 0 .4rem;
  font-size: var(--t-md);
  color: var(--ink-leise);
}

/* DAS SUCHFELD (10.09.2026). Ueber hundert Eintraege und auf dem
   Telefon einundzwanzig Bildschirme -- ab dieser Groesse findet ein
   Blick auf die Ueberschriften nichts mehr.

   Es steht `hidden` in der Vorlage und wird erst vom Skript sichtbar
   gemacht; ohne JavaScript bleibt die Seite, wie sie war. */
.hilfe-suche { margin: 1.4rem 0 .4rem; max-width: 34rem; }
.hilfe-suche label {
  display: block; margin-bottom: .3rem;
  font-size: var(--t-sm); color: var(--ink-leise);
}
.hilfe-suche input[type="search"] {
  width: 100%;
  padding: .55rem .8rem;
  border: 1px solid var(--linie-stark);
  border-radius: var(--r2);
  background: var(--flaeche-panel);
  color: var(--ink);
  font: inherit;
}
.hilfe-suche input[type="search"]:focus-visible {
  border-color: var(--petrol); outline: none;
}
.hilfe-suche .hinweistext { margin: .35rem 0 0; }

/* Das Inhaltsverzeichnis. Anker als Chips, damit sie als Ziele lesbar
   sind und nicht als Fliesstext mit Unterstreichung.

   ES KLEBT OBEN MIT. Bei einundzwanzig Bildschirmen ist „wo bin ich
   gerade" die Frage, die der Scrollbalken nicht beantwortet -- und der
   Weg zurueck nach oben war bisher Wischen. `--z-haftend` ist dieselbe
   Ebene wie die Kopfleiste; `top` ist deren Hoehe, sonst schoebe sich
   das Verzeichnis darunter. */
.hilfe-inhalt {
  display: flex; flex-wrap: wrap; gap: .5rem;
  margin: 1.4rem 0 2.2rem;
  position: sticky; top: 3.1rem; z-index: 1;
  padding: .6rem 0;
  background: var(--flaeche);
}
/* Der Abschnitt, in dem gerade gelesen wird. Kein Farbklecks, sondern
   der Rand -- die Marke soll sagen „hier", nicht „klick mich". */
.hilfe-inhalt a.hier {
  color: var(--ink);
  border-color: var(--petrol);
}
/* Waehrend gesucht wird, klebt nichts: Die Seite ist dann kurz, und
   ein klebendes Verzeichnis ueber drei Treffern nimmt nur Platz. */
.hilfeseite.wird-gesucht .hilfe-inhalt { position: static; }
.hilfe-inhalt a {
  padding: .42rem .8rem;
  border: 1px solid var(--linie-stark);
  border-radius: var(--r2);
  color: var(--ink-leise);
  text-decoration: none;
  font-size: var(--t-sm);
}
.hilfe-inhalt a:hover,
.hilfe-inhalt a:focus-visible {
  color: var(--ink);
  border-color: var(--ink-still);
  background: var(--flaeche-panel);
}

/* Die Abschnitte selbst. Begriff fett, Erklaerung eingerueckt darunter
   -- und NICHT nebeneinander: Auf einem Telefon waeren zwei Spalten je
   zwanzig Zeichen breit. */
.hilfe-liste { margin: .9rem 0 0; max-width: 52rem; }
.hilfe-liste dt {
  font-weight: 600;
  margin-top: 1.05rem;
  display: flex; align-items: center; gap: .5rem;
}
.hilfe-liste dd {
  margin: .2rem 0 0;
  color: var(--ink-still);
  line-height: 1.6;
}
/* Die Funktionsliste (R70). Drei Angaben in einem Absatz: was sie tut,
   wo man sie findet, woran man denken muss.

   WO UND DENK STEHEN IN EIGENEN ZEILEN und nicht im Fliesstext dahinter:
   „Wo finde ich das" ist die Frage, mit der jemand hier ankommt, und sie
   soll sich mit dem Auge abfahren lassen, ohne jeden Satz zu lesen. Die
   Farbe unterscheidet sie, nicht die Groesse -- kleiner gesetzt waere es
   die eine Zeile, die am Spielfeldrand niemand liest. */
.funktionsliste .wo,
.funktionsliste .denk { display: block; margin-top: .18rem; }
.funktionsliste .wo { color: var(--ink-leise); }
.funktionsliste .denk {
  color: var(--ink-leise);
  border-left: 2px solid var(--linie);
  padding-left: .6rem;
}

/* Das Beispielbild zu einer Linienart (R70). Es steht VOR der
   Kurzform und nicht daneben: Auf einem Telefon wären zwei Spalten je
   zwanzig Zeichen breit -- dieselbe Begründung wie oben. */
.linienliste .linienbild { display: block; margin: .35rem 0 .3rem; }
.linienliste .linienbild svg { width: 42mm; max-width: 100%; height: auto; }

/* Die Bildschirmfotos der Bedienoberfläche (10.09.2026).

   NUR HIER GIBT ES FOTOS. Sonst wird in der Hilfe gezeichnet -- ein
   gezeichnetes Bild ändert sich mit dem Renderer, ein Foto ist ein
   Stand von heute. Für „wo sitzt der Knopf" gibt es keinen anderen Weg.

   EIN RAHMEN UND EIN ABSTAND. Ohne ihn läuft ein dunkles Bildschirmfoto
   auf dunklem Grund in die Seite hinein, und man sieht nicht, wo das
   Bild aufhört und die Seite anfängt.

   `aspect-ratio` steht bewusst NICHT hier: Die drei Bilder haben sehr
   verschiedene Formate (eine breite Leiste, ein hohes Feld), und eine
   feste Vorgabe schnitte eines davon an. `height: auto` und der
   Umbruch machen den Rest. */
.bedienbilder {
  display: grid; gap: 1.4rem; margin: 1.1rem 0 1.6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  max-width: 52rem;
}
.bedienbilder figure { margin: 0; }
.bedienbilder img {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--linie); border-radius: 10px;
  background: var(--flaeche-tief);
}
.bedienbilder figcaption {
  margin-top: .5rem; font-size: .86rem; line-height: 1.55;
  color: var(--ink-still);
}

.hilfe-liste.schlicht { list-style: none; padding: 0; }
.hilfe-liste.schlicht li {
  padding: .5rem 0;
  border-bottom: 1px solid var(--linie);
  color: var(--ink-leise);
}

/* Die Dateiendung hinter einem Ausdruck: eine Angabe, kein Titel. */
.hilfeseite .endung {
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-weight: 400;
  color: var(--ink-still);
  padding: .1rem .42rem;
  border: 1px solid var(--linie);
  border-radius: var(--r1);
}

/* Der Farbtupfer vor einer Linienart. Er traegt seine Farbe als
   `style`-Angabe aus `render.LINE_STYLES` -- hier steht nur die Form. */
.hilfeseite .linienmarke {
  width: 1.5rem; height: .22rem; flex: 0 0 auto;
  border-radius: 2px;
}

/* Die Tabelle „Demo gegen Abo". Zebrastreifen statt Gitter: Drei
   Spalten mit kurzen Angaben liest man zeilenweise. */
.hilfe-tabelle {
  width: 100%; max-width: 52rem;
  border-collapse: collapse;
  margin: 1rem 0 0;
}
.hilfe-tabelle th,
.hilfe-tabelle td {
  text-align: left;
  padding: .62rem .8rem;
  border-bottom: 1px solid var(--linie);
  vertical-align: top;
}
.hilfe-tabelle th {
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink-leise);
  white-space: nowrap;
}
.hilfe-tabelle td:first-child { color: var(--ink); }
.hilfe-tabelle td { color: var(--ink-still); }
.hilfe-tabelle tbody tr:nth-child(even) { background: var(--flaeche-panel); }

/* Auf dem Telefon wird die Tabelle sonst breiter als der Bildschirm und
   schiebt die ganze Seite zur Seite -- derselbe Fehler wie bei der
   Kopfleiste im Editor (R32). */
@media (max-width: 560px) {
  .hilfe-tabelle { display: block; overflow-x: auto; }
}

/* --- Klassen ohne Regel, nachgereicht am 02.09.2026 ---------------------

   Gefunden von `test_klassen_haben_regeln.py`, das es wegen der
   Hilfeseite gibt. Es hat elf weitere Vorlagen gefunden, in denen eine
   Klasse steht und nichts dahinter.

   DER SCHLIMMSTE FALL WAR `.warnung`. Sie steht auf drei Seiten immer
   zusammen mit `.meldung` -- unter anderem auf „Konto loeschen". Eine
   Warnung sah damit genau aus wie ein gewoehnlicher Hinweis. Das ist
   nicht Gestaltung, das ist Bedeutung: Wer eine Warnung nicht als solche
   erkennt, liest sie nicht. */

.meldung.warnung {
  border-color: var(--warn, var(--gold));
  background: color-mix(in oklch, var(--gold) 12%, var(--flaeche-panel));
}
.meldung.warnung::before { content: "⚠ "; }

/* Zwei Felder nebeneinander (Regelwerk und Klasse im Playbook-Formular).
   Ohne Regel standen sie untereinander -- richtig, aber nicht das, was
   der Name verspricht. */
.feldpaar {
  display: grid; gap: .9rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}

/* Die Nummer vor einem Playnamen auf der Kachel. Sie ordnet ein und ist
   nicht der Name selbst. */
.kachelnummer { color: var(--ink-still); font-variant-numeric: tabular-nums; }

/* Die Vorschau des Vereinswappens im Formular. */
.wappenprobe {
  margin: 0 0 .9rem; display: flex; align-items: center; gap: .8rem;
}
.wappenprobe img {
  width: 64px; height: 64px; object-fit: contain;
  border: 1px solid var(--linie); border-radius: var(--r2);
  background: var(--flaeche-panel);
}
.wappenprobe figcaption { color: var(--ink-still); font-size: var(--t-sm); }

/* Die beiden Wege zur Schullizenz, nebeneinander. */
.schulkarten {
  display: grid; gap: 1rem; margin: 1.4rem 0 0;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
}
.karte {
  border: 1px solid var(--linie); border-radius: var(--r3);
  padding: 1.1rem 1.2rem; background: var(--flaeche-panel);
}
.karte h2, .karte h3 { margin-top: 0; }

/* --- Die Kaufstrecke (R102, 09.09.2026) --------------------------------

   Fuenf Klassen fuer drei Seiten: Kaufen, Kuendigen, Widerrufen. Sie
   sehen aus wie Formularteile, sind aber etwas anderes -- an jeder
   haengt eine Rechtsfolge, und deshalb duerfen sie nicht aussehen wie
   beiläufige Zeilen.

   DER BESTELLKASTEN IST DER WICHTIGSTE. § 312j Abs. 2 BGB verlangt,
   dass die wesentlichen Angaben UNMITTELBAR ueber dem Bestellknopf
   stehen -- „unmittelbar" ist woertlich gemeint. Der Kasten macht das
   sichtbar: Was darin steht, gehoert zum Knopf und nicht zur Seite
   darueber. Ohne ihn stuende der Satz irgendwo im Fliesstext, und die
   Anforderung waere formal erfuellt und tatsaechlich nicht.

   WAHLKARTE GEGEN WAHLZEILE: Eine Karte ist eine Entscheidung mit
   Folgen (welche Stufe, welcher Vertrag), eine Zeile ist eine Angabe
   (wer kauft, Haekchen fuer die Bedingungen). Der Unterschied ist die
   Flaeche -- eine Karte laesst sich am Rand treffen, eine Zeile nicht,
   und genau so unterschiedlich wichtig sind sie.

   Gefunden von `test_klassen_haben_regeln.py`, wie schon die
   Fremdanmeldeknoepfe: Ohne Regel faellt die Seite auf die Vorgaben des
   Browsers zurueck, und das sieht nur, wer sie aufmacht. */
.wahlkarte {
  display: block; margin: .7rem 0 0; padding: .9rem 1rem;
  border: 1px solid var(--linie); border-radius: 12px;
  background: var(--flaeche-panel); cursor: pointer;
}
.wahlkarte:has(input:checked) {
  border-color: var(--petrol-rand); background: var(--petrol-hell);
}
.wahlkarte input { margin-right: .6rem; }
.wahltitel { font-weight: 650; }
.wahlkarte .leise { display: block; margin-top: .2rem;
                    color: var(--ink-still); font-size: var(--t-sm); }

.wahlzeile {
  display: flex; align-items: baseline; gap: .55rem;
  margin: .5rem 0 0; line-height: 1.55;
}

.bestellkasten {
  margin: 1.6rem 0 0; padding: 1.1rem 1.2rem;
  border: 1px solid var(--linie-stark); border-radius: 12px;
  background: var(--flaeche-tief);
}
.bestellkasten p { margin: 0 0 .9rem; color: var(--ink-leise);
                   line-height: 1.6; }
.bestellkasten .knopf { width: 100%; }

/* Das Formular fuer eine Kuendigung oder einen Widerruf OHNE Anmeldung.
   Schmal wie jedes Formular, das man am Telefon ausfuellt. */
.erklaerung { display: flex; flex-direction: column; gap: .3rem;
              margin-top: 1.2rem; max-width: 30rem; }
.erklaerung label { margin-top: .8rem; font-weight: 600; }
.erklaerung .leise { color: var(--ink-still); font-size: var(--t-sm);
                     margin: .1rem 0 0; }

/* Die Zeile, in der man den Verein fuer die Schullizenz waehlt. */
.auswahlzeile {
  display: flex; flex-wrap: wrap; align-items: center; gap: .7rem;
  margin: 1rem 0 0;
}

/* --- Die Knoepfe fuer Google und Apple (R19), nachgereicht 02.09.2026 ---

   Gefunden von `test_klassen_haben_regeln.py`: `.fremdanmeldung`,
   `.fremd`, `.fremd-google` und `.fremd-apple` standen im HTML, und
   keine davon hatte eine Regel. Die beiden Knoepfe bekamen nur `.knopf`
   -- also zwei gewoehnliche Knoepfe, in denen das Logo am Text klebt.

   DAS IST DAS ERSTE, WAS EIN NEUER BENUTZER SIEHT. Wer hier zoegert,
   legt kein Konto an.

   BEIDE GLEICH GROSS UND GLEICH GEBAUT, mit einer Ausnahme: die Farbe.
   Google und Apple geben fuer ihre Knoepfe Gestaltungsregeln vor, und
   ein Knopf, der sich nicht daran haelt, ist bei der App-Abnahme ein
   Grund zur Ablehnung. Google will sein Logo auf hellem oder dunklem
   Grund mit ausreichend Kontrast, Apple seinen Knopf in Schwarz, Weiss
   oder Weiss mit Rand. Auf einer dunklen Seite ist Weiss die Fassung,
   die beide zulassen. */

.fremdanmeldung { display: flex; flex-direction: column; gap: .6rem; }
.fremdanmeldung form { margin: 0; }

.knopf.fremd {
  width: 100%;
  display: inline-flex; align-items: center; justify-content: center;
  gap: .6rem;
  min-height: 46px;
  font-weight: 550;
  /* Beide Zeichen sind gleich hoch gesetzt, damit die Schrift auf einer
     Linie steht. Ohne das sitzt „Mit Apple anmelden" zwei Pixel tiefer
     als „Mit Google anmelden", und das sieht man sofort, ohne es
     benennen zu koennen. */
  line-height: 1;
}
.knopf.fremd svg { flex: 0 0 auto; }

.knopf.fremd-google {
  background: #FFFFFF; color: #1F1F1F; border-color: #DADCE0;
}
.knopf.fremd-google:hover,
.knopf.fremd-google:focus-visible { background: #F1F3F4; }

.knopf.fremd-apple {
  background: #FFFFFF; color: #000000; border-color: #FFFFFF;
}
.knopf.fremd-apple:hover,
.knopf.fremd-apple:focus-visible { background: #E8E8ED; }

/* Das „oder" zwischen Passwort und den Anbieterknoepfen.

   Die Klasse stand nur in `editor.css`, und die wird ausschliesslich von
   `editor.html` geladen. Auf der Anmelde- und der Registrierseite -- den
   einzigen beiden Seiten, auf denen `_fremdanmeldung.html` ueberhaupt
   vorkommt -- war das „oder" deshalb ein blanker Absatz statt einer
   Trennlinie. */
.trenner {
  display: flex; align-items: center; gap: .8rem;
  margin: 1.4rem 0; color: var(--ink-still); font-size: var(--t-sm);
}
.trenner::before,
.trenner::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--linie);
}

/* DIE SYMBOLE DER DRUCKSEITE (R99).
 *
 * Niklas am 09.09.2026 mit fünf gezeichneten SVG: „bgl unserer druck
 * funktion ja hübsch sie einfach mit unseren svg auf bitte". Ein
 * Papierstapel, ein Armband, ein Bogen -- man sieht vor dem Aufklappen,
 * was herauskommt.
 *
 * DIESELBEN DATEIEN WIE IN DER APP. Dort liegen sie als erzeugtes PDF
 * im Bildkatalog (`scripts/drucksymbole.py`), hier unmittelbar als SVG.
 * Eine Zeichnung, zwei Wege -- und keine zweite Fassung, die
 * auseinanderlaufen kann.
 *
 * `flex-shrink: 0`, weil eine lange Überschrift das Bild sonst
 * zusammendrückt: „Bilder zum Weiterverwenden" bricht auf schmalen
 * Fenstern um, und ein gequetschtes Symbol sieht aus wie ein Fehler. */
.drucksymbol {
  flex-shrink: 0;
  border-radius: 8px;
  background: var(--flaeche-hoch, #F4F7F9);
}

/* Der Hinweis auf die andere Sprachfassung (R138).
   Er steht ueber dem Inhalt und soll ihn nicht verdraengen: eine
   Zeile, leise, aber anklickbar. Der Satz steht IMMER in der Sprache,
   auf die er zeigt -- wer die Seitensprache nicht versteht, versteht
   auch den Hinweis nicht, wenn er uebersetzt waere. */
.anderesprache {
  margin: 0;
  padding: .5rem 1rem;
  text-align: center;
  font-size: var(--t-sm);
  background: var(--flaeche-panel);
  border-bottom: 1px solid var(--linie);
  color: var(--ink-leise);
}
.anderesprache a {
  color: var(--petrol);
  text-decoration: underline;
  text-underline-offset: .2em;
}

/* ------------------------------------------------------------------ *
 * DIE WISSENSSEITEN (R150) -- Route Tree und Regelvergleich.
 *
 * JEDER SELEKTOR BEGINNT MIT `.wissen`. Dieses Blatt wird gebuendelt
 * und gilt damit auf JEDER Seite; eine Regel auf `table` oder `ol`
 * traefe die Verwaltung, den Editor und die Kaufstrecke gleich mit.
 * Genau dieses Muster hat im September dreiunddreissig Mal zugeschlagen.
 * ------------------------------------------------------------------ */

.wissenseite h2 { margin-top: 2.2rem; }
.wissenseite p { max-width: 62ch; }

.wissen-regel {
  border-left: 3px solid var(--petrol);
  background: var(--petrol-hell);
  padding: .75rem 1rem;
  border-radius: 0 6px 6px 0;
  font-size: var(--t-md);
}

/* Der Baum: zehn Karten, je eine Route. */
.wissen-baum {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}

.wissen-ast {
  background: var(--flaeche-panel);
  border: 1px solid var(--linie);
  border-radius: 10px;
  padding: .85rem;
}

/* Die Richtung wird FARBLICH unterschieden, aber nie NUR farblich:
   Unter jeder Karte steht sie ausgeschrieben. Wer die Farben nicht
   unterscheiden kann, verliert sonst genau die Merkregel, um die es
   auf dieser Seite geht. */
.wissen-ast.wissen-aussen { border-left: 3px solid var(--gold); }
.wissen-ast.wissen-innen  { border-left: 3px solid var(--petrol); }
.wissen-ast.wissen-gerade { border-left: 3px solid var(--linie-stark); }

.wissen-bild {
  background: var(--flaeche-tief);
  border-radius: 6px;
  padding: .4rem;
  display: flex;
  justify-content: center;
}
.wissen-bild svg { width: 100%; height: auto; max-width: 150px; }

.wissen-nummer {
  margin: .6rem 0 .2rem;
  font-family: var(--schrift-marke);
  font-size: var(--t-lg);
  letter-spacing: .01em;
}
.wissen-nummer span {
  display: inline-block;
  min-width: 1.6em;
  margin-right: .35em;
  padding: 0 .3em;
  border-radius: 5px;
  background: var(--flaeche-hoch);
  color: var(--petrol-tief);
  text-align: center;
}
.wissen-text { margin: 0 0 .35rem; font-size: var(--t-sm); }
.wissen-mass { margin: 0; font-size: var(--t-xs); color: var(--ink-still); }

/* Die Verbandskoepfe ueber der Tabelle. */
.wissen-verbaende {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  margin: 1.5rem 0;
}
.wissen-verband {
  background: var(--flaeche-panel);
  border: 1px solid var(--linie);
  border-radius: 10px;
  padding: .9rem 1rem;
}
.wissen-verband h2 { margin: 0 0 .35rem; font-size: var(--t-lg); }
.wissen-geltung { margin: 0 0 .4rem; font-size: var(--t-sm); }
.wissen-fassung { margin: 0; font-size: var(--t-xs); color: var(--ink-still); }

/* Die Tabelle scrollt waagerecht statt umzubrechen: Auf einem Telefon
   sind sechs Verbaende nebeneinander sonst unlesbar, und eine Tabelle,
   die umbricht, verliert die Zuordnung Zeile-Spalte. */
.wissen-tabellenrahmen { overflow-x: auto; margin: 1rem 0 1.5rem; }

.wissen-tabelle {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  font-size: var(--t-sm);
}
.wissen-tabelle caption {
  caption-side: bottom;
  padding-top: .6rem;
  font-size: var(--t-xs);
  color: var(--ink-still);
  text-align: left;
}
.wissen-tabelle th, .wissen-tabelle td {
  border: 1px solid var(--linie);
  padding: .5rem .65rem;
  text-align: left;
  vertical-align: top;
}
.wissen-tabelle thead th {
  background: var(--flaeche-hoch);
  font-family: var(--schrift-marke);
  font-size: var(--t-md);
}
.wissen-tabelle tbody th { font-weight: 600; color: var(--ink-leise); }

/* Die abweichenden Zeilen sind der Grund, warum jemand die Seite
   aufruft. Farbe UND ein Zeichen davor -- Farbe allein waere fuer
   einen Teil der Leser gar keine Hervorhebung. */
.wissen-tabelle tr.wissen-anders { background: var(--gold-hell); }
.wissen-tabelle tr.wissen-anders th[scope="row"]::before {
  content: "\2260\00a0";
  color: var(--gold);
  font-weight: 700;
}

.wissen-quellen { font-size: var(--t-xs); word-break: break-all; }
.wissen-quellen a { color: var(--petrol); }

/* Der Vergleicher: eine Liste von Links, kein Skript noetig. */
.wissen-vergleicher {
  margin-top: 2.2rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--linie);
}
.wissen-vergleicher h2 { margin-top: 0; }
.wissen-paarungen {
  list-style: none;
  margin: .8rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.wissen-paarung {
  display: inline-block;
  padding: .35rem .7rem;
  border: 1px solid var(--linie-stark);
  border-radius: 999px;
  font-size: var(--t-sm);
  text-decoration: none;
  color: var(--ink-leise);
}
.wissen-paarung:hover, .wissen-paarung:focus-visible {
  border-color: var(--petrol);
  color: var(--petrol-tief);
}
.wissen-paarung.jetzt {
  background: var(--petrol);
  border-color: var(--petrol);
  color: var(--auf-petrol);
}

.wissen-weiter, .wissen-angebot {
  margin-top: 2.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--linie);
}
.wissen-weiter ul { padding-left: 1.1rem; }
.wissen-weiter a { color: var(--petrol); }

/* Was ein Verband wirklich anders macht, und wo er sich widerspricht. */
.wissen-abweichungen { margin: .4rem 0 0; padding-left: 1.05rem; font-size: var(--t-sm); }
.wissen-abweichungen li { margin-bottom: .35rem; }
.wissen-verband h3 { margin: 0 0 .3rem; font-size: var(--t-md); }


/* --- Die Konzeptseiten (R150, 30.09.2026) --------------------------
   „mesh concept flag football", „inside zone erklaert" -- wonach ein
   Trainer im dritten Jahr sucht. 24 Konzepte, gruppiert nach
   Spielform, jedes gezeichnet.

   `max-width` UEBER `.wissen-bild svg` (150px): Dort steht EIN Pfeil,
   hier eine ganze Aufstellung mit bis zu elf Figuren. Bei 150px
   klebten die Rollenbuchstaben aufeinander. */
.wissen-spielform { margin: 2rem 0; }
.wissen-spielform > h2 { margin-bottom: .8rem; }

.wissen-konzepte {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  list-style: none;
  padding: 0;
  margin: 0;
}
.wissen-konzept {
  background: var(--flaeche-hoch);
  border: 1px solid var(--linie);
  border-radius: var(--r2);
  padding: .8rem;
}
/* Das ganze Bild ist der Link, nicht nur der Name: Auf einem
   Handybildschirm ist eine Zeile Text ein zu kleines Ziel. */
.wissen-konzept > a { text-decoration: none; color: inherit; display: block; }
.wissen-konzept .wissen-bild svg { max-width: 100%; }
.wissen-konzeptname {
  margin: .6rem 0 .3rem;
  font-family: var(--schrift-marke);
  font-size: var(--t-md);
  color: var(--petrol);
}
.wissen-konzept > a:hover .wissen-konzeptname { text-decoration: underline; }

/* Auf der Einzelseite darf das Bild so gross werden, wie der Platz
   hergibt -- es ist der Grund, warum jemand die Seite geoeffnet hat. */
.wissen-bild-gross { padding: 1rem; margin: 1rem 0; }
.wissen-bild-gross svg { max-width: 34rem; }

.wissen-oben { margin: 0 0 .6rem; font-size: var(--t-sm); }
.wissen-oben a { color: var(--petrol); }

.wissen-nachbarn { padding-left: 1.1rem; }
.wissen-nachbarn a { color: var(--petrol); }
.wissen-nachbarn li { margin-bottom: .3rem; }
.wissen-nachbarn .wissen-mass { display: inline; margin-left: .4rem; }

/* Die Jahreszahlung unter dem Monatspreis (30.09.2026).

   Kleiner als die Monatszahl und nicht daneben: Der Monatspreis ist
   die Zahl, mit der verglichen wird. Die Jahreszahlung ist ein
   Angebot an den, der ohnehin einen Haushalt plant -- sie soll
   auffindbar sein, nicht laut. Bis hierher stand sie nur im
   Checkout. */
.preisjahr {
  margin: -.4rem 0 .9rem;
  font-size: var(--t-sm);
  color: var(--petrol);
}
