/* assets/theme-admin.css  —  Design 3, Etappe 2, Baustein 1 (D13/D14).
 *
 * DIE QUELLE FUER FARBEN UND BAUSTEINE DER ADMIN- UND SETUP-WELT.
 *
 * WARUM ES DIESE DATEI GIBT
 * Die Inventur vom 09.09.2026 hat den Ist-Zustand gezaehlt: `.btn` an 16 Stellen
 * definiert, 16 Varianten der Kopfzeile, 1 627 Hexfarben in den Seiten selbst,
 * 42 von 59 Seiten mit eigenem <style>-Block. Eine Farbaenderung war damit eine
 * Suchaufgabe mit ungewissem Ausgang.
 *
 * DIE ZWEI WELTEN (10_Design_Guidelines_Umsetzung.md Abschnitt 2a):
 *   Spiel und Screen  -> dunkel, Gruen   (--game-*, eigene Datei, spaeter)
 *   Admin und Setup   -> hell,   Blau    (--admin-*, DIESE Datei)
 *
 * DIE REGEL, die diese Datei traegt:
 *   1. Farbwerte stehen AUSSCHLIESSLICH in :root, als Token.
 *   2. Jeder Baustein verweist nur auf var(--admin-*) - nie auf einen Hexwert.
 *   3. Eine Seite der Admin-Welt bindet diese Datei ein und hat KEINEN eigenen
 *      <style>-Block.
 * Punkt 1 und 2 pruefen tests/admin_theme_test.php Abschnitt 3, Punkt 3 der
 * Abschnitt 4 - fuer die Pilotseite.
 *
 * TOKENNAMEN: sie stammen aus 19_Design_System_and_Colors.md Abschnitt 3a und
 * werden hier nicht erfunden. Die dortige Regel 5 sagt, die konkreten Hexwerte
 * werden "mit dem ersten Umbauschritt zentral festgelegt und ausschliesslich
 * dort gepflegt" - das ist diese Datei.
 *
 * KONTRAST: jede Text-auf-Grund-Kombination erreicht mindestens 4.5:1; der
 * kleinste Wert im Satz ist 4.67:1 (Erfolgsgruen als Text auf dem Seitengrund).
 * Die gemessenen Werte stehen im Bericht 2026-09-09_Design3-AdminTheme.md.
 *
 * NICHT HIER DRIN: die obere Navigationsleiste und die Turnier-Admin-Navigation.
 * Sie sind Baustein 3 und 4 dieser Etappe und haben eigene Guidelines (11 und
 * 13). Wer sie hier ergaenzt, macht aus der einen Quelle wieder zwei.
 */

:root {
  /* --- Flaechen und Text ------------------------------------------------ */
  --admin-background:       #f5f7fa;   /* Seitenhintergrund, sehr helles Grau  */
  --admin-surface:          #ffffff;   /* Karten, Panels, Dialoge              */
  --admin-surface-elevated: #ffffff;   /* schwebende Flaechen (mit Schatten)   */
  --admin-text-primary:     #1f2937;   /* Haupttext, dunkles Blaugrau          */
  --admin-text-secondary:   #5b6472;   /* Zusatzinformation, Labels            */
  --admin-border:           #e3e8ef;   /* Trennlinien, Feldrahmen              */

  /* --- Handlungsfarben --------------------------------------------------- */
  --admin-primary:          #2563eb;   /* Primaertaste, Auswahl, Fokus - Blau  */
  --admin-primary-hover:    #1d4ed8;   /* gedrueckt oder ueberfahren           */
  --admin-primary-text:     #ffffff;   /* Text auf der Primaerflaeche          */

  /* --- Zustaende --------------------------------------------------------- */
  --admin-danger:           #b91c1c;   /* Fehler, Loeschen                     */
  --admin-warning:          #b45309;   /* Aufmerksamkeit, ausstehend           */
  --admin-success:          #15803d;   /* gespeichert, bestaetigt              */
  --admin-info:             #475569;   /* neutraler Hinweis                    */

  /* --- Struktur ---------------------------------------------------------- */
  --admin-space-1: 6px;
  --admin-space-2: 10px;
  --admin-space-3: 16px;
  --admin-space-4: 24px;
  /* Zeichengroessen (Design 13b). Thomas' Befund: die Zeichen waren zu
     klein - in der Kachelwand von lokal.php und in der Titelkachel des
     Setups. Sie stehen hier als Token, weil zwei Stylesheets sie brauchen:
     game_setup.css fuer die Auswahlkacheln, diese Datei fuer den Titel. */
  --admin-icon-tile:  40px;   /* Auswahlkachel - das Zeichen traegt die Kachel */
  --admin-icon-title: 32px;   /* Titelkachel des Setups                       */
  --admin-radius:    12px;
  --admin-radius-sm:  8px;
  --admin-font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --admin-font-size: 15px;
  --admin-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 1px 3px rgba(15, 23, 42, .08);
  /* DESIGN 7: Der abdunkelnde Grund hinter einem Dialog. Er fehlte - jede
     Seite mit Modal trug ihn als rgba() im eigenen Style-Block. */
  --admin-overlay: rgba(15, 23, 42, .5);
  --admin-focus-ring: 0 0 0 3px rgba(37, 99, 235, .15);

  /* DESIGN 10: die blassen Toene derselben Rollen. Sie standen bisher als
     rgba() oder als eigener Hexwert in admin.css - als Grund hinter einem
     farbigen Text (Status "laeuft", Hinweis, Zaehler). */
  --admin-primary-soft: #eef2ff;
  --admin-success-soft: #dcfce7;
  --admin-warning-soft: #fef3c7;

  /* DESIGN 10: die KO-Phase hat im Bestand einen EIGENEN Akzent - Violett.
     Er unterscheidet die Endrunde von der Gruppenphase und steht im Markup
     an Knopf, Spaltentitel und Zuweisungsrahmen. Weil es eine Farbe ist,
     steht sie hier und nicht in assets/turnier-admin.css. */
  --admin-ko:       #7c3aed;
  --admin-ko-hover: #6d28d9;
  --admin-ko-soft:  rgba(124, 58, 237, .25);
}

