/* Der Verwaltungsbereich: ein Stil für alle Seiten.
 *
 * # Warum diese Datei existiert
 *
 * Weil es sie nicht gab. Am 09.09.2026 lagen rund 850 Zeilen Stil inline in zwölf
 * Seiten, jede mit ihrer eigenen Kopie. Das ist die Ursache der ersten Beanstandung
 * („die Menüs bei MVP-Wahl sehen anders aus als bei den anderen"): es gab keine Stelle,
 * an der man es einmal richtig macht. Wer eine Seite anfasste, änderte eine von zwölf
 * Wahrheiten.
 *
 * # Für wen das hier gebaut ist
 *
 * Nicht für den Entwickler. Der Auftraggeber am 09.09.2026: „Der Rest wird
 * perspektivisch nicht von mir betreut (sondern von Leuten in Redaktion, Verein) die
 * evtl. nicht so viel Ahnung von Technik haben."
 *
 * Damit ist die frühere Vorgabe „ich will es ganz simpel haben weil es ein admin
 * interface ist" (02.09.2026) aufgehoben — sie gilt nur noch für `/db`, und `/db` wird
 * nicht angefasst. Hier darf es aussehen wie ein Werkzeug, mit dem man arbeiten mag.
 *
 * Praktische Folgen, die über Geschmack hinausgehen:
 *   * Jede Handlung sagt, was sie tut, nicht wie sie umgesetzt ist.
 *   * Was nicht zurückholbar ist, sieht anders aus als der Rest (`.gefahr`).
 *   * Zahlenspalten stehen untereinander (`font-variant-numeric: tabular-nums`),
 *     sonst wandert das Komma und man vergleicht Unvergleichbares.
 *
 * # Zwei harte Grenzen
 *
 * **Keine Schrift von außen, und auch keine selbst gehostete.** Caddy setzt auf diese
 * Seiten `default-src 'none'` und nennt `font-src` nicht — damit ist jede
 * Schriftdatei verboten, auch eine von der eigenen Maschine. Es bleibt der
 * Systemschriftstapel, und das ist kein Verzicht: er ist auf jedem Gerät schon geladen,
 * sieht nach dem Betriebssystem aus und kostet keinen Abruf.
 *
 * **Keine Icon-Bibliothek.** Dieselbe Regel. Die Symbole stehen deshalb als SVG
 * unmittelbar in der Seite, siehe `.sym`. Vorteil davon: sie erben die Textfarbe und
 * skalieren mit der Schriftgröße.
 *
 * # Kein Dunkelmodus
 *
 * Wie in der App (#46) und aus demselben Grund: zwei Farbwelten sind zwei Fassungen,
 * die auseinanderlaufen, und eine Verwaltungsseite wird bei Tageslicht in einer
 * Geschäftsstelle bedient. Die Farben stehen fest.
 */

/* ---------------------------------------------------------------- Bezeichner
 *
 * Die Vereinsfarben sind wörtlich die der App (`BrandColor.swift`), damit Verwaltung
 * und App eine Identität haben und nicht zwei. Die Neutraltöne sind **nicht** graue
 * Grautöne, sondern leicht ins Navy gezogen: ein reines Mittelgrau sieht neben dem
 * Vereinsblau aus wie ein Versehen.
 */
:root {
  --navy:        #17255A;
  --navy-tief:   #0A1230;
  --navy-hell:   #243A7A;
  --tinte:       #02051A;
  --gold:        #F8BF00;
  --gold-tief:   #C89A00;

  --grund:       #F4F6FA;
  --flaeche:     #FFFFFF;
  --flaeche-ruhig: #F8FAFC;
  --linie:       #E2E7F0;
  --linie-stark: #C9D2E3;
  --text:        #141A2E;
  --text-leise:  #5A6478;
  --text-still:  #8B93A6;

  --gut:         #147A4B;
  --gut-grund:   #E8F6EE;
  --warn:        #8A5A00;
  --warn-grund:  #FFF6E0;
  --schlecht:    #A31621;
  --schlecht-grund: #FDECEE;

  --r-klein:  8px;
  --r:       12px;
  --r-gross: 16px;
  --r-pille: 999px;

  --schatten-1: 0 1px 2px rgba(20, 26, 46, .06), 0 1px 1px rgba(20, 26, 46, .04);
  --schatten-2: 0 4px 16px rgba(20, 26, 46, .08), 0 1px 3px rgba(20, 26, 46, .05);
  --schatten-3: 0 12px 32px rgba(20, 26, 46, .12), 0 2px 6px rgba(20, 26, 46, .06);

  --schrift: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
             Arial, sans-serif;
  --schrift-zahl: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

  /* 1320 und nicht 1200: die Kontenliste hat sieben Spalten, und bei 1200 fiel der
     Knopf „Löschen" aus dem Bild — gemessen am 09.09.2026. Auf einem MacBook (1440
     logische Punkte) passt jetzt alles ohne Rollen, auf einem kleineren rollt die
     Tabelle, und nur sie. */
  --breite: 1320px;
}

* { box-sizing: border-box; }

/* ---------------------------------------------------------------- hidden gewinnt
 *
 * `[hidden]` setzt im Browser `display: none` — aber nur mit der Spezifitaet eines
 * Attributs. Jede Klasse mit eigenem `display` schlaegt es, und in dieser Datei haben
 * `.meldung` (flex), `.feld` (grid) und `.karte` eins. Also stand die Warnung
 * „Testbauten sind derzeit mitgesperrt" auf `/version` sichtbar da, obwohl sie
 * `hidden` trug, und dasselbe galt fuer das Punktefeld der Helferbuchung auf `/konten`.
 * Gemessen am 09.09.2026 am Bildschirmfoto.
 *
 * Das `!important` ist hier richtig und nicht faul: `hidden` ist eine Aussage ueber
 * das Element und keine Formatierung, die sich abwaegen liesse. Wer etwas mit `hidden`
 * versteckt, will es versteckt haben, egal was sonst gilt.
 */
[hidden] { display: none !important; }

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

body {
  margin: 0;
  background: var(--grund);
  color: var(--text);
  font: 16px/1.55 var(--schrift);
  /* Ohne das rendert Safari die Schrift schwerer als Chrome, und die Seite sieht auf
     zwei Rechnern verschieden aus. */
  -webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------- Kopf
 *
 * Das dunkle Band ist kein Schmuck und war es nie: beide Logos gibt es nur als weiße
 * Dateien (`vfb_logo_weiss.png`, `DEKRA_1Liga_Frauen_RGB_weiss.png`), farbige liefert
 * volleyball-suhl.de nicht — geprüfte 404 am 02.09.2026. Auf weißem Grund wären sie
 * unsichtbar. Ein Band ist eine Entscheidung, ein unsichtbares Logo ein Fehler.
 */
.kopf {
  background: linear-gradient(180deg, var(--navy) 0%, var(--navy-tief) 100%);
  color: #fff;
  padding: 0 20px;
  position: sticky;
  top: 0;
  z-index: 20;
  box-shadow: var(--schatten-2);
}

.kopf-innen {
  max-width: var(--breite);
  margin: 0 auto;
  min-height: 68px;
  display: flex;
  align-items: center;
  gap: 24px;
}

.kopf img { height: 30px; width: auto; display: block; }
.kopf img.hochkant { height: 44px; }

.kopf-logos { display: flex; align-items: center; gap: 16px; }

/* Der Weg zurück. Ein Pfeil allein ist auf einer Verwaltungsseite zu wenig: wer hier
   arbeitet, soll lesen können, wohin er kommt. */
.zurueck {
  color: rgba(255, 255, 255, .82);
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px 7px 9px;
  border-radius: var(--r-pille);
  border: 1px solid rgba(255, 255, 255, .22);
  white-space: nowrap;
}
.zurueck:hover { background: rgba(255, 255, 255, .12); color: #fff; }

.kopf-titel {
  margin-left: auto;
  text-align: right;
  min-width: 0;
}
.kopf-titel b { display: block; font-size: 15px; font-weight: 600; }
.kopf-titel span {
  display: block;
  font-size: 12.5px;
  color: rgba(255, 255, 255, .68);
}

/* Wer angemeldet ist, ganz rechts im Band.
 *
 * Seit dem 19.09.2026 hat jeder seinen eigenen Zugang; auf einem geteilten Rechner in
 * der Geschäftsstelle muss ablesbar sein, unter wessen Namen gerade gearbeitet wird.
 * Der Block hängt sich hinter `.kopf-titel`, dessen `margin-left: auto` den Titel nach
 * rechts drückt — deshalb steht hier eine Trennlinie statt eines weiteren `auto`.
 *
 * Auf schmalen Geräten fällt der Name weg und nur der Knopf bleibt: das Band hat dort
 * keinen Platz für drei Textblöcke, und der Weg hinaus ist der wichtigere von beiden. */
.kopf-konto {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-left: 18px;
  border-left: 1px solid rgba(255, 255, 255, .18);
}
.kopf-konto-name { text-align: right; min-width: 0; }
.kopf-konto-name b { display: block; font-size: 13.5px; font-weight: 600; }
.kopf-konto-name span {
  display: block;
  font-size: 11.5px;
  color: rgba(255, 255, 255, .62);
}
.kopf-abmelden {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 11px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: rgba(255, 255, 255, .86);
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .22);
  border-radius: var(--r-klein);
  cursor: pointer;
}
.kopf-abmelden:hover { background: rgba(255, 255, 255, .16); color: #fff; }
.kopf-abmelden:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.kopf-abmelden .sym { width: 16px; height: 16px; }
/* ---------------------------------------------------------------- Das Band am Telefon
 *
 * **Auf dem Telefon bleiben nur drei Dinge: der Weg zurück, die Logos, der Weg hinaus.**
 *
 * So bestellt am 20.09.2026: „im mobile die headings in der menü leiste (beispiel
 * 'Spieltag, Was bereit ist, und was nicht') entfernen. Nur < Menü (VfB Logo) (DEKRA
 * Logo) Abmelden. Mehr nicht, der Text macht einen break und sieht auf mobile nicht
 * gut aus."
 *
 * Gemessen war es schlimmer als unschön: bei 390 Pixeln brach „Was bereit ist, und was
 * nicht" auf fünf Zeilen um, schob das Band auf 230 Pixel Höhe und schob den Knopf
 * „Abmelden" unter den Titel — zwei Bedienelemente übereinander, beide halb verdeckt.
 *
 * **Weggenommen wird nichts, was man nur hier findet.** Der Titel steht auf jeder Seite
 * noch einmal als Überschrift, und wer angemeldet ist, steht auf der Menüseite unter
 * „Angemeldet als …". Auf einem Telefon gibt es auch keinen geteilten Rechner, dessen
 * wegen der Name im Band steht — das ist der Bildschirm in der Geschäftsstelle.
 *
 * **Über CSS und nicht im JavaScript.** Sonst hinge die Darstellung an der Breite im
 * Augenblick des Ladens und bliebe beim Drehen des Geräts stehen.
 */
@media (max-width: 720px) {
  .kopf { padding: 0 12px; }
  .kopf-innen { gap: 12px; min-height: 58px; }
  .kopf-titel { display: none; }
  .kopf-konto-name { display: none; }
  /* Ohne den Titel fehlt das `margin-left: auto`, das den rechten Block bisher an den
     Rand geschoben hat. Es zieht hierher um, sonst klebt „Abmelden" an den Logos. */
  .kopf-konto { margin-left: auto; padding-left: 0; border-left: 0; }
  .kopf img { height: 26px; }
  .kopf img.hochkant { height: 36px; }
  .kopf-logos { gap: 12px; }
}

/* Noch schmaler (iPhone SE, 320 px): die Beschriftungen schrumpfen mit, statt dass
   etwas herausfällt. Gemessen passt die Reihe dann in 296 Pixel. */
@media (max-width: 400px) {
  .kopf-innen { gap: 8px; }
  .zurueck { font-size: 13px; padding: 6px 10px 6px 8px; }
  .kopf-abmelden { font-size: 12.5px; padding: 6px 9px; }
  .kopf-logos { gap: 9px; }
}

/* Und der Rumpf darunter: 20 Pixel Rand sind auf einem 390 Pixel breiten Schirm ein
   Zehntel der Seite. Zwölf reichen, und die Karten werden dadurch lesbar breiter. */
@media (max-width: 560px) {
  main { padding: 18px 12px 56px; }
}

/* ---------------------------------------------------------------- Rumpf */
main {
  max-width: var(--breite);
  margin: 0 auto;
  padding: 26px 20px 72px;
}

/* Der Seitenkopf: Kicker, Titel, ein Satz dazu. Der Satz ist nicht Zierde — er sagt
   jemandem, der die Seite zum ersten Mal öffnet, wofür sie da ist. */
.seitenkopf { margin: 0 0 22px; }
.seitenkopf .kicker {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--navy-hell);
  margin: 0 0 6px;
}
.seitenkopf h1 {
  margin: 0;
  font-size: 27px;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--tinte);
}
.seitenkopf p {
  margin: 8px 0 0;
  color: var(--text-leise);
  max-width: 62ch;
}