/* =====================================================================
   Seitenrahmen
   ===================================================================== */
body {
  margin: 0;
  background: var(--admin-background);
  color: var(--admin-text-primary);
  font-family: var(--admin-font);
  font-size: var(--admin-font-size);
  -webkit-text-size-adjust: 100%;
}

/* DESIGN 6 (10.09.2026): line-height haengt jetzt an .admin-page statt an body.
   Eine Seite, die dieses Theme nur fuer EINE Komponente laedt - die drei
   Turnier-Admin-Seiten tun das seit Design 6 -, soll nicht ihre gesamte
   Textmetrik aendern. Dasselbe gilt weiter unten fuer die Formularfelder. */
.admin-page {
  line-height: 1.45;
  max-width: 900px;
  margin: 0 auto;
  padding: var(--admin-space-3);
}

/* Kopfzeile einer Seite: Titel und die Aktionen dazu. Das ist NICHT die
   Navigationsleiste - hier steht, worum es auf DIESER Seite geht. */
.admin-page > header {
  display: flex;
  align-items: center;
  gap: var(--admin-space-2);
  flex-wrap: wrap;
  margin-bottom: var(--admin-space-3);
}
.admin-page > header h1 {
  font-size: 21px;
  margin: 0;
  font-weight: 700;
}

/* =====================================================================
   Karte
   ===================================================================== */
.card {
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius);
  padding: var(--admin-space-3);
  margin-bottom: var(--admin-space-3);
  box-shadow: var(--admin-shadow);
}
.card-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--admin-space-2);
  flex-wrap: wrap;
}
.card-scroll { overflow-x: auto; }

/* =====================================================================
   Tasten
   ===================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--admin-space-1);
  border: 1px solid var(--admin-primary);
  background: var(--admin-primary);
  color: var(--admin-primary-text);
  border-radius: var(--admin-radius-sm);
  padding: 9px 14px;
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  text-decoration: none;
}
.btn:hover { background: var(--admin-primary-hover); border-color: var(--admin-primary-hover); }
.btn:focus-visible { outline: 2px solid var(--admin-primary); outline-offset: 2px; }
.btn[disabled], .btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-primary { background: var(--admin-primary); border-color: var(--admin-primary); color: var(--admin-primary-text); }
.btn-secondary {
  background: var(--admin-surface);
  border-color: var(--admin-border);
  color: var(--admin-text-primary);
}
.btn-secondary:hover { background: var(--admin-background); border-color: var(--admin-border); }
.btn-danger { background: var(--admin-danger); border-color: var(--admin-danger); color: var(--admin-primary-text); }
.btn-danger:hover { background: var(--admin-danger); }

.btn-sm { padding: 7px 11px; font-size: 13px; }

/* =====================================================================
   Formularfelder
   ===================================================================== */
/* DESIGN 6: an .admin-page gebunden. Die drei Turnier-Admin-Seiten laden dieses
   Theme fuer die Navigation und bringen ihr eigenes assets/admin.css mit; sie
   haben zusammen 54 <label>, 46 <input> und 20 <select>. Blanke Elementregeln
   haetten sie alle umgestaltet - Eingabefelder ueber die volle Breite, wo heute
   schmale stehen. .admin-page ist die Klasse, mit der eine Seite erklaert, dass
   sie auf dieses Theme umgestellt IST. */
.admin-page label {
  display: block;
  margin-bottom: var(--admin-space-1);
  color: var(--admin-text-secondary);
  font-size: 13px;
  font-weight: 600;
}
.admin-page input, .admin-page select, .admin-page textarea {
  width: 100%;
  box-sizing: border-box;
  background: var(--admin-surface);
  color: var(--admin-text-primary);
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius-sm);
  padding: 9px 11px;
  font: inherit;
}
.admin-page input:focus, .admin-page select:focus, .admin-page textarea:focus {
  outline: none;
  border-color: var(--admin-primary);
  box-shadow: var(--admin-focus-ring);
}
.admin-page input[disabled], .admin-page select[disabled],
.admin-page textarea[disabled] { opacity: .6; }
.field { margin-bottom: var(--admin-space-3); }
.field-error { color: var(--admin-danger); font-size: 13px; margin-top: var(--admin-space-1); }

/* =====================================================================
   Tabelle
   ===================================================================== */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}
.table th, .table td {
  padding: 8px 6px;
  text-align: center;
  border-bottom: 1px solid var(--admin-border);
}
.table th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .3px;
  color: var(--admin-text-secondary);
  font-weight: 700;
}
.table td.l, .table th.l { text-align: left; }
.table tbody tr:nth-child(even) { background: var(--admin-background); }
.table tbody tr.is-first td { font-weight: 700; }

/* =====================================================================
   Badge
   ===================================================================== */
.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  background: var(--admin-background);
  color: var(--admin-text-secondary);
  border: 1px solid var(--admin-border);
}
.badge-success { color: var(--admin-success); border-color: var(--admin-success); }
.badge-warning { color: var(--admin-warning); border-color: var(--admin-warning); }
.badge-danger  { color: var(--admin-danger);  border-color: var(--admin-danger); }
.badge-info    { color: var(--admin-info);    border-color: var(--admin-info); }

/* =====================================================================
   Hinweiskasten - stehend (.notice) und fluechtig (.toast)
   ===================================================================== */
.notice {
  border: 1px solid var(--admin-border);
  border-left-width: 4px;
  border-radius: var(--admin-radius-sm);
  padding: var(--admin-space-2) var(--admin-space-3);
  background: var(--admin-surface);
  color: var(--admin-text-primary);
}
.notice-info    { border-left-color: var(--admin-info); }
.notice-success { border-left-color: var(--admin-success); }
.notice-warning { border-left-color: var(--admin-warning); }
.notice-danger  { border-left-color: var(--admin-danger); }

.toast {
  position: fixed;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  background: var(--admin-text-primary);
  color: var(--admin-surface);
  padding: 9px 16px;
  border-radius: var(--admin-radius-sm);
  font-size: 13.5px;
  opacity: 0;
  transition: opacity .2s;
  z-index: 80;
}
.toast.show { opacity: 1; }

/* =====================================================================
   Abstaende und Textfarben
   ===================================================================== */
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: var(--admin-space-1); }
.mt-2 { margin-top: var(--admin-space-2); }
.mt-3 { margin-top: var(--admin-space-3); }
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: var(--admin-space-1); }
.mb-2 { margin-bottom: var(--admin-space-2); }
.mb-3 { margin-bottom: var(--admin-space-3); }

.muted        { color: var(--admin-text-secondary); font-size: 13px; }
.text-success { color: var(--admin-success); }
.text-danger  { color: var(--admin-danger); }
.text-warning { color: var(--admin-warning); }

/* =====================================================================
   Obere Navigationsleiste  (Guideline 11, Design 5)
   ---------------------------------------------------------------------
   Struktur und Verhalten stehen in Guideline 11; die Farben kommen
   ausschliesslich aus den Token dieser Datei. Dieselben Klassennamen
   gelten im anderen Theme - eine Komponente, zwei Welten.

   Jede Regel haengt am Weltrahmen `.topbar-admin`. Sonst entscheidet die
   Ladereihenfolge der Stylesheets ueber die Welt statt das Markup.

   §9 ist hier die harte Regel: die Leiste bricht NIE um. Der Bestand tat
   genau das - `.ua-top` schaltete unter 760px auf `flex-wrap: wrap` und
   wurde zweizeilig, `.topbar` der Liga-Seiten unter 680px ebenso.
   ===================================================================== */
.topbar-admin .topbar {
  display: flex;
  align-items: center;
  gap: var(--admin-space-2);
  flex-wrap: nowrap;              /* §9: kein mehrzeiliger Header */
  min-width: 0;
  padding: var(--admin-space-2) var(--admin-space-3);
  background: var(--admin-surface);
  border-bottom: 1px solid var(--admin-border);
  color: var(--admin-text-primary);
  font-family: var(--admin-font);
  font-size: var(--admin-font-size);
  position: relative;
}

/* §4: Marke und Schriftzug sind die Home-Navigation. */
.topbar-admin .topbar-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--admin-space-1);
  font-weight: 800;
  font-size: 18px;
  text-decoration: none;
  color: var(--admin-text-primary);
  white-space: nowrap;
  flex: 0 0 auto;
}
.topbar-admin .topbar-brand img { height: 28px; width: auto; display: block; }
.topbar-admin .topbar-spacer { flex: 1 1 auto; min-width: 0; }

/* §5.2: der Anzeigename. Er darf schrumpfen, bevor die Leiste umbricht. */
.topbar-admin .topbar-user {
  color: var(--admin-text-secondary);
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* §5.1: nur auf "Mein Bereich". §9: Badges duerfen die Hoehe nicht treiben. */
.topbar-admin .topbar-badges {
  display: inline-flex;
  align-items: center;
  gap: var(--admin-space-1);
  flex: 0 0 auto;
}
.topbar-admin .topbar-badges > * { max-height: 30px; }

.topbar-admin .topbar-item {
  display: inline-flex;
  align-items: center;
  padding: 8px 13px;
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius-sm);
  background: transparent;
  color: var(--admin-text-primary);
  text-decoration: none;
  font: inherit;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
  flex: 0 0 auto;
}
.topbar-admin .topbar-item:hover { border-color: var(--admin-primary); }
.topbar-admin .topbar-item-primary {
  background: var(--admin-primary);
  border-color: var(--admin-primary);
  color: var(--admin-primary-text);
}
.topbar-admin .topbar-item:focus-visible,
.topbar-admin .topbar-menu-btn:focus-visible,
.topbar-admin .topbar-back:focus-visible { outline: none; box-shadow: var(--admin-focus-ring); }