/* ---------------------------------------------------------------- Zwei Spalten
 *
 * Links die Funktionen, rechts die Daten. So bestellt am 08.09.2026: „links sollen die
 * Funktionen stehen und rechts die Daten/Protokolle/Tabellen".
 *
 * Der Grund dahinter trägt über den Wunsch hinaus: eine Handlung und ihre Wirkung
 * gehören ins selbe Bild. Wer unten etwas einträgt und oben nachsehen muss, ob es
 * gewirkt hat, scrollt zwischen Ursache und Folge hin und her — und genau dabei
 * passieren die Fehler.
 *
 * Unter 1000 Pixeln wird daraus eine Spalte: die Funktionen zuerst, weil man deswegen
 * gekommen ist.
 */
.zweispaltig {
  display: grid;
  grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
  gap: 22px;
  align-items: start;
}
@media (max-width: 1000px) {
  .zweispaltig { grid-template-columns: 1fr; }
}

/* Die linke Spalte bleibt beim Rollen stehen, solange sie hineinpasst. Rechts liegen
   die langen Tabellen; die Funktionen dazu sollen nicht davonlaufen. */
.spalte-links { position: sticky; top: 86px; display: grid; gap: 16px; }
@media (max-width: 1000px) {
  .spalte-links { position: static; }
}
.spalte-rechts { display: grid; gap: 16px; min-width: 0; }

/* ---------------------------------------------------------------- Karten */
.karte {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--r-gross);
  box-shadow: var(--schatten-1);
  overflow: hidden;
}
.karte > .karte-kopf {
  padding: 15px 18px 13px;
  border-bottom: 1px solid var(--linie);
  background: var(--flaeche-ruhig);
  display: flex;
  align-items: center;
  gap: 10px;
}
.karte-kopf h2 {
  margin: 0;
  font-size: 15.5px;
  font-weight: 650;
  letter-spacing: -.005em;
}
.karte-kopf .zahl {
  margin-left: auto;
  font: 600 12.5px/1 var(--schrift);
  color: var(--text-leise);
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--r-pille);
  padding: 5px 10px;
  font-variant-numeric: tabular-nums;
}
.karte > .karte-rumpf { padding: 18px; }
.karte > .karte-rumpf > :first-child { margin-top: 0; }
.karte > .karte-rumpf > :last-child { margin-bottom: 0; }

/* Eine Karte, die eine Gefahr trägt. Rot am Rand und nicht als Fläche: eine rote
   Fläche schreit, und eine Seite, auf der alles schreit, wird überlesen. */