/* §7: das Drei-Punkte-Menue. Ueber 1080px gibt es es nicht. */
.topbar-admin .topbar-menu-btn {
  display: none;
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius-sm);
  background: transparent;
  color: var(--admin-text-primary);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.topbar-admin .topbar-menu {
  position: absolute;
  top: 100%;
  right: var(--admin-space-3);
  z-index: 70;
  min-width: 200px;
  display: flex;
  flex-direction: column;
  /* Flaeche, nicht "elevated": in der Spiel-Welt ist --game-surface-elevated
     ein HELLES Grau (#8c8c8c). Weisse Schrift darauf ergaebe 2.4:1. */
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius);
  padding: var(--admin-space-1);
}
.topbar-admin .topbar-menu-user {
  padding: 8px 12px;
  color: var(--admin-text-secondary);
  font-size: 13px;
  border-bottom: 1px solid var(--admin-border);
}
.topbar-admin .topbar-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  border: none;
  background: transparent;
  color: var(--admin-text-primary);
  text-decoration: none;
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  border-radius: var(--admin-radius-sm);
}
.topbar-admin .topbar-menu-item:hover {
  background: var(--admin-primary);
  color: var(--admin-primary-text);
}

/* =====================================================================
   Die Kopfzeile UNTER der Leiste  (Guideline 13-Setup §4 und §5)
   ---------------------------------------------------------------------
   Guideline 11 §4 verbietet ein Zurueck IN der Leiste; 13-Setup §4 verlangt
   eines DIREKT DARUNTER, in genau einer Form. Beide Saetze gelten - sie
   sprechen von verschiedenen Zeilen.
   ===================================================================== */
.topbar-admin .topbar-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--admin-space-1) var(--admin-space-3);
  padding: var(--admin-space-3) var(--admin-space-3) 0;
}
.topbar-admin .topbar-back {
  color: var(--admin-text-secondary);
  text-decoration: none;
  font-size: 14px;
  flex: 0 0 auto;
  border-radius: var(--admin-radius-sm);
}
.topbar-admin .topbar-back:hover { color: var(--admin-primary); }
.topbar-admin .topbar-title {
  margin: 0;
  font-size: 20px;
  font-weight: 800;
  color: var(--admin-text-primary);
}
.topbar-admin .topbar-kontext { color: var(--admin-text-secondary); font-size: 13px; }

/* §6/§9: der verbindliche Breakpoint. Darunter uebernimmt das Menue. */
@media (max-width: 1080px) {
  .topbar-admin .topbar-item { display: none; }
  .topbar-admin .topbar-menu-btn { display: inline-flex; align-items: center; justify-content: center; }
  .topbar-admin .topbar-brand { font-size: 16px; }
  .topbar-admin .topbar-brand img { height: 24px; }
}
@media (max-width: 430px) {
  /* §7: reicht der Platz auch dafuer nicht, hat die eine Zeile Vorrang -
     der Name steht dann im Menue, wo er ohnehin schon steht. */
  .topbar-admin .topbar-user { display: none; }
  .topbar-admin .topbar-brand span { display: none; }
}

/* =====================================================================
   Obere Navigationsleiste  (Guideline 11, Design 5)
   ---------------------------------------------------------------------
   Struktur und Verhalten stehen in Guideline 11; die Farben kommen
   ausschliesslich aus den Token dieser Datei. Dieselben Klassennamen
   gelten im anderen Theme - eine Komponente, zwei Welten.

   Jede Regel haengt am Weltrahmen `.topbar-admin`. Sonst entscheidet die
   Ladereihenfolge der Stylesheets ueber die Welt statt das Markup.

   §9 ist hier die harte Regel: die Leiste bricht NIE um. Der Bestand tat
   genau das - `.ua-top` schaltete unter 760px auf `flex-wrap: wrap` und
   wurde zweizeilig, `.topbar` der Liga-Seiten unter 680px ebenso.
   ===================================================================== */
.topbar-admin .topbar {
  display: flex;
  align-items: center;
  gap: var(--admin-space-2);
  flex-wrap: nowrap;              /* §9: kein mehrzeiliger Header */
  min-width: 0;
  padding: var(--admin-space-2) var(--admin-space-3);
  background: var(--admin-surface);
  border-bottom: 1px solid var(--admin-border);
  color: var(--admin-text-primary);
  font-family: var(--admin-font);
  font-size: var(--admin-font-size);
  position: relative;
}

/* §4: Marke und Schriftzug sind die Home-Navigation. */
.topbar-admin .topbar-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--admin-space-1);
  font-weight: 800;
  font-size: 18px;
  text-decoration: none;
  color: var(--admin-text-primary);
  white-space: nowrap;
  flex: 0 0 auto;
}
.topbar-admin .topbar-brand img { height: 28px; width: auto; display: block; }
.topbar-admin .topbar-spacer { flex: 1 1 auto; min-width: 0; }

/* §5.2: der Anzeigename. Er darf schrumpfen, bevor die Leiste umbricht. */
.topbar-admin .topbar-user {
  color: var(--admin-text-secondary);
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* §5.1: nur auf "Mein Bereich". §9: Badges duerfen die Hoehe nicht treiben. */
.topbar-admin .topbar-badges {
  display: inline-flex;
  align-items: center;
  gap: var(--admin-space-1);
  flex: 0 0 auto;
}
.topbar-admin .topbar-badges > * { max-height: 30px; }

.topbar-admin .topbar-item {
  display: inline-flex;
  align-items: center;
  padding: 8px 13px;
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius-sm);
  background: transparent;
  color: var(--admin-text-primary);
  text-decoration: none;
  font: inherit;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
  flex: 0 0 auto;
}
.topbar-admin .topbar-item:hover { border-color: var(--admin-primary); }
.topbar-admin .topbar-item-primary {
  background: var(--admin-primary);
  border-color: var(--admin-primary);
  color: var(--admin-primary-text);
}
.topbar-admin .topbar-item:focus-visible,
.topbar-admin .topbar-menu-btn:focus-visible,
.topbar-admin .topbar-back:focus-visible { outline: none; box-shadow: var(--admin-focus-ring); }

/* §7: das Drei-Punkte-Menue. Ueber 1080px gibt es es nicht. */
.topbar-admin .topbar-menu-btn {
  display: none;
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius-sm);
  background: transparent;
  color: var(--admin-text-primary);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.topbar-admin .topbar-menu {
  position: absolute;
  top: 100%;
  right: var(--admin-space-3);
  z-index: 70;
  min-width: 200px;
  display: flex;
  flex-direction: column;
  /* Flaeche, nicht "elevated": in der Spiel-Welt ist --game-surface-elevated
     ein HELLES Grau (#8c8c8c). Weisse Schrift darauf ergaebe 2.4:1. */
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius);
  padding: var(--admin-space-1);
}
/* Das `hidden`-Attribut MUSS gewinnen. `display: flex` oben ist staerker als
   die Regel `[hidden]{display:none}` des Browsers - ohne diese Zeile stand das
   Menue auf jeder Seite dauerhaft offen, auch am Desktop. Der Rauchtest hat es
   nicht gesehen, weil er nur den KNOPF gemessen hat; sichtbar wurde es erst im
   Screenshot. */
.topbar-admin .topbar-menu[hidden] { display: none; }
.topbar-admin .topbar-menu-user {
  padding: 8px 12px;
  color: var(--admin-text-secondary);
  font-size: 13px;
  border-bottom: 1px solid var(--admin-border);
}
.topbar-admin .topbar-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  border: none;
  background: transparent;
  color: var(--admin-text-primary);
  text-decoration: none;
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  border-radius: var(--admin-radius-sm);
}
.topbar-admin .topbar-menu-item:hover {
  background: var(--admin-primary);
  color: var(--admin-primary-text);
}

/* =====================================================================
   Die Kopfzeile UNTER der Leiste  (Guideline 13-Setup §4 und §5)
   ---------------------------------------------------------------------
   Guideline 11 §4 verbietet ein Zurueck IN der Leiste; 13-Setup §4 verlangt
   eines DIREKT DARUNTER, in genau einer Form. Beide Saetze gelten - sie
   sprechen von verschiedenen Zeilen.
   ===================================================================== */
.topbar-admin .topbar-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--admin-space-1) var(--admin-space-3);
  padding: var(--admin-space-3) var(--admin-space-3) 0;
}
.topbar-admin .topbar-back {
  color: var(--admin-text-secondary);
  text-decoration: none;
  font-size: 14px;
  flex: 0 0 auto;
  border-radius: var(--admin-radius-sm);
}
.topbar-admin .topbar-back:hover { color: var(--admin-primary); }
.topbar-admin .topbar-title {
  margin: 0;
  font-size: 20px;
  font-weight: 800;
  color: var(--admin-text-primary);
}
.topbar-admin .topbar-kontext { color: var(--admin-text-secondary); font-size: 13px; }

/* §6/§9: der verbindliche Breakpoint. Darunter uebernimmt das Menue. */
@media (max-width: 1080px) {
  .topbar-admin .topbar-item { display: none; }
  .topbar-admin .topbar-menu-btn { display: inline-flex; align-items: center; justify-content: center; }
  .topbar-admin .topbar-brand { font-size: 16px; }
  .topbar-admin .topbar-brand img { height: 24px; }
}
@media (max-width: 430px) {
  /* §7: reicht der Platz auch dafuer nicht, hat die eine Zeile Vorrang -
     der Name steht dann im Menue, wo er ohnehin schon steht. */
  .topbar-admin .topbar-user { display: none; }
  .topbar-admin .topbar-brand span { display: none; }
}

/* =====================================================================
   N4a (Design 7, 10.09.2026): die zwei weissen Zeilen als EINE Einheit
   ---------------------------------------------------------------------
   Die obere Leiste und die Turnier-Toolbar sind beide weiss und gehoeren
   zusammen; die graue Kontextzeile steht darunter. Bis zu den Rauchtests
   auf darthub.ch stand die graue Zeile DAZWISCHEN - Thomas hat das am
   10.09.2026 als Fehler gemeldet.

   Damit die beiden wie eine Flaeche wirken, gibt die obere Leiste ihre
   untere Kante ab, sobald eine Toolbar folgt. Die Kante der Einheit ist
   dann die der Toolbar.
   ===================================================================== */
.topbar-mit-nav .topbar { border-bottom: none; }

/* =====================================================================
   Turnier-Admin-Navigation  (Guideline 13, Design 6)
   ---------------------------------------------------------------------
   Die zweite Zeile unter der oberen Leiste: Status, Turnieraktionen,
   Verwaltungsaktionen (13 §2.1, Teile 3 bis 5). Die ersten beiden Teile -
   Dashboard-Navigation und Turniername - traegt seit Design 5 die obere
   Leiste; N4 hat entschieden, dass Titel und Kontext dort stehen.

   Warum zwei Zeilen und nicht eine: 13 §2.5 verlangt, dass die
   Kopfinformation kompakt sichtbar bleibt, und Guideline 11 §9 verbietet
   den mehrzeiligen Header. Der Bestand hat genau das falsch geloest -
   `.toolbar` in assets/admin.css steht auf `flex-wrap: wrap` und wurde auf
   dem Handy zwei- und dreizeilig.

   Das ⋮-Menue nutzt den Bestandsvertrag aus assets/toolbar_more.js:
   `#tbMoreBtn` und `#tbMore`, auf Desktop `display: contents`. 13 §2.5
   verlangt ausdruecklich "keine separate zweite Mobile-Bedienlogik" - es
   gibt deshalb EINEN Knopf je Aktion, der nur anders dargestellt wird.
   ===================================================================== */