.karte.gefahr { border-color: #EFC7CC; }
.karte.gefahr > .karte-kopf {
  background: var(--schlecht-grund);
  border-bottom-color: #EFC7CC;
}
.karte.gefahr .karte-kopf h2 { color: var(--schlecht); }

/* ---------------------------------------------------------------- Knöpfe */
/* **Jeder Knopf hat einen Rahmen.**
 *
 * Hier stand `border: 1px solid transparent`, und die Grundform war damit unsichtbar:
 * ein Knopf ohne Variante sah aus wie ein Wort im Text. Gemeldet am 18.09.2026
 * („Buttons sind nicht voll umrandet"). Die gefuellten Varianten setzen den Rahmen
 * auf ihre eigene Farbe, damit alle Knoepfe dieselbe Silhouette haben und nebeneinander
 * gleich gross sind. */
.knopf {
  appearance: none;
  font: 600 14.5px/1 var(--schrift);
  background: var(--flaeche);
  color: var(--navy);
  border: 1px solid var(--linie-stark);
  border-radius: var(--r-klein);
  padding: 11px 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.knopf:hover:not(:disabled) { background: var(--flaeche-ruhig); border-color: var(--navy); }
.knopf:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.knopf:disabled { opacity: .5; cursor: not-allowed; }

/* Genau ein Hauptknopf je Bereich. Zwei gleich starke Knöpfe nebeneinander sind keine
   Wahl, sondern eine Ratlosigkeit. */
.knopf-haupt {
  background: var(--navy); color: #fff;
  border-color: var(--navy); box-shadow: var(--schatten-1);
}
.knopf-haupt:hover:not(:disabled) { background: var(--navy-hell); }

.knopf-zweit {
  background: var(--flaeche);
  color: var(--navy);
  border-color: var(--linie-stark);
}
.knopf-zweit:hover:not(:disabled) { background: var(--flaeche-ruhig); }

.knopf-gefahr { background: var(--schlecht); color: #fff; border-color: var(--schlecht); }
.knopf-gefahr:hover:not(:disabled) { background: #8A121B; }

/* Der leise Knopf bleibt leise — aber er bleibt ein Knopf: heller Rahmen statt gar
   keinem. */
.knopf-still {
  background: transparent;
  color: var(--text-leise);
  border-color: var(--linie);
  padding: 8px 10px;
}
.knopf-still:hover:not(:disabled) { background: var(--flaeche-ruhig); color: var(--text); }

.knopf-klein { font-size: 13.5px; padding: 8px 12px; }
.knopf-breit { width: 100%; }

.knopfreihe { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }

/* ---------------------------------------------------------------- Felder */
.feld { display: grid; gap: 6px; margin: 0 0 14px; }
.feld > label,
.feld-marke {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-leise);
}
/* `input:not([type])` steht hier nicht aus Ordnungsliebe.
 *
 * Die Seiten bauen ihre Felder mit `document.createElement('input')` und setzen `type`
 * meist nicht — ein solches Feld verhaelt sich wie `type="text"`, aber das ATTRIBUT
 * fehlt, und damit greift `[type="text"]` nicht. Die Folge waren nackte Systemkaesten
 * mitten in gestalteten Karten: gemeldet am 09.09.2026 fuer die Felder des Testtickers
 * und die Rechenaufgabe der Live Activity.
 *
 * Die Alternative waere, in jeder JS-Datei ein `type` nachzutragen. Das behebt die
 * heutigen Stellen und nicht die naechste. */
.feld input:not([type]),
.feld input[type="text"],
.feld input[type="number"],
.feld input[type="url"],
.feld input[type="date"],
.feld input[type="datetime-local"],
.feld input[type="email"],
.feld input[type="password"],
.feld input[type="search"],
.feld select,
.feld textarea {
  font: 15px/1.45 var(--schrift);
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--r-klein);
  padding: 10px 12px;
  width: 100%;
}
.feld textarea { resize: vertical; min-height: 96px; }
.feld input:focus, .feld select:focus, .feld textarea:focus {
  outline: none;
  border-color: var(--navy-hell);
  box-shadow: 0 0 0 3px rgba(36, 58, 122, .15);
}
.feld .hinweis { font-size: 13px; color: var(--text-still); }

/* Zahlen und Kennungen in der Zahlenschrift: eine Kennung wie VFB-7K4Q-26 liest man
   zeichenweise, und dafür müssen die Zeichen gleich breit sein. */
.feld input.zahl, .feld input.kennung { font-family: var(--schrift-zahl); }

/* Ein Schalter. Die ganze Zeile ist anfassbar, nicht nur das Kästchen — am
   Schreibtisch ist das bequem, am Tablet ist es der Unterschied zwischen Treffen und
   Danebentippen. */
.schalter {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 11px 13px;
  border: 1px solid var(--linie);
  border-radius: var(--r-klein);
  background: var(--flaeche-ruhig);
  cursor: pointer;
  margin: 0 0 10px;
}
.schalter:hover { border-color: var(--linie-stark); }
.schalter input { margin: 2px 0 0; width: 18px; height: 18px; accent-color: var(--navy); }
.schalter b { display: block; font-size: 14.5px; font-weight: 600; }
.schalter span { display: block; font-size: 13px; color: var(--text-leise); }

/* ---------------------------------------------------------------- Tabellen
 *
 * Jede Tabelle steht in einer `.tabellenrolle` und hat eine Mindestbreite. Ohne die
 * presst der Browser die Spalten zusammen, bis Wörter umbrechen — gemessen am
 * 09.09.2026: in der Kontenliste stand vom Knopf „Löschen" nur noch das L, und die
 * Namen brachen zweizeilig. Waagerecht rollen ist die richtige Antwort darauf: der
 * Seitenrumpf bleibt ruhig, und wer die letzte Spalte braucht, schiebt sie sich her.
 */
.tabellenrolle {
  overflow-x: auto;
  /* Ohne das schneidet die Rolle den Fokusrahmen eines Knopfes in der letzten Spalte
     ab. Zwei Pixel Luft, und er ist ganz zu sehen. */
  padding-bottom: 2px;

  /* **Ein Schatten am Rand, wo es weitergeht.**
   *
   * Auf einem Telefon gibt es keine Rollbalken: die Tabelle endet am Bildschirmrand,
   * und nichts sagt, dass rechts noch drei Spalten stehen. Gesehen am 20.09.2026 auf
   * /checkin — die vierte Spalte war angeschnitten und sah aus wie ein Darstellungs-
   * fehler.
   *
   * Der Kniff ist alt und braucht kein JavaScript: vier Verläufe im Hintergrund, zwei
   * davon am Inhalt festgemacht (`local`) und zwei am Kasten (`scroll`). Wo der Inhalt
   * am Anfang steht, deckt der weisse Verlauf den Schatten zu; sobald gerollt wird,
   * wandert er weg und der Schatten kommt zum Vorschein. */
  background:
    linear-gradient(to right, var(--flaeche) 30%, rgba(255, 255, 255, 0)) left center,
    linear-gradient(to left, var(--flaeche) 30%, rgba(255, 255, 255, 0)) right center,
    linear-gradient(to right, rgba(20, 26, 46, .13), rgba(255, 255, 255, 0) 60%) left center,
    linear-gradient(to left, rgba(20, 26, 46, .13), rgba(255, 255, 255, 0) 60%) right center;
  background-repeat: no-repeat;
  background-size: 34px 100%, 34px 100%, 16px 100%, 16px 100%;
  background-attachment: local, local, scroll, scroll;
}
table.liste, table.protokoll { min-width: 680px; }
table.liste {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
table.liste th {
  text-align: left;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--text-still);
  padding: 10px 12px;
  border-bottom: 1px solid var(--linie);
  background: var(--flaeche-ruhig);
  position: sticky;
  top: 0;
  white-space: nowrap;
}
table.liste td {
  padding: 11px 12px;
  border-bottom: 1px solid var(--linie);
  /* Mittig und nicht oben: in einer Zeile stehen Zahlen, Haken und Knöpfe
     nebeneinander, und die haben verschiedene Höhen. Oben ausgerichtet hängt der
     Haken über der Zahl. */
  vertical-align: middle;
}
table.liste tr:last-child td { border-bottom: 0; }
table.liste tbody tr:hover td { background: var(--flaeche-ruhig); }
table.liste td.zahl, table.liste th.zahl {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
table.liste td.kennung { font-family: var(--schrift-zahl); font-size: 13px; }
/* Eine Zeile, die Aufmerksamkeit braucht. Ein Streifen links und kein Farbteppich:
   man soll sie finden, ohne dass die Tabelle unlesbar wird. */
table.liste tr.auffaellig td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

/* ---------------------------------------------------------------- Marken */
.marke {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: 600 12px/1 var(--schrift);
  padding: 5px 9px;
  border-radius: var(--r-pille);
  white-space: nowrap;
}
.marke-gut      { background: var(--gut-grund);      color: var(--gut); }
.marke-warn     { background: var(--warn-grund);     color: var(--warn); }
.marke-schlecht { background: var(--schlecht-grund);  color: var(--schlecht); }
.marke-still    { background: var(--flaeche-ruhig);   color: var(--text-leise);
                  border: 1px solid var(--linie); }
.marke-navy     { background: rgba(36, 58, 122, .1);  color: var(--navy); }

/* ------------------------------------------------- Suche nach einer Kontonummer
 *
 * `VFB-` [Feld] `-26`. Die festen Teile stehen als Text im selben Rahmen wie das Feld,
 * damit es nach **einer** Eingabe aussieht und nicht nach dreien. Bestellt am
 * 01.10.2026 fuer den Heimspieltag: ein Fan zeigt seine Nummer, und es muss sich in
 * Sekunden nachsehen lassen, ob er angefordert hat.
 *
 * Das Jahr rechts ist Anzeige und kein Filter; der Grund steht in `autogramme.js`.
 */
.suchzeile {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 14px;
}
.suchlabel {
  font: 600 13px/1 var(--schrift);
  color: var(--text-leise);
}
.kontofeld {
  display: inline-flex;
  align-items: center;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--r-klein);
  padding: 0 10px;
}
.kontofeld:focus-within {
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(36, 58, 122, .12);
}
/* Die festen Teile sind Beschriftung und kein Inhalt: leiser, und nicht markierbar,
 * damit ein Doppelklick ins Feld die vier Zeichen erwischt und nicht das VFB. */
.kontofeld .fest {
  font: 600 15px/1 var(--schrift-zahl);
  color: var(--text-leise);
  user-select: none;
  padding: 10px 0;
}
.kontofeld .mitte {
  font: 700 15px/1 var(--schrift-zahl);
  letter-spacing: .12em;
  text-transform: uppercase;
  width: 5.5em;
  border: 0;
  outline: 0;
  background: none;
  color: var(--text);
  padding: 10px 2px;
}
.kontofeld .mitte::placeholder { color: var(--linie-stark); letter-spacing: .12em; }
/* **Nur ein Fokusring, nicht zwei.** Die allgemeine Regel fuer Eingabefelder legt jedem
 * `input` im Fokus einen Schein an. Hier zeichnet ihn schon der Kasten (`:focus-within`),
 * und beide zusammen ergaben einen Rahmen im Rahmen. Im Bild gesehen, am 01.10.2026. */
.kontofeld .mitte:focus { box-shadow: none; }

/* ------------------------------------------------- Chip: ein Filter zum Umlegen
 *
 * Ein Schalter ueber einer Liste, der einen Teil davon ein- und ausblendet. Zuerst
 * gebraucht am 30.09.2026 fuer die stornierten Autogrammkarten.
 *
 * Er sieht aus wie eine `.marke` und ist doch etwas anderes: eine Marke sagt einen
 * Zustand an, ein Chip aendert einen. Deshalb ein eigener Name, ein `button` im
 * Quelltext und ein sichtbarer Fokusrahmen.
 */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: 600 12px/1 var(--schrift);
  padding: 7px 12px;
  margin: 0 0 12px;
  border-radius: var(--r-pille);
  white-space: nowrap;
  cursor: pointer;
  background: var(--flaeche-ruhig);
  color: var(--text-leise);
  border: 1px solid var(--linie);
}
.chip:hover { border-color: var(--linie-stark); color: var(--text); }
.chip-an {
  background: rgba(36, 58, 122, .1);
  color: var(--navy);
  border-color: var(--navy-hell);
}

/* ------------------------------------------------- Zustaende der Autogramme
 *
 * Fuenf Zustaende, fuenf Farben, am 23.09.2026 so bestellt: offen grau,
 * unterschrieben blau, abgeholt gruen, nicht abgeholt rot, storniert orange.
 *
 * **Die Klassen heissen nach dem Zustand und nicht nach der Farbe.** Wer spaeter
 * entscheidet, dass storniert doch grau sein soll, aendert eine Zeile hier statt der
 * Stelle im Skript, die die Marke baut. Und im Skript steht dann weiterhin, was gemeint
 * ist, nicht wie es aussieht.
 *
 * Gebaut auf den vorhandenen Marken, damit die Seite aussieht wie jede andere:
 * dieselben Groessen, dieselben Rundungen, dieselben Farbtoken. */
.zustand-offen          { background: var(--flaeche-ruhig); color: var(--text-leise);
                          border: 1px solid var(--linie); }
.zustand-unterschrieben { background: rgba(36, 58, 122, .1); color: var(--navy); }
.zustand-abgeholt       { background: var(--gut-grund); color: var(--gut); }
.zustand-nicht_abgeholt { background: var(--schlecht-grund); color: var(--schlecht); }
.zustand-storniert      { background: var(--warn-grund); color: var(--warn); }

/* Derselbe Farbcode noch einmal als Streifen am Zeilenanfang. **Zweimal und nicht
 * einmal**: die Marke steht in der vierten Spalte, und wer eine Liste von vierzig
 * Karten ueberfliegt, sucht am linken Rand. Dieselbe Bauweise wie `tr.auffaellig`. */
table.liste tr.reihe-offen td:first-child          { box-shadow: inset 3px 0 0 var(--linie-stark); }
table.liste tr.reihe-unterschrieben td:first-child { box-shadow: inset 3px 0 0 var(--navy-hell); }
table.liste tr.reihe-abgeholt td:first-child       { box-shadow: inset 3px 0 0 var(--gut); }
table.liste tr.reihe-nicht_abgeholt td:first-child { box-shadow: inset 3px 0 0 var(--schlecht); }
table.liste tr.reihe-storniert td:first-child      { box-shadow: inset 3px 0 0 var(--warn); }

/* Eine stornierte Karte ist keine mehr. Der Name der Spielerin steht durchgestrichen,
 * damit das auch ohne Farbe erkennbar ist — auf einem Ausdruck in Graustufen und fuer
 * alle, die Rot und Gruen nicht unterscheiden. */
table.liste tr.reihe-storniert td:first-child { text-decoration: line-through; }

/* ---------------------------------------------------------------- Meldungen */
.meldung {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 13px 15px;
  border-radius: var(--r);
  font-size: 14.5px;
  margin: 0 0 16px;
  border: 1px solid;
}
.meldung-gut      { background: var(--gut-grund);      border-color: #BFE3CE; color: #0E5C38; }
.meldung-warn     { background: var(--warn-grund);     border-color: #F0DCA8; color: #6B4600; }
.meldung-schlecht { background: var(--schlecht-grund);  border-color: #EFC7CC; color: #7E1119; }
.meldung-still    { background: var(--flaeche-ruhig);   border-color: var(--linie);
                    color: var(--text-leise); }

/* Wenn nichts da ist. Ein leerer Kasten mit einem Satz, der sagt **warum** nichts da
   ist — nicht „keine Daten". Wer „keine Daten" liest, sucht den Fehler bei sich. */
.leer {
  text-align: center;
  padding: 34px 20px;
  color: var(--text-leise);
}
.leer .sym { color: var(--linie-stark); margin: 0 auto 10px; display: block; }
.leer b { display: block; color: var(--text); margin-bottom: 4px; font-size: 15px; }

/* ---------------------------------------------------------------- Symbole
 *
 * Inline SVG, weil die CSP keine Icon-Bibliothek erlaubt (`default-src 'none'`, kein
 * `font-src`). Kein Verlust: sie erben die Textfarbe über `currentColor` und wachsen
 * mit der Schrift, weil die Größe in `em` steht.
 */
.sym {
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}
.sym-gross { width: 1.6em; height: 1.6em; }

/* ---------------------------------------------------------------- Kleinteile */
.still { color: var(--text-leise); }
.leise { font-size: 13px; color: var(--text-still); }
.trenner { height: 1px; background: var(--linie); border: 0; margin: 16px 0; }
.zahlen { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--schrift-zahl); }

/* Der Fuß: wo man ist und was nicht öffentlich ist. */
.fuss {
  max-width: var(--breite);
  margin: 0 auto;
  padding: 0 20px 40px;
  color: var(--text-still);
  font-size: 13px;
}

/* Ein Kennwert, groß. Für Zahlen, die man auf einen Blick will. */
.kennwerte {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
}
.kennwert {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--r);
  padding: 14px 16px;
}
.kennwert b {
  display: block;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--tinte);
}
.kennwert span { font-size: 13px; color: var(--text-leise); }

/* Bewegung nur, wenn sie erwünscht ist. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ================================================================ Die Bausteine,
 * die die Seiten im Browser bauen
 *
 * Der Abschnitt oben beschreibt, was in den HTML-Dateien steht. Alles darunter baut
 * JavaScript zur Laufzeit — eine Adresskarte je Weiterleitung, eine Zeile je Konto,
 * eine Klappkarte je Spielerin.
 *
 * # Warum die Namen hier anders klingen
 *
 * Weil sie älter sind. `.kopfzeile`, `.hinweis`, `.jetzt` standen schon in den zwölf
 * Inline-Kopien und stehen in gut 4000 Zeilen JavaScript. Sie umzubenennen hätte an
 * dieser Datei nichts verbessert und in jeder JS-Datei etwas kaputt machen können.
 * Also stehen sie hier, mit dem neuen Aussehen, und das JavaScript bleibt, wie es ist.
 *
 * # Die eine Regel, die man kennen muss
 *
 * Eine Karte hat von sich aus Innenabstand — das ist der Normalfall, weil die
 * Karten aus dem JavaScript einfach Inhalt enthalten. Eine Karte mit eigenem Kopf und
 * Rumpf (`.karte-kopf` / `.karte-rumpf`) bekommt zusätzlich `.gegliedert`; dann liegt
 * der Abstand in den Teilen und nicht am Rand. Ohne das Wort stünde der Abstand
 * doppelt.
 */

/* ---------------------------------------------------------------- Datenkarten */
.karte { padding: 16px 18px; }
.karte.gegliedert { padding: 0; }

/* Ein Wert, der von der Quelle kommt.
 *
 * Hier stand ein gestrichelter Rand, und er war falsch. Auf der Pflegeseite kommt
 * **jeder** Wert von der Quelle, solange niemand etwas gepflegt hat — zwölf gestrichelte
 * Kästen untereinander sehen aus wie zwölf Baustellen. Gemessen am 09.09.2026 am ersten
 * Bildschirmfoto der neuen Seite.
 *
 * Es bleibt der ruhigere Grund. Den Unterschied sagt ohnehin die Marke rechts oben, und
 * die sagt ihn in Worten. */
.karte.vorgabe { background: var(--flaeche-ruhig); }

/* Eine Angabe, deren Änderung außerhalb der App nachgezogen werden muss. */
.karte.achtung { border-left: 4px solid var(--warn); }

/* Eine Karte, die Aufmerksamkeit braucht (ein aktiver Testschalter, eine Dublette). */
.karte.warnung { border-color: #F0DCA8; background: var(--warn-grund); }

/* Etwas Abgeschaltetes, Storniertes, Gesperrtes. Blass und nicht weg: es soll
   nachweisbar bleiben, dass es da ist. */
.karte.aus { background: var(--flaeche-ruhig); opacity: .72; }

/* Zwei Einträge, die dasselbe meinen. */
.karte.doppelung { border-left: 4px solid var(--schlecht); }

/* Der Kopf einer Datenkarte: Name links, Marke rechts. */
.kopfzeile {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.kopfzeile b { font-size: 15.5px; font-weight: 650; letter-spacing: -.005em; }
.kopfzeile .name { font-size: 15.5px; font-weight: 650; }

/* Ein Satz zur Karte. */
.hinweis { font-size: 13.5px; color: var(--text-leise); margin: 5px 0 10px; }
.hinweis.warnung { color: var(--warn); }
.hinweis-klein { font-size: 13px; color: var(--text-still); }
.hinweis-gross { font-size: 14.5px; color: var(--text-leise); }

/* Der geltende Wert. In der Zahlenschrift, weil hier Adressen und Kennungen stehen,
   die man zeichenweise liest. */
.jetzt {
  font-family: var(--schrift-zahl);
  font-size: 12.5px;
  color: var(--text-leise);
  background: var(--flaeche-ruhig);
  border: 1px solid var(--linie);
  border-radius: var(--r-klein);
  padding: 7px 10px;
  margin: 0 0 11px;
  overflow-wrap: anywhere;
}
.karte.vorgabe .jetzt { background: var(--flaeche); }

/* ---------------------------------------------------------------- Marken, alte Namen
 * `gepflegt` und `eigen` setzt das JavaScript; sie bedeuten dasselbe wie
 * `.marke-gut` und `.marke-navy`.
 *
 * **Die Zustaende der Autogramme sind ausgenommen, seit dem 30.09.2026.** Sie tragen
 * `zustand-…` und kein `marke-…`, fielen damit in diese Auffangregel, und die schlaegt
 * mit `:not([class*=…])` jede einfache Klasse in der Spezifitaet. Die fuenf Farben vom
 * 23.09.2026 standen also in der Datei und haben **nie** auf der Marke gewirkt; sichtbar
 * war allein der Streifen am linken Zeilenrand, der einen anderen Selektor hat. Gefunden
 * am 30.09.2026 beim Nachmessen der berechneten Farben im Browser: alle sechs Marken
 * hatten denselben grauen Grund. Im Quelltext sah beides fuer sich richtig aus.
 */
.marke:not([class*="marke-"]):not([class*="zustand-"]) {
  background: var(--flaeche-ruhig);
  color: var(--text-leise);
  border: 1px solid var(--linie);
}
.marke.gepflegt { background: var(--gut-grund); color: var(--gut); border-color: #BFE3CE; }
.marke.eigen    { background: rgba(36, 58, 122, .1); color: var(--navy); border-color: transparent; }
.marke.warnung  { background: var(--warn-grund); color: var(--warn); border-color: #F0DCA8; }
.marke.gefahr   { background: var(--schlecht-grund); color: var(--schlecht); border-color: #EFC7CC; }

/* ---------------------------------------------------------------- Feldzeilen
 *
 * `.zeile` ist eine waagerechte Reihe aus Feldern und einem Knopf. Die Felder darin
 * tragen keinen unteren Abstand: in einer Reihe sollen sie auf einer Linie enden,
 * und der Abstand kommt von `gap`.
 */
.zeile { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.zeile > .feld { margin: 0; }
.feld.breit { flex: 1 1 22rem; min-width: 0; }
.feld input.zahl { width: 7.5rem; }
.feld input.kurz { width: 9rem; }

/* Felder ohne Klasse gibt es auch — das JavaScript baut sie manchmal roh. Sie sollen
   trotzdem aussehen wie die anderen. */
input:not([type]),
input[type="text"], input[type="number"], input[type="url"], input[type="date"],
input[type="datetime-local"], input[type="email"],
input[type="password"], input[type="search"], select, textarea {
  font: 15px/1.45 var(--schrift);
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--r-klein);
  padding: 10px 12px;
  max-width: 100%;
}
textarea { resize: vertical; }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--navy-hell);
  box-shadow: 0 0 0 3px rgba(36, 58, 122, .15);
}
input.zahl, input.kennung { font-family: var(--schrift-zahl); }
input[type="checkbox"], input[type="radio"] { accent-color: var(--navy); }

/* ---------------------------------------------------------------- Knöpfe ohne Klasse
 *
 * Das JavaScript baut `<button>` und hängt höchstens `gefahr` oder `klein` dran. Der
 * nackte Knopf ist deshalb der **zweite** Knopf: ein Blatt voll starker Knöpfe hat
 * keine Hauptsache mehr. Wo eine Handlung die Hauptsache ist, steht `.knopf-haupt`
 * oder `.stark` in der HTML-Datei.
 */
button {
  appearance: none;
  font: 600 14.5px/1 var(--schrift);
  background: var(--flaeche);
  color: var(--navy);
  border: 1px solid var(--linie-stark);
  border-radius: var(--r-klein);
  padding: 11px 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  white-space: nowrap;
  transition: background-color .12s ease, border-color .12s ease;
}
button:hover:not(:disabled) { background: var(--flaeche-ruhig); }
button:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
button:disabled { opacity: .45; cursor: not-allowed; }

button.stark { background: var(--navy); color: #fff; border-color: transparent; }
button.stark:hover:not(:disabled) { background: var(--navy-hell); }

button.gefahr { background: var(--flaeche); color: var(--schlecht); border-color: #EFC7CC; }
button.gefahr:hover:not(:disabled) { background: var(--schlecht-grund); }

button.klein, .knopf.klein { font-size: 13.5px; padding: 8px 12px; }

/* ---------------------------------------------------------------- Meldungen, alte Namen */
.meldung.gut      { background: var(--gut-grund);       border-color: #BFE3CE; color: #0E5C38; }
.meldung.schlecht { background: var(--schlecht-grund);  border-color: #EFC7CC; color: #7E1119; }
.meldung.warnung  { background: var(--warn-grund);      border-color: #F0DCA8; color: #6B4600; }
/* Leer heißt weg. Das JavaScript leert den Text, statt das Element zu entfernen — ohne
   diese Zeile bliebe ein leerer farbiger Streifen stehen. */
.meldung:empty { display: none; }
.meldung:not(.gut):not(.schlecht):not(.warnung):not([class*="meldung-"]) {
  background: var(--flaeche-ruhig);
  border-color: var(--linie);
  color: var(--text-leise);
}

/* ---------------------------------------------------------------- Protokolltabellen
 * `table.protokoll` ist der alte Name für `table.liste`; beide sehen gleich aus.
 */
table.protokoll {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
table.protokoll th {
  text-align: left;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--text-still);
  padding: 10px 12px;
  border-bottom: 1px solid var(--linie);
  background: var(--flaeche-ruhig);
  white-space: nowrap;
}
table.protokoll td {
  padding: 11px 12px;
  border-bottom: 1px solid var(--linie);
  vertical-align: top;
}
table.protokoll tr:last-child td { border-bottom: 0; }
table.protokoll tbody tr:hover td { background: var(--flaeche-ruhig); }
table.protokoll td.wann, table.liste td.wann {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  color: var(--text-leise);
}
td.kennung, .kennung {
  font-family: var(--schrift-zahl);
  font-size: 12.5px;
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------- Blättern */
.blaettern {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--linie);
}
.blaettern:empty { display: none; }
.blaettern .blatt-stand {
  flex: 1 1 auto;
  text-align: center;
  font-size: 13px;
  color: var(--text-leise);
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- Klappkarten
 *
 * Eine Person, eine Regel, eine Prämie. Aufklappbar, weil neun Felder mal dreizehn
 * Spielerinnen eine Seite ergeben, die niemand überblickt — zu ist der Normalfall,
 * offen die Ausnahme.
 */
details.person {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--r);
  box-shadow: var(--schatten-1);
  margin: 0 0 10px;
  overflow: hidden;
}
details.person > summary {
  padding: 13px 16px;
  cursor: pointer;
  display: flex;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
  list-style: none;
}
details.person > summary::-webkit-details-marker { display: none; }
/* Ein eigener Winkel, weil der voreingestellte Marker in jedem Browser anders sitzt. */
details.person > summary::after {
  content: "";
  margin-left: auto;
  width: 8px; height: 8px;
  border-right: 2px solid var(--text-still);
  border-bottom: 2px solid var(--text-still);
  transform: rotate(45deg);
  transition: transform .15s ease;
}
details.person[open] > summary::after { transform: rotate(-135deg); }
details.person > summary:hover { background: var(--flaeche-ruhig); }
details.person > summary b { font-size: 15px; font-weight: 650; }
details.person[open] > summary {
  border-bottom: 1px solid var(--linie);
  background: var(--flaeche-ruhig);
}
details.person .inhalt { padding: 6px 16px 14px; }

.feldzeile { padding: 12px 0; border-bottom: 1px solid var(--linie); }
.feldzeile:last-child { border-bottom: 0; }

/* Die Rückennummer vor dem Namen. Feste Breite, damit die Namen untereinander
   anfangen und nicht nach der Ziffernzahl wandern. */
.nummer {
  font-variant-numeric: tabular-nums;
  font-family: var(--schrift-zahl);
  color: var(--navy);
  background: rgba(36, 58, 122, .1);
  border-radius: var(--r-klein);
  min-width: 2.4rem;
  text-align: center;
  padding: 2px 6px;
  font-size: 13px;
  font-weight: 700;
}

/* ---------------------------------------------------------------- Kleinteile */
/* **Ueber die volle Breite, seit dem 14.09.2026.**
 *
 * Hier stand `max-width: 68ch`, die uebliche Lesegrenze: laenger als rund 68 Zeichen
 * findet das Auge beim Zeilenwechsel schwerer zurueck. Gemeldet vom Auftraggeber, der
 * diese Seiten taeglich benutzt: „die Beschreibung von den einzelnen Sachen geht nur bis
 * zur Haelfte der Seite, soll eigentlich ueber die ganze Seite gehen, und nicht
 * zwischendrin aufhoeren." Auf einem breiten Schirm sah der Umbruch nicht nach Absicht
 * aus, sondern nach einem abgeschnittenen Text.
 *
 * Die Begruendung fuer die Grenze bleibt richtig, die Entscheidung ist eine andere. Wer
 * sie zurueckholen will, sollte vorher wissen, dass sie einmal bewusst gefallen ist. */
.unter { color: var(--text-leise); font-size: 14.5px; margin: 0 0 14px; }
.mitte { text-align: center; }
.warte { color: var(--text-still); font-style: normal; }
/* Ein Wert, den es nicht gibt. */
.geist, .ersatz { color: var(--text-still); }
.dazu { font-size: 13px; color: var(--text-leise); }

/* Ein Balken für einen Anteil (Stimmen, Tippverteilung). */
.balkenspur {
  background: var(--flaeche-ruhig);
  border-radius: var(--r-pille);
  overflow: hidden;
  height: 8px;
}
.balken { background: var(--navy); height: 100%; border-radius: var(--r-pille); }

/* Eine Zwischenüberschrift im Rumpf einer Karte. Kleiner als der Kartenkopf und in
   Kapitälchenart, damit sie ordnet, ohne mit ihm zu konkurrieren. */
.karte-rumpf h3, h3.feld-marke {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-still);
  margin: 22px 0 10px;
}
.karte-rumpf > h3:first-child { margin-top: 0; }

/* ---------------------------------------------------------------- Karte in Karte
 *
 * Die Seiten bauen Listen aus Karten und legen sie in eine Karte mit Kopf. Zwei
 * Rahmen um dasselbe sind einer zu viel: das innere Element bekommt deshalb keinen
 * eigenen Rahmen, sondern eine Trennlinie nach unten. Aus einem Kasten voll Kästen
 * wird eine Liste, und die liest man von oben nach unten statt Kasten für Kasten.
 */
.karte-rumpf .karte {
  border: 0;
  border-bottom: 1px solid var(--linie);
  border-radius: 0;
  box-shadow: none;
  background: transparent;
  padding: 16px 0;
}
.karte-rumpf .karte:last-child { border-bottom: 0; padding-bottom: 0; }
.karte-rumpf .karte:first-child { padding-top: 0; }

/* Die Ausnahmen bleiben sichtbar: was von der Quelle kommt, was Aufmerksamkeit
   braucht, was abgeschaltet ist. Als Streifen links, nicht als Fläche. */
.karte-rumpf .karte.vorgabe { background: transparent; }
.karte-rumpf .karte.achtung { border-left: 3px solid var(--warn); padding-left: 13px; }
.karte-rumpf .karte.warnung {
  background: var(--warn-grund);
  border-radius: var(--r-klein);
  padding-left: 13px; padding-right: 13px;
}
.karte-rumpf .karte.doppelung { border-left: 3px solid var(--schlecht); padding-left: 13px; }

/* ---------------------------------------------------------------- Die Pflegeseiten
 *
 * Sie sind die Ausnahme von der Regel darueber. Ein Punkt besteht dort aus fuenf
 * Zeilen (Titel, Hinweis, geltender Wert, neues Feld, Knopf), und zwoelf davon
 * untereinander laufen als flache Liste ineinander — gemeldet am 18.09.2026. Also
 * wieder Flaechen, und sie sagen gleich noch etwas: weiss ist gepflegt, ruhig ist
 * Vorgabe. Eine Farbe liest man, ohne zu lesen.
 *
 * Ueber die Klasse am `<body>` und nicht in jeder der sechs Seiten: sechs Kopien
 * waeren sechs Gelegenheiten, eine Korrektur zu vergessen. */
.pflegeseite .karte-rumpf .karte {
  border: 1px solid var(--linie);
  border-radius: var(--r-klein);
  background: var(--flaeche);
  padding: 15px 16px;
  margin: 0 0 12px;
}
.pflegeseite .karte-rumpf .karte:last-child { padding-bottom: 15px; margin-bottom: 0; }
.pflegeseite .karte-rumpf .karte:first-child { padding-top: 15px; }
.pflegeseite .karte-rumpf .karte.vorgabe { background: var(--flaeche-ruhig); }

/* Das Vorschaubild eines Portraetvorschlags von der Vereinsseite. Quadratisch
   beschnitten, damit zwei Bilder nebeneinander vergleichbar sind. */
.probebild { border-radius: var(--r-klein); object-fit: cover; background: var(--flaeche-ruhig); }

/* Der Wegweiser auf der Uebersicht von /pflege. */
.wegweiser { display: grid; gap: 2px; }
.wegweiser a {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 11px;
  border-radius: var(--r-klein);
  color: var(--text);
  text-decoration: none;
  font-size: 14.5px;
  font-weight: 500;
}
.wegweiser a:hover { background: var(--flaeche-ruhig); color: var(--navy); }
.wegweiser .sym { color: var(--text-still); }
.wegweiser a:hover .sym { color: var(--navy); }

/* ---------------------------------------------------------------- Felder in der
 * linken Spalte
 *
 * `.zeile` ist waagerecht — auf 380 Pixeln waere das eine Reihe aus abgeschnittenen
 * Feldern. In der Funktionsspalte stehen sie deshalb untereinander, und der Knopf
 * nimmt die ganze Breite: er ist der Abschluss des Formulars und nicht eines von
 * vielen Bedienteilen.
 */
.spalte-links .zeile { flex-direction: column; align-items: stretch; }
.spalte-links .zeile > .feld { flex: none; width: 100%; }
.spalte-links .zeile input.zahl,
.spalte-links .zeile input.kurz { width: 100%; }
.knopf-breit, button.knopf-breit { width: 100%; }

/* ---------------------------------------------------------------- Knöpfe in Listen
 *
 * In einer Liste steht derselbe Knopf zwanzigmal. Mit Rahmen ist das eine Wand aus
 * Kästen, und wenn zwei davon rot sind, sind es vierzig rote Kästen — dann ist Rot
 * kein Warnzeichen mehr, sondern der Grundton der Seite. Gemessen am 09.09.2026 am
 * ersten Bildschirmfoto von /konten.
 *
 * Also: kein Rahmen, keine Fläche, nur Text. Der Rahmen kommt beim Überfahren, und
 * die eigentliche Warnung steht in der Rückfrage — die liest man, weil man sie
 * wegklicken muss.
 */
button.still, .knopf.still {
  background: transparent;
  border-color: transparent;
  color: var(--navy);
  padding: 6px 10px;
}
button.still:hover:not(:disabled) {
  background: var(--flaeche);
  border-color: var(--linie-stark);
}
button.gefahr-still { color: var(--schlecht); }
button.gefahr-still:hover:not(:disabled) {
  background: var(--schlecht-grund);
  border-color: #EFC7CC;
}

/* Die Handlungsspalte rechts. Rechtsbündig, damit die Knöpfe eine Kante bilden und
   nicht nach der Textlänge der Zeile wandern. */
table.liste td.handlungen {
  text-align: right;
  white-space: nowrap;
  /* Ein Prozent heißt „so schmal wie der Inhalt". Ohne das nimmt sich die Spalte
     ihren Anteil an der Restbreite, und die Namensspalte bricht dafür zweizeilig. */
  width: 1%;
}
table.liste td.handlungen button { margin-left: 4px; }
table.liste td.mitte, table.liste th.mitte { text-align: center; }

/* Eine Zeile, die nicht mehr zählt: gesperrt, gelöscht, storniert. Blass und nicht
   weg — es soll nachweisbar bleiben, dass sie da ist. */
table.liste tr.aus td { color: var(--text-still); }
table.liste tr.aus td strong { font-weight: 500; }

/* Namen, Kennungen und Zeitangaben brechen nicht. Ein zweizeiliger Name macht die
   Zeile hoch und spart keine Breite; wenn es eng wird, soll die Tabelle rollen. */
table.liste td strong, table.liste td.kennung, table.liste td.wann { white-space: nowrap; }

/* Karten liegen untereinander, wenn eine Seite mehrere hat und keine zwei Spalten
   braucht. Der Abstand steht hier und nicht als Rand an jeder Karte, sonst muss man
   ihn bei der letzten wieder abziehen. */
main > .karte + .karte { margin-top: 18px; }
main > .zweispaltig + .karte { margin-top: 18px; }

/* Die Rechenaufgabe vor einer Handlung ohne Rückweg. Groß und in der Zahlenschrift,
   damit man sie liest statt sie zu übersehen. */
.aufgabe {
  font-family: var(--schrift-zahl);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--tinte);
}

/* Eine Tabelle aus Beschriftung und Wert, wie beim aktuellen Stand der App-Versionen.
   Die linke Spalte ist die Beschriftung und keine Überschrift der Spalte, deshalb
   steht sie nicht in Kapitälchen. */
table.protokoll tbody th {
  text-transform: none;
  letter-spacing: 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-leise);
  background: transparent;
  width: 1%;
  padding-right: 20px;
}

/* Die Handlungsspalte gilt auch in `table.protokoll`: die Seiten benutzen beide Namen
   für dieselbe Sache, und eine Regel, die nur für einen gilt, ist der Anfang von zwei
   Aussehen. */
table.protokoll td.handlungen {
  text-align: right;
  white-space: nowrap;
  width: 1%;
}
table.protokoll td.handlungen button { margin-left: 4px; }
table.protokoll td.zahl, table.protokoll th.zahl {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
table.protokoll td.mitte, table.protokoll th.mitte { text-align: center; }
table.protokoll tr.aus td { color: var(--text-still); }

/* ===========================================================================
   Dateien hochladen, und Kennungen, die abgetippt werden
   =========================================================================== */

/* Das Ablagefeld. Gross genug, dass man Dateien hineinzieht, ohne zu zielen — bei den
   Athletenkarten kommen dreissig auf einmal aus dem Ticketsystem. */
.ablage {
  display: block;
  border: 2px dashed var(--linie);
  border-radius: var(--r-klein);
  padding: 22px 16px;
  text-align: center;
  background: var(--flaeche);
  cursor: pointer;
}
.ablage.drueber { border-color: var(--gut); background: var(--gut-grund); }
.ablage p { margin: 0; color: var(--text-leise); font-size: 13.5px; }
.ablage b { display: block; font-size: 15px; color: var(--text); margin-bottom: 4px; }
/* Das echte Dateifeld bleibt bedienbar, steht aber nicht im Weg: der Rahmen darueber ist
   die Flaeche, die man trifft. */
.ablage input[type=file] { display: none; }

/* Eine Kennung, die ein Mensch abliest und weitergibt: Schreibmaschine und weit
   auseinander, weil 0 und O, 1 und l sonst dasselbe Zeichen sind. */
td.code, .code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.09em;
  font-weight: 650;
}


/* ======================================================= Anmeldung und Zugaenge
 *
 * Zwei Seiten, die es seit dem 19.09.2026 gibt: die Anmeldung und die Pflege der
 * Zugaenge. Ihr Stil steht hier und nicht in den Seiten, weil in diesem Baum gilt,
 * was `scripts/pruefe-verwaltung.mjs` durchsetzt: hoechstens 45 Zeilen `<style>` je
 * Seite. Die Regel gibt es, weil der Verwaltungsbereich schon einmal aus zwoelf
 * Kopien von 850 Zeilen bestand und deshalb zwoelf verschiedene Menues hatte.
 */

  /* Die Seite steht für sich: kein Kopfband, kein Menü, keine Fußzeile. Alles, was
     hier gebraucht wird, steht in diesem Block — verwaltung.css liefert Farben,
     Schrift, Felder und Knöpfe. */

  /* **An die Seite gebunden und nicht an `body`.**
   *
   * Beim ersten Versuch am 19.09.2026 stand hier ein nacktes `body { … }`. Diese Datei
   * laedt aber jede Verwaltungsseite: damit war der Grund aller Seiten navy, das
   * Kopfband schrumpfte zu einem Kaestchen in der Mitte, und die Kachelseiten sahen
   * aus wie zerschossen. Gesehen im Bildschirmfoto von /benutzer.
   *
   * Die Anmeldeseite traegt deshalb eine Klasse, und alles hier haengt daran. */
  body.anmeldeseite {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 24px;
    /* Derselbe Verlauf wie das Kopfband der Verwaltung, nur über die ganze Seite.
       Damit ist auf den ersten Blick klar, wohin man sich anmeldet. */
    background: linear-gradient(180deg, var(--navy) 0%, var(--navy-tief) 100%);
  }

  .anmeldung {
    width: min(420px, 100%);
    /* **Die Karte ist ein `main`**, und `main` traegt in dieser Datei 26 px oben und
       72 px unten Polsterung fuer die Verwaltungsseiten. Auf einer Karte, die fuer
       sich steht, sind das 98 px Weiss ohne Grund — im ersten Bildschirmfoto vom
       19.09.2026 hing der Kasten unten sichtbar durch. */
    padding: 0;
    margin: 0;
    background: var(--flaeche);
    border-radius: var(--r-gross);
    /* Ein deutlicher Schatten, weil die Karte auf dunklem Grund steht und sonst
       aufgeklebt wirkt. */
    box-shadow: 0 24px 60px rgba(10, 18, 48, .45);
    overflow: hidden;
  }

  .anmeldung-kopf {
    display: grid;
    justify-items: center;
    gap: 10px;
    padding: 28px 24px 20px;
    border-bottom: 1px solid var(--linie);
    text-align: center;
  }
  /* Das Wappen ist weiß und braucht seinen blauen Block — sonst steht es unsichtbar
     auf der weißen Karte. Derselbe Fall wie im Briefkopf, siehe briefe.js. */
  .anmeldung-marke {
    display: grid;
    place-items: center;
    width: 76px; height: 76px;
    border-radius: 20px;
    background: var(--navy);
  }
  .anmeldung-marke img { width: 52px; height: auto; }
  .anmeldung-kopf b { font-size: 17px; font-weight: 700; color: var(--navy); }
  .anmeldung-kopf span { font-size: 13px; color: var(--text-leise); }

  .anmeldung-rumpf { padding: 22px 24px 24px; display: grid; gap: 14px; }
  /* Die vier Schritte liegen im selben Kasten und werden ein- und ausgeblendet. Das
     Raster steht am Schritt und nicht am Rumpf, weil `[hidden]` sonst gegen ein
     `display: grid` verliert — genau der Fall, für den ganz oben in dieser Datei
     `[hidden] { display: none !important }` steht. */
  .anmeldung-form { display: grid; gap: 14px; }
  .anmeldung-rumpf label { display: grid; gap: 6px; font-size: 13px; font-weight: 600; }
  .anmeldung-rumpf .knopf { width: 100%; justify-content: center; margin-top: 4px; }
  .anmeldung-satz { margin: 0; font-size: 13.5px; line-height: 1.5; color: var(--text-leise); }
  .anmeldung-satz b { color: var(--text); }

  /* Der QR-Code zum Einrichten. Weiß hinterlegt und mit Rand, weil ein Code ohne
     Ruhezone von manchen Kameras nicht erkannt wird — dieselbe Regel wie auf der
     Hallenanzeige. */
  .qr-feld {
    display: grid;
    place-items: center;
    padding: 14px;
    background: #fff;
    border: 1px solid var(--linie);
    border-radius: var(--r);
  }
  .qr-feld svg { width: min(210px, 100%); height: auto; display: block; }

  /* Das Geheimnis zum Abtippen. Schreibmaschinenschrift, damit die Gruppen stehen,
     und auswählbar. */
  .geheimnis {
    margin: 0;
    padding: 10px 12px;
    background: var(--flaeche-ruhig);
    border: 1px solid var(--linie);
    border-radius: var(--r-klein);
    font: 15px/1.5 var(--schrift-zahl);
    letter-spacing: .08em;
    text-align: center;
    user-select: all;
  }

  /* Die Ersatzschlüssel. Zwei Spalten, damit zehn Stück nicht zur Bildschirmlänge
     werden, und in Schreibmaschinenschrift: sie werden abgeschrieben. */
  .ersatzliste {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px 14px;
    margin: 0;
    padding: 14px;
    list-style: none;
    background: var(--flaeche-ruhig);
    border: 1px solid var(--linie);
    border-radius: var(--r);
    font: 14px/1.6 var(--schrift-zahl);
  }

  /* Gedruckt bleibt nur, was man aufhebt: die Schlüssel. */
  @media print {
    body.anmeldeseite { background: #fff; display: block; padding: 0; }
    .anmeldung { box-shadow: none; width: auto; }
    .anmeldung-fuss, .nichtdrucken, .meldung { display: none !important; }
  }

  .anmeldung-fuss {
    padding: 0 24px 22px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-leise);
  }

  /* Nur was diese Seite allein braucht. */

  /* Zwei Felder nebeneinander, solange Platz ist. Dieselbe Aufteilung wie in den
     Pflegeformularen, nur steht sie hier: verwaltung.css kennt sie noch nicht, und
     eine halbe Klasse in die gemeinsame Datei zu legen, heisst, sie dort zu suchen. */
  /* `auto-fit` statt `1fr 1fr`: in der schmalen linken Spalte ist fuer zwei Felder
     kein Platz, und die Fensterbreite sagt darueber nichts — die Karte ist auch auf
     einem breiten Schirm 320 px schmal. Gesehen am 19.09.2026: „z. B. Redaktion" und
     das Passwortfeld standen halb ausserhalb der Karte.
     `min-width: 0` an den Feldern, weil ein `input` von sich aus breiter sein will
     als seine Rasterzelle und sie sonst aufdrueckt. */
  .feldpaar { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; }
  .feldpaar input, .feldpaar select { min-width: 0; }
  .feldpaar label, .anmeldung-rumpf label { display: grid; gap: 6px; font-size: 13px; font-weight: 600; }

  .zugangsliste { display: grid; gap: 2px; }
  .zugang {
    display: grid;
    gap: 6px;
    padding: 12px;
    border: 1px solid var(--linie);
    border-radius: var(--r-klein);
    background: var(--flaeche);
  }
  .zugang + .zugang { margin-top: 6px; }
  .zugang.ich { border-color: var(--navy); }
  .zugang.ruht { background: var(--flaeche-ruhig); }
  .zugang-name { font-size: 15px; font-weight: 650; }
  .zugang-name .kennung { font-weight: 400; color: var(--text-leise); }
  .zugang-unter { font-size: 12.5px; color: var(--text-leise); }
  /* Ein Zugang, dessen zweiter Faktor noch aussteht. Kein Fehler, sondern ein
     Zwischenstand — deshalb der warnende und nicht der schlechte Ton. */
  .zugang-unter.wartet { color: var(--warn); }
  .zugang .knopfreihe { margin: 2px 0 0; }

  /* Die Bereiche einer Rolle: zwei Spalten, damit siebzehn Haken nicht zu einer
     Bildschirmlänge werden. */
  .bereichswahl {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 8px;
  }
  .bereichswahl label {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 8px;
    align-items: start;
    padding: 10px;
    border: 1px solid var(--linie);
    border-radius: var(--r-klein);
    cursor: pointer;
  }
  .bereichswahl label:hover { background: var(--flaeche-ruhig); }
  .bereichswahl input { margin-top: 2px; }
  .bereichswahl b { font-size: 13.5px; font-weight: 650; }
  .bereichswahl span {
    grid-column: 2;
    font-size: 12px;
    line-height: 1.45;
    color: var(--text-leise);
  }

  /* **Die Knopfreihe braucht Luft nach oben.**
   *
   * `.knopfreihe` traegt selbst keinen Abstand — sie steht auf den meisten Seiten
   * zwischen Feldern, die ihren eigenen mitbringen. Hier folgt sie unmittelbar auf
   * eine Liste und auf das Feld mit den Bereichen, und dann klebt sie daran:
   * „Neue Rolle" sass am 19.09.2026 direkt unter der letzten Rolle und sah aus wie
   * ein weiterer Eintrag. Beanstandet, und zu Recht.
   *
   * Als Nachbarregel und nicht an `.knopfreihe` selbst: die Klasse steht auf zwanzig
   * Seiten, und ein Abstand fuer alle waere eine Aenderung an zwanzig Stellen,
   * beschlossen an einer. */
  .rollenliste + .knopfreihe,
  .bereichswahl + .knopfreihe { margin-top: 16px; }

  .rollenliste { display: grid; gap: 6px; }
  /* **Eine Rolle ist ein Knopf, und `button` traegt in dieser Datei Eigenschaften mit.**
   *
   * Der nackte `button` oben ist `display: inline-flex` mit `justify-content: center`
   * und `white-space: nowrap`. Wer nur `display` umstellt, nimmt die anderen beiden
   * mit: am 19.09.2026 stand der Text der Rollen mittig, obwohl `text-align: left`
   * galt und berechnet auch so ankam — `justify-content` richtet bei einem Raster die
   * ganze Spur aus, und das schlaegt jede Textausrichtung. Gemessen: Knopf 880 px,
   * Inhalt 132 px, mittig.
   *
   * Bloecke statt Raster loesen es ohne Gegenmittel: `justify-content` gilt fuer
   * Bloecke nicht. `white-space` muss trotzdem zurueckgesetzt werden, sonst laeuft
   * eine lange Rollenbezeichnung aus der Karte statt umzubrechen. */
  .rollenliste .rolle {
    display: block;
    white-space: normal;
    padding: 10px 12px;
    border: 1px solid var(--linie);
    border-radius: var(--r-klein);
    cursor: pointer;
    text-align: left;
    background: var(--flaeche);
    font: inherit;
    color: inherit;
  }
  .rollenliste .rolle:hover { background: var(--flaeche-ruhig); }
  .rollenliste .rolle.gewaehlt { border-color: var(--navy); background: var(--flaeche-ruhig); }
  .rollenliste b { display: block; font-size: 14px; font-weight: 650; }
  .rollenliste span { display: block; margin-top: 3px; font-size: 12.5px; color: var(--text-leise); }

/* Die Liste der Spieltage auf dem Gutscheinblatt. Sie stand bis zum 19.09.2026 in der
 * Seite und ist hierher gezogen, als die Rollenliste denselben Bau bekam: zwei Listen
 * mit demselben Verhalten und zwei Fassungen davon sind eine zu viel. */
  .spieltagliste { display: grid; gap: 2px; }
  .spieltagliste .spieltagliste-eintrag {
    /* Bloecke und kein Raster: `button` traegt in verwaltung.css
       `justify-content: center` und `white-space: nowrap`, und beides bleibt stehen,
       wenn man nur `display` umstellt. Der Eintrag stuende dann mittig und ohne
       Umbruch. Aufgefallen am 19.09.2026 an der Rollenliste, derselbe Bau. */
    display: block;
    white-space: normal;
    text-align: left;
    padding: 10px 12px;
    border: 1px solid transparent;
    border-radius: var(--r-klein);
    background: transparent;
    font: inherit;
    color: inherit;
    cursor: pointer;
  }
  .spieltagliste-eintrag:hover { background: var(--flaeche-ruhig); }
  .spieltagliste-eintrag.gewaehlt { background: var(--flaeche-ruhig); border-color: var(--navy); }
  .spieltagliste b { display: block; font-size: 14.5px; font-weight: 650; }
  .spieltagliste span { display: block; margin-top: 2px; font-size: 12.5px; color: var(--text-leise); }

/* Die Karte „Angemeldet als …" unten im Menue. Sie steht dort, weil jeder sein
 * Passwort selbst aendern koennen muss — auch wer die Benutzerseite nicht sieht.
 * Schmal und unten: der seltenste Handgriff auf der meistbesuchten Seite. */
.eigenzugang { max-width: 620px; margin-top: 8px; }
.eigenzugang .karte-rumpf { display: grid; gap: 12px; }
.eigenzugang .knopfreihe { margin: 0; }

/* ---------------------------------------------------------------- Spieltags-Cockpit
 *
 * Vier Zeilen, die am Spieltag zusammen beantworten, ob man losfahren kann. Der ganze
 * Aufbau hängt an einer Entscheidung: **drei Zustände, nicht zwei.**
 *
 * `bereit` grün, `offen` gelb, `unbekannt` grau. Das Graue ist der Grund für die
 * dritte Farbe: wenn der Editor nicht antwortet, darf die Zeile nicht „kein Heft"
 * sagen, sondern „weiß ich nicht". Zwei Zustände zwingen an dieser Stelle zur Lüge,
 * und die Lüge fällt am Spieltag auf, wenn niemand mehr Zeit hat.
 *
 * Die Marke links trägt ein Zeichen (✓ ! ?) und nicht nur Farbe. Ein Cockpit, das
 * seine Aussage allein über Rot und Grün trägt, sagt einem rotgrünblinden Menschen
 * nichts — und es wird auf einem Telefon im Hallenlicht gelesen.
 */
.cockpit { display: grid; gap: 10px; margin: 4px 0 20px; }

.cockpitzeile {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 4px 14px;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-left: 4px solid var(--linie-stark);
  border-radius: var(--r);
  box-shadow: var(--schatten-1);
  padding: 15px 17px;
}

/* Die Marke ist rund und trägt das Zeichen mittig. Feste Größe, damit die Titel aller
   Zeilen auf derselben senkrechten Linie beginnen — auch wenn ein Satz umbricht. */
.cockpitmarke {
  width: 30px;
  height: 30px;
  border-radius: var(--r-pille);
  display: flex;
  align-items: center;
  justify-content: center;
  font: 700 15px/1 var(--schrift);
  flex: none;
}

.cockpitmitte { display: grid; gap: 3px; min-width: 0; }
.cockpitmitte b { font-size: 15.5px; font-weight: 650; letter-spacing: -.01em; }
.cockpitmitte > span { font-size: 13.5px; line-height: 1.45; color: var(--text-leise); }

/* Zahlen in Schreibmaschinenschrift: sie stehen untereinander und werden verglichen
   („zuletzt 18:42" gegen „zuletzt 18:02"). */
.cockpitzahlen {
  font: 12.5px/1.4 var(--schrift-zahl);
  color: var(--text-still);
  font-variant-numeric: tabular-nums;
}

.cockpitzeile.bereit { border-left-color: var(--gut); }
.cockpitzeile.bereit .cockpitmarke { background: var(--gut-grund); color: var(--gut); }

.cockpitzeile.offen { border-left-color: var(--warn); background: #FFFDF7; }
.cockpitzeile.offen .cockpitmarke { background: var(--warn-grund); color: var(--warn); }
.cockpitzeile.offen .cockpitmitte b { color: var(--warn); }

/* Unbekannt und entfaellt sehen gleich zurueckhaltend aus und sind es nicht: das eine
 * heisst „weiss ich nicht", das andere „gibt es hier nicht". Der Unterschied steht im
 * Zeichen (? gegen –) und im Satz, nicht in der Farbe — beide sollen ruhig bleiben und
 * nicht nach einer Handlung aussehen. */
.cockpitzeile.unbekannt,
.cockpitzeile.entfaellt { border-left-color: var(--linie-stark); background: var(--flaeche-ruhig); }
.cockpitzeile.unbekannt .cockpitmarke,
.cockpitzeile.entfaellt .cockpitmarke {
  background: var(--flaeche);
  color: var(--text-still);
  border: 1px solid var(--linie);
}
/* Eine Zeile, die nicht gilt, tritt einen Schritt zurueck: sie steht da, damit niemand
   sie fuer vergessen haelt, und soll den Blick nicht halten. */
.cockpitzeile.entfaellt .cockpitmitte b { color: var(--text-leise); font-weight: 600; }

/* Die Wege unter den Zeilen: Ziele ohne Zustand. Sie stehen bewusst getrennt und mit
   einer Linie darüber — sonst liest man sie als vierte oder fünfte Zeile und sucht
   dort eine Ampel, die es nicht gibt. */
.cockpitwege {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding-top: 16px;
  margin-top: 4px;
  border-top: 1px solid var(--linie);
}

/* Schmal: Marke, Text und Weg untereinander. Der Weg rückt unter den Text und nicht
   unter die Marke — eingerückt bleibt er sichtbar als das, was zur Zeile gehört. */
@media (max-width: 560px) {
  .cockpitzeile { grid-template-columns: auto 1fr; }
  .cockpitzeile > .knopf { grid-column: 2; justify-self: start; margin-top: 4px; }
}

/* Die Kachel im Menue, die hierher fuehrt. Sie steht in dieser Datei und nicht im
 * Stilblock von menu.html, weil der dort auf 95 Zeilen begrenzt ist
 * (scripts/pruefe-verwaltung.mjs) - und weil Kachel und Seite dieselbe Sache sind.
 * `.gruppe`, `.kacheln` und `.kachel` selbst bleiben in menu.html: sie gehoeren
 * nur dieser einen Seite.
 */
/* ------------------------------------------------------------ Das Cockpit
   EIGENE SEKTION, EIGENE FARBE. So bestellt am 20.09.2026: „Sollte aber seine eigene
   Sektion in der Verwaltung bekommen, vielleicht auch eine eigene Farbumrandung. Sehr
   sichtbar."

   Gold und nicht rot. Rot ist in diesem Menue schon vergeben und bedeutet dort etwas
   Bestimmtes: nicht zurueckholbar (Push, Benutzer und Rollen). Ein dritter roter
   Rahmen um etwas, das nur liest, wuerde die Warnung der beiden anderen verwaessern.
   Gold ist die zweite Vereinsfarbe, kommt im Menue sonst nirgends vor und faellt
   auf weissem Grund auf — sichtbar, ohne zu warnen.

   Die Kachel laeuft ueber die ganze Breite und steht ganz oben, weil sie am Spieltag
   der erste Griff ist und weil sie auf die anderen Punkte verweist, nicht neben
   ihnen steht. */
.gruppe.spieltagsgruppe > h2 { color: var(--gold-tief); }
.gruppe.spieltagsgruppe > h2::after { background: #F0DCA8; }

/* **Gold ja, breit nein.** Die Kachel lief bis zum 23.09.2026 ueber die ganze Zeile
 * (`grid-column: 1 / -1`) und stand damit allein ueber den Auswertungen. So bestellt:
 * dieselbe Breite wie jede andere Kachel, daneben die Auswertungen, der goldene Rand
 * bleibt. Die Hervorhebung traegt die Farbe, sie braucht die Breite nicht dazu. */
a.kachel.cockpit-kachel {
  border: 2px solid var(--gold);
  background: linear-gradient(180deg, #FFFDF5 0%, var(--flaeche) 62%);
  align-items: center;
}
a.kachel.cockpit-kachel:hover {
  border-color: var(--gold-tief);
  box-shadow: var(--schatten-2);
}
.cockpit-kachel .haube {
  background: var(--gold);
  color: var(--navy);
}
/* Die Schriftgroessen der breiten Fassung sind mit ihr weggefallen: in einer Kachel
 * von normaler Breite sprengt eine 18,5-Pixel-Ueberschrift die Zeile, und der Text
 * daneben stuende dann anders als in allen Nachbarkacheln. */

/* ---------------------------------------------------------------- Kosten und Budget
 *
 * Die Seite `/kosten`: was die eingeloesten Praemien den Verein kosten, und die
 * Grenze, gegen die gewarnt wird.
 *
 * **Warum das hier steht und nicht in der Seite.** Der Stilblock einer Seite darf 45
 * Zeilen nicht ueberschreiten (scripts/pruefe-verwaltung.mjs), und diese Regeln sind
 * 50. Die Grenze ist keine Schikane: was in einer Seite steht, findet niemand, der
 * eine zweite Seite gleich aussehen lassen will — und die grossen Zahlenkarten hier
 * sind genau die Bauform, die eine Auswertungsseite wieder braucht.
 */
/* Die drei grossen Zahlen oben: Saison, laufender Monat, letzter Spieltag. */
.zahlenreihe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
  margin: 0 0 22px;
}
.zahlkarte {
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--r-gross);
  box-shadow: var(--schatten-1);
  padding: 16px 18px;
  display: grid;
  gap: 2px;
  align-content: start;
}
.zahlkarte .was {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-still);
}
.zahlkarte .wert {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.zahlkarte .dazu { font-size: 13px; color: var(--text-leise); line-height: 1.45; }
.zahlkarte .dazu.fehlt { color: var(--warn); }

/* Der Balken des Budgets. Kein Diagramm, nur ein Streifen: die Frage ist, wie viel
   noch da ist, und die beantwortet eine Laenge schneller als eine Zahl. */
.budgetbalken {
  height: 12px;
  border-radius: var(--r-pille);
  background: var(--flaeche-ruhig);
  border: 1px solid var(--linie);
  overflow: hidden;
  margin: 10px 0 8px;
}
.budgetbalken > span { display: block; height: 100%; background: var(--gut); }
.budgetbalken.warnt > span { background: var(--warn); }
.budgetbalken.drueber > span { background: var(--schlecht); }

.betrag { font-variant-numeric: tabular-nums; white-space: nowrap; }
td.betrag, th.betrag { text-align: right; }

/* Eine Liste aus Bezeichnung und Zahl, in einer schmalen Spalte. Kein Raster mit
   fester Spaltenzahl: „Getraenkegutschein" bricht darin um und die Zahl rutscht in die
   naechste Zeile. Hier steht der Name links, die Zahl rechts, und bei zu wenig Platz
   bricht nur der Name. */
.postenliste {
  display: grid;
  gap: 6px;
  margin: 10px 0;
  padding: 0;
  list-style: none;
  font-size: 13.5px;
}
.postenliste li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--linie);
}
.postenliste li:last-child { border-bottom: 0; padding-bottom: 0; }
.postenliste b { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- Entwürfe (/push)
 *
 * Die Liste der gespeicherten Mitteilungsentwürfe, links in der Schreibspalte.
 *
 * **Sie sieht bewusst nicht nach Senden aus.** Auf derselben Seite steht der rote
 * Kasten mit dem Knopf, der an jedes Telefon geht und nicht zurückholbar ist. Alles
 * hier ist ruhig: helle Fläche, kleine Knöpfe, kein Rot. Wer die Gewohnheit entwickelt,
 * dass der auffällige Knopf der gefährliche ist, soll sie behalten dürfen.
 */
.entwurfsliste {
  display: grid;
  gap: 8px;
  margin-top: 14px;
  /* Die linke Spalte klebt beim Rollen (`.spalte-links`). Eine lange Liste darin
     schöbe den Sendekasten aus dem Bild — deshalb rollt sie in sich selbst, wie die
     Berichtsliste darüber. */
  max-height: 22rem;
  overflow-y: auto;
}
.entwurf {
  border: 1px solid var(--linie);
  border-radius: var(--r-klein);
  background: var(--flaeche);
  padding: 10px 12px;
}
.entwurf.offen { border-color: var(--navy); background: var(--flaeche-ruhig); }
.entwurf-kopf { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.entwurf-unter {
  margin: 3px 0 8px;
  font-size: 12.5px;
  color: var(--text-leise);
  overflow-wrap: anywhere;
}
.entwurf .knopfreihe { gap: 8px; margin: 0; }

/* ---------------------------------------------------------------------------
   Das Logofeld der Sponsorenseite (#128)

   Eine feste Schauflaeche, in die das Logo hineinpasst statt sie zu fuellen:
   `contain` und nicht `cover`. Ein zugeschnittenes Firmenlogo ist ein beschaedigtes
   Firmenlogo, und die Seitenverhaeltnisse reichen hier vom breiten Schriftzug bis
   zum quadratischen Wappen.

   Der karierte Grund macht sichtbar, was am Bild durchsichtig ist. Viele Logos
   kommen als PNG mit freigestelltem Hintergrund, und auf einer weissen Flaeche
   sieht ein weisser Schriftzug aus wie ein fehlendes Bild.
--------------------------------------------------------------------------- */
.logofeld { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin-bottom: .5rem; }

.logoschau {
  width: 132px; height: 64px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--rand, #d5d9e0); border-radius: 8px;
  background-color: #fbfcfd;
  background-image:
    linear-gradient(45deg, #eef1f5 25%, transparent 25%, transparent 75%, #eef1f5 75%),
    linear-gradient(45deg, #eef1f5 25%, transparent 25%, transparent 75%, #eef1f5 75%);
  background-size: 14px 14px;
  background-position: 0 0, 7px 7px;
  flex: none;
}

.logoschau img { max-width: 124px; max-height: 56px; object-fit: contain; }

/* Der Dateiwaehler ist breit und hoelzern. Schmal gehalten, damit er die Zeile nicht
   sprengt; die Schauflaeche daneben ist das, was zaehlt. */
.logofeld input[type="file"] { max-width: 15rem; font-size: .85rem; }

/* ---------------------------------------------------------------------------
   Klappkarten fuer lange Verzeichnisse (#128)

   Neunundfuenfzig offene Formulare untereinander ergaben eine Seite von rund
   fuenfundvierzigtausend Pixeln. Zugeklappt ist jeder Eintrag eine Zeile, und die
   Zusammenfassung traegt, was man beim Suchen braucht.

   `details` und nicht ein eigener Schalter: Tastatur, Vorlesen und die Suche des
   Browsers funktionieren damit ohne eine Zeile JavaScript.
--------------------------------------------------------------------------- */
.klappkarte {
  border: 1px solid var(--rand, #d5d9e0);
  border-radius: 10px;
  margin-bottom: .5rem;
  background: #fff;
}

.klappkarte > summary {
  cursor: pointer;
  padding: .55rem .75rem;
  border-radius: 10px;
  list-style: none;
}

/* Das Dreieck von Safari und Chrome weg, dafuer ein eigenes: es soll links stehen
   und dieselbe Farbe haben wie die Beschriftung daneben. */
.klappkarte > summary::-webkit-details-marker { display: none; }

.klappkarte > summary::before {
  content: "›";
  display: inline-block;
  width: 1rem;
  color: var(--leise, #6b7280);
  transition: transform .12s ease;
}

.klappkarte[open] > summary::before { transform: rotate(90deg); }
.klappkarte > summary:hover { background: #f5f7fa; }
.klappkarte > summary:focus-visible { outline: 2px solid #2a5bd7; outline-offset: -2px; }

/* Ein abgeschalteter Eintrag bleibt lesbar, tritt aber zurueck. Nicht ausblenden:
   er steht hier, weil jemand ihn wieder einschalten koennen soll. */
.klappkarte.aus > summary { opacity: .55; }

.klappzeile { display: inline-flex; align-items: center; gap: .6rem; vertical-align: middle; }
.klappzeile .kennung { font-size: .82rem; }

/* Der Platz fuer das Logo bleibt auch leer stehen, damit die Namen untereinander
   auf einer Linie beginnen. Ein Verzeichnis, in dem jede Zeile anders einrueckt,
   liest sich schlecht. */
.klappbild {
  width: 44px; height: 24px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
}

.klappbild img { max-width: 44px; max-height: 24px; object-fit: contain; }

.klappkarte > .karte { border: 0; margin: 0; border-top: 1px solid var(--rand, #d5d9e0); border-radius: 0 0 10px 10px; }

/* --- Die Bilderablage (#147) ---------------------------------------------
 *
 * Ein Raster aus Kacheln, je Bild eine. Die Vorschau steht oben in fester Hoehe,
 * damit die Kacheln eine Reihe bilden und nicht nach Seitenverhaeltnis springen;
 * `contain` statt `cover`, weil ein beschnittenes Vorschaubild etwas anderes zeigt
 * als das Bild, das man einzutragen im Begriff ist.
 */
.bildraster {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

.bildkachel {
  display: flex; flex-direction: column; gap: 6px;
  padding: 12px; border: 1px solid var(--rand, #d5d9e0); border-radius: 10px;
  background: var(--flaeche, #fff);
}

.bildschau {
  height: 140px; display: flex; align-items: center; justify-content: center;
  background: var(--flaeche-ruhig, #f2f4f7); border-radius: 8px; overflow: hidden;
}

.bildschau img { max-width: 100%; max-height: 140px; object-fit: contain; }

/* Der Hinweis unter einem unnoetig schweren Bild (#160).
 *
 * Warnfarben und ein eigener Grund, damit er sich von der Kachel abhebt: er sagt
 * etwas ueber dieses eine Bild und nicht ueber die Seite. Ganz unten in der Kachel,
 * weil er erst zaehlt, wenn man das Bild schon gefunden hat. */
.abspecken {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 2px; padding: 8px 10px; border-radius: 8px;
  background: var(--warn-flaeche, #fff7e6);
  border: 1px solid var(--warn, #c98a00);
}

.abspecken p { margin: 0; }
.abspecken .knopf { align-self: flex-start; }

/* Die Adresse steht in einem Feld und nicht als Text: so laesst sie sich markieren
 * und von Hand kopieren, wenn die Zwischenablage nicht darf. */
.adressfeld {
  width: 100%; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .78rem; padding: 6px 8px;
  border: 1px solid var(--rand, #d5d9e0); border-radius: 6px;
  background: var(--flaeche-ruhig, #f2f4f7); color: var(--text, #1b2432);
}