.tnav {
  display: flex;
  align-items: center;
  gap: var(--admin-space-2);
  flex-wrap: nowrap;
  min-width: 0;
  padding: var(--admin-space-2) var(--admin-space-3);
  background: var(--admin-surface);
  border-bottom: 1px solid var(--admin-border);
  font-family: var(--admin-font);
  position: relative;
}

.tnav-status {
  display: inline-flex;
  align-items: center;
  gap: var(--admin-space-1);
  color: var(--admin-text-secondary);
  font-size: 13px;
  flex: 0 0 auto;
}
.tnav-status label { margin: 0; font-size: 13px; }
.tnav-status select {
  width: auto;
  padding: 6px 9px;
  background: var(--admin-surface);
  color: var(--admin-text-primary);
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius-sm);
  font: inherit;
}
.tnav-spacer { flex: 1 1 auto; min-width: 0; }

/* DESIGN 7 (T2, 10.09.2026): DER ⋮-KNOPF IST JETZT IMMER DA.
   Bis heute war er nur unter dem Breakpoint sichtbar, und der Behaelter stand
   am Desktop auf `display: contents` - die Tasten waren direkt Kinder der
   Leiste. Seit die sekundaeren Aktionen (Hilfe, Fehler) auch am Desktop im
   Menue liegen, muss der Behaelter bei JEDER Breite ein aufklappbares Feld
   sein; `display: contents` traegt das nicht.

   Die primaeren Tasten stehen dafuer direkt in der Leiste. Unter 1080px
   verschiebt assets/toolbar_more.js DIESELBEN Knoepfe ins Menue - nicht
   Kopien (13 §2.5). */
.tnav .tb-more-toggle { display: inline-flex; align-items: center; justify-content: center; }
.tnav .tb-more {
  display: none;
  position: absolute;
  top: 100%;
  right: var(--admin-space-3);
  z-index: 40;
  flex-direction: column;
  gap: var(--admin-space-1);
  min-width: 210px;
  max-width: 88vw;
  background: var(--admin-surface-elevated);
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius);
  box-shadow: var(--admin-shadow);
  padding: var(--admin-space-1);
}
.tnav .tb-more.open { display: flex; }
.tnav .tb-more .btn { width: 100%; justify-content: flex-start; text-align: left; }

.tnav .btn { flex: 0 0 auto; white-space: nowrap; }

/* §2.5 und Guideline 11 §6: unter 1080px wandern AUCH die primaeren Aktionen
   ins ⋮-Menue - dieselben Knoepfe, verschoben von toolbar_more.js.

   T2 IST ENTSCHIEDEN (Thomas, 10.09.2026). Design 6 hatte den Breakpoint auf
   1600px gesetzt, weil die Zeile mit den langen Beschriftungen 1554px brauchte;
   damit lagen auf jedem Laptop alle Aktionen hinter dem ⋮. Thomas hat den
   umgekehrten Weg gewaehlt: die Zeile wurde kuerzer (siehe
   lib/TournamentNavSections.php), und der Breakpoint ist wieder der aus
   Guideline 11 - 1080px. */
@media (max-width: 1080px) {
  .tnav .tnav-status { display: none; }
}

/* =====================================================================
   DESIGN 10 (11.09.2026) — der Rest der Admin-Welt
   =====================================================================

   Etappe 3 nimmt den letzten 17 Seiten "admin.css" und "user_area.css" ab.
   Was diese beiden an ALLGEMEINEN Bausteinen trugen, steht ab hier: Dialog,
   Hilfefenster, die Formularreste und die zweiten Schreibweisen der Tasten.
   Was FACHLICH ist - Boards, Gruppen, KO-Baum, Spielerpool -, steht in
   "assets/turnier-admin.css" und gehoert nicht hierher.

   Vier Regeln waren vorher an keiner Stelle definiert, obwohl Seiten sie
   benutzten. Sie sind mit Design 7 und 8 stillschweigend verlorengegangen:
   .help-win (karriere.php, member.php, verein.php) und .modal (verein.php).
   Ein Overlay ohne display:none klappt mitten in der Seite auf.
   tests/etappe3_seiten_test.php Abschnitt 5 haelt das jetzt fest.
   ===================================================================== */

/* ---------------------------------------------------------------------
   DIE BRUECKE IST WEG (Design 19, Etappe 5 Teil 4, 12.09.2026)

   Hier stand ein :root-Block, der zwoelf KURZE Namen auf die Admin-Token
   legte: --bg, --panel, --line, --ink, --muted, --accent, --accent-d,
   --grey, --green, --blue, --red, --shadow. Er speiste die
   Begleit-Stylesheets (member.css, training.css, user_area.css,
   player_search.css, pyramid.css, auth.css), die auf denselben kurzen Namen
   standen.

   WARUM ER WEG MUSSTE: Kurze Namen gehoeren keiner Welt. Dieselben Namen
   beanspruchen theme-game.css und theme-screen.css. Fuenf Spielseiten laden
   BEIDE Themes - checkout121.php, cricket.php, rtc.php, shanghai.php und
   split_score.php -, und dort gewann schlicht das zuletzt geladene. Die
   Notloesung hiess "Admin-Theme immer zuerst laden".

   Sie war nicht nur zerbrechlich, sie war falsch: das Aufklappfeld der
   Spielersuche (player_search.css / .psw-dd) bekam ueber --panel den Wert
   der SPIEL-Welt - ein graues #8c8c8c statt des weissen #ffffff, das
   dieselbe Komponente auf lokal.php zeigte. Gemessen am 12.09.2026,
   21 Abweichungen auf checkout121.php allein.

   WIE ES JETZT LAEUFT: Jede Welt hat ihre eigenen, mit Praefix benannten
   Token. Die Begleit-Stylesheets der Admin-Welt lesen --admin-* direkt.
   pyramid.css und auth.css laufen in mehreren Welten und lesen
   var(--admin-x, var(--kurz)): in der Admin-Welt greift das Token, in der
   oeffentlichen und in der Screen-Welt der kurze Name, den public.css bzw.
   tv.css dort selbst setzen. Diese beiden Dateien sind unberuehrt.

   Geprueft in tests/browser/design19_bruecke.js: je eine Seite aus jeder
   Welt, Stylesheets in beiden Reihenfolgen, gleiches Ergebnis.
   --------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
   Zweite Schreibweisen der Tasten

   admin.css und user_area.css schrieben den Zusatz als eigene Klasse
   (btn ghost), das Theme schreibt ihn angehaengt (btn-secondary). Beide
   Schreibweisen stehen im Bestand, an hunderten Stellen. Sie bekommen hier
   EINE Definition statt zweier - umbenannt wird das Markup nicht, das waere
   ein Suchlauf ohne Gewinn.

   .btn.primary ist der Sonderfall: sie war GRUEN, nicht blau. Sie steht im
   Dialog neben der blauen Abbrechen-Taste; waeren beide blau, sahen sie
   gleich aus. Der richtige Name dafuer ist .btn-success - er steht hier und
   ist die Empfehlung fuer neues Markup. Dass "primary" in der einen
   Schreibweise gruen und in der anderen blau heisst, ist eine Altlast und
   steht als Frage im Bericht.
   --------------------------------------------------------------------- */
.btn.ghost   { background: var(--admin-surface); border-color: var(--admin-border); color: var(--admin-text-primary); }
.btn.ghost:hover { background: var(--admin-background); border-color: var(--admin-border); }
.btn.danger  { background: var(--admin-danger); border-color: var(--admin-danger); color: var(--admin-primary-text); }
.btn.grey    { background: var(--admin-text-secondary); border-color: var(--admin-text-secondary); color: var(--admin-primary-text); }
.btn.small,
.btn.sm      { padding: 7px 11px; font-size: 13px; }
.btn-success,
.btn.primary { background: var(--admin-success); border-color: var(--admin-success); color: var(--admin-primary-text); }
.btn-success:hover,
.btn.primary:hover { background: var(--admin-success); filter: brightness(.94); }

/* ---------------------------------------------------------------------
   Dialog

   Neun Seiten tragen ein .modal im Markup. Der abdunkelnde Grund kam mit
   Design 7 als Token (--admin-overlay) - die Regel selbst stand weiter nur
   in admin.css.
   --------------------------------------------------------------------- */
.modal {
  position: fixed;
  inset: 0;
  background: var(--admin-overlay);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 50;
  padding: var(--admin-space-4);
}
.modal.show { display: flex; }
.modal-box {
  background: var(--admin-surface-elevated);
  color: var(--admin-text-primary);
  border-radius: var(--admin-radius);
  padding: var(--admin-space-4);
  max-width: 640px;
  width: 100%;
  max-height: 90vh;
  overflow: auto;
  box-shadow: var(--admin-shadow);
}
.modal-box h3 { margin: 0 0 var(--admin-space-3); }
.modal-actions {
  display: flex;
  gap: var(--admin-space-2);
  justify-content: flex-end;
  margin-top: var(--admin-space-3);
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------------
   Das schwebende Hilfefenster

   Es war DUNKEL (#0b1220, #131c2e) - die alte Anzeige-Palette, aus der Zeit,
   als auch die Hilfeseiten dunkel waren. D7 hat die Hilfe der Verwaltungswelt
   zugeordnet; der Rahmen folgt jetzt nach.
   --------------------------------------------------------------------- */
.help-win {
  position: fixed;
  inset: 0;
  background: var(--admin-overlay);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.help-win.show { display: flex; }
.help-frame {
  width: 92vw;
  max-width: 1100px;
  height: 88vh;
  background: var(--admin-surface);
  border: 1px solid var(--admin-border);
  border-radius: var(--admin-radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: var(--admin-shadow);
}
.help-frame iframe { flex: 1; width: 100%; border: none; background: var(--admin-surface); }
.help-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--admin-space-2) var(--admin-space-3);
  background: var(--admin-background);
  border-bottom: 1px solid var(--admin-border);
}
.help-title   { font-weight: 700; color: var(--admin-text-primary); }
.help-actions { display: flex; align-items: center; gap: var(--admin-space-3); }
.help-open    { color: var(--admin-primary); text-decoration: none; font-size: 14px; }
.help-open:hover { text-decoration: underline; }
.help-close {
  background: transparent;
  border: none;
  color: var(--admin-text-secondary);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: var(--admin-radius-sm);
}
.help-close:hover { background: var(--admin-background); color: var(--admin-text-primary); }

/* ---------------------------------------------------------------------
   Formular und Kleinteile aus user_area.css

   Design 8 hat diese Regeln in den Style-Block von member.php KOPIERT -
   "nur, was diese Seite benutzt". Bei vierzehn weiteren Seiten waere daraus
   wieder das geworden, wogegen der ganze Umbau geht: dieselbe Regel an
   vierzehn Stellen. Sie stehen deshalb hier, einmal.
   --------------------------------------------------------------------- */
.ua-grid { display: grid; grid-template-columns: 1fr; gap: var(--admin-space-3); }
@media (min-width: 760px) { .ua-grid.two { grid-template-columns: 1fr 1fr; } }

.card .card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--admin-space-2); margin: -2px 0 var(--admin-space-2);
}
.card .card-head h2 { margin: 0; }

.frm { display: grid; grid-template-columns: 1fr; gap: var(--admin-space-2); }
@media (min-width: 560px) {
  .frm.two { grid-template-columns: 1fr 1fr; }
  .fld.full, .fld.span2 { grid-column: 1 / -1; }
}
.fld label { display: block; font-size: 13px; color: var(--admin-text-secondary); margin-bottom: 5px; }
.fld input, .fld textarea, .fld select {
  width: 100%; box-sizing: border-box; padding: 12px;
  border: 1px solid var(--admin-border); border-radius: var(--admin-radius-sm);
  font-size: 15px; font-family: inherit; background: var(--admin-surface);
  color: var(--admin-text-primary);
}
.fld input:focus, .fld textarea:focus, .fld select:focus {
  outline: none; border-color: var(--admin-primary); box-shadow: var(--admin-focus-ring);
}
.fld input[readonly] { background: var(--admin-background); color: var(--admin-text-secondary); }
.fld textarea { min-height: 80px; resize: vertical; }
.fld .hint, .hint { font-size: 12px; color: var(--admin-text-secondary); margin-top: 4px; }

.btnrow { display: flex; flex-wrap: wrap; gap: var(--admin-space-2); margin-top: var(--admin-space-3); }

.msg {
  border-radius: var(--admin-radius-sm); padding: 11px 13px;
  margin: 0 0 var(--admin-space-3); font-size: 14px; display: none;
}
.msg.show { display: block; }
.msg.ok  { background: var(--admin-background); border: 1px solid var(--admin-success); color: var(--admin-success); }
.msg.err { background: var(--admin-background); border: 1px solid var(--admin-danger);  color: var(--admin-danger); }

.uid-box  { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--admin-space-2); }
.uid-code {
  font-size: 24px; font-weight: 800; letter-spacing: 2px;
  font-family: Consolas, ui-monospace, monospace; color: var(--admin-text-primary);
}
.qr-holder {
  background: var(--admin-surface); padding: var(--admin-space-2);
  border: 1px solid var(--admin-border); border-radius: var(--admin-radius);
}
.qr-holder img, .qr-holder canvas { display: block; width: 200px; height: 200px; }

.info-row {
  display: flex; justify-content: space-between; gap: var(--admin-space-2);
  padding: 8px 0; border-top: 1px solid var(--admin-border); font-size: 15px;
}
.info-row:first-of-type { border-top: none; }
.info-row .k { color: var(--admin-text-secondary); }
.info-row .v { font-weight: 600; text-align: right; }

.note-box {
  background: var(--admin-background); border: 1px dashed var(--admin-border);
  border-radius: var(--admin-radius); padding: var(--admin-space-3);
  text-align: center; color: var(--admin-text-secondary);
}
.club-logo {
  width: 64px; height: 64px; border-radius: var(--admin-radius);
  object-fit: cover; border: 1px solid var(--admin-border); background: var(--admin-surface);
}
.hidden { display: none !important; }
.center { text-align: center; }

/* === Setup-Titel (Design 13a) =========================================
   Die oberste Kachel eines Setups: Bild und Name der gewaehlten Spielart,
   darunter der eingestellte Modus. EIN Baustein - er gilt damit fuer
   lokal.php und die fuenf Spielseiten zugleich.

   Nur Token, keine Farbwerte: die Kachel muss in derselben Welt stehen wie
   die Karten darunter, und die wechselt mit dem Theme, nicht mit dieser
   Regel. Das Bild ist ein Zeichen, keine Datei - es waechst mit der
   Schriftgroesse mit statt an einer festen Pixelbreite zu kleben.
   ===================================================================== */
.setup-title {
  display: flex; align-items: center; gap: var(--admin-space-3);
}
.setup-title-bild {
  font-size: var(--admin-icon-title); line-height: 1; flex: 0 0 auto;
}
.setup-title-text { min-width: 0; }
.setup-title-name {
  margin: 0; font-size: 1.25rem; line-height: 1.25;
  color: var(--admin-text-primary);
}
/* Drei Zeilen, von fest nach beweglich: Name, was die Spielart IST, wie sie
   gerade eingestellt ist. Die mittlere kommt aus dem Kontrakt und stand bis
   Design 13a lose ueber der Kachel. */
.setup-title-text2 {
  margin-top: 2px; font-size: 13px; color: var(--admin-text-secondary);
  line-height: 1.3;
}
.setup-title-modus {
  margin-top: 2px; font-size: 13px; font-weight: 600;
  color: var(--admin-text-secondary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Am Telefon steht die Kachel enger. Die Zeichen werden ueber die Token
   kleiner - beide zugleich, in einer Regel, statt an zwei Stellen. Der
   Name darf dabei NICHT umbrechen (Entscheid 13b), die Zeilen darunter
   schon. */
@media (max-width: 480px) {
  :root {
    --admin-icon-tile:  32px;
    --admin-icon-title: 26px;
  }
  .setup-title { gap: var(--admin-space-2); }
  .setup-title-name {
    font-size: 1.1rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .setup-title-modus { white-space: normal; }
}
