/*
 * app.css — die eine servierte Stylesheet-Datei der WVV-Tool-Web-App (F026).
 *
 * Setzt `knowledge/design.md` woertlich um. Gliederung (design.md Abschnitt 9):
 *   1. Tokens (Farben/Typo/Spacing/Radius, Abschnitt 1/3/4)
 *   2. Reset/Basis
 *   3. Layout/Shell (Sidebar/Content, Abschnitt 7)
 *   4. Komponenten (Tabellen/Badges/Buttons/Formulare/Details, Abschnitt 4)
 *   5. Utilities (.sr-only/.table-scroll/.skip-link)
 *
 * Kein Praeprozessor/Build-Schritt (Simplicity First) -- reines CSS mit Custom
 * Properties. Kein externes Font/CDN (NFR-02).
 */

/* ==========================================================================
   1. Tokens
   ========================================================================== */

:root {
  /* Light (Default), design.md Abschnitt 1.2 */
  --color-bg: #f8fafc;
  --color-surface: #ffffff;
  --color-surface-alt: #f1f5f9;
  --color-border: #cbd5e1;
  --color-text: #0f172a;
  --color-text-muted: #475569;

  --color-primary: #0f766e;
  --color-primary-hover: #115e59;
  --color-primary-contrast: #ffffff;
  /* F080: sehr dezenter Hintergrundton fuer .activity-row--relevant (design.md
     Abschnitt 4.1) -- solides, helles Tint statt Alpha (identisches Muster zu
     --color-success-bg/--color-warning-bg/--color-danger-bg im Hell-Theme). */
  --color-primary-bg: #e6f2f1;

  --color-success: #15803d;
  --color-success-bg: #dcfce7;
  --color-warning: #b45309;
  --color-warning-bg: #fef3c7;
  --color-danger: #b91c1c;
  --color-danger-bg: #fee2e2;

  --color-focus-ring: #2563eb;

  /* Typografie (Abschnitt 3.1/3.2) */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", Consolas, monospace;

  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --line-height-tight: 1.25;
  --line-height-body: 1.5;

  /* Spacing (Abschnitt 3.3, Dichte "komfortabel") */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-8: 3rem;

  /* Radius & Rahmen (Abschnitt 3.4) */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-full: 999px;
  --border-width: 1px;

  /* F078: Zeilenhoehe einer Kopfzeile -- traegt den `top`-Versatz der zweiten
     `<thead>`-Zeile bei gruppierten Spaltenkoepfen (design.md Abschnitt 4.1,
     "Gruppierte Spaltenkoepfe"). Der plan.md-Schaetzwert (2.75rem) wurde per
     Playwright/Chromium gegen das tatsaechliche Rendering der Meldungstabelle
     geprueft: eine reale Kopfzeile (th, `--space-2`-Padding + `--font-size-sm`-
     Zeile, einzeilig) ist tatsaechlich 38px = 2.375rem hoch, nicht 2.75rem --
     2.75rem hinterliess beim Scrollen eine sichtbare 6px-Luecke zwischen
     Gruppen- und Unterkopfzeile. Korrigiert auf den gemessenen Wert. */
  --table-header-row-height: 2.375rem;
}

/* Dunkles Erscheinungsbild ohne gespeicherte Praeferenz: Betriebssystem
   entscheidet (design.md Abschnitt 2 Punkt 1). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg: #0f172a;
    --color-surface: #1e293b;
    --color-surface-alt: #334155;
    --color-border: #475569;
    --color-text: #f1f5f9;
    --color-text-muted: #94a3b8;

    --color-primary: #2dd4bf;
    --color-primary-hover: #5eead4;
    --color-primary-contrast: #0f172a;
    --color-primary-bg: rgba(45, 212, 191, 0.16); /* F080, s. Hell-Theme-Kommentar oben */

    --color-success: #4ade80;
    --color-success-bg: rgba(74, 222, 128, 0.16);
    --color-warning: #fbbf24;
    --color-warning-bg: rgba(251, 191, 36, 0.16);
    --color-danger: #f87171;
    --color-danger-bg: rgba(248, 113, 113, 0.16);

    --color-focus-ring: #60a5fa;
  }
}

/* Expliziter Nutzer-Toggle (design.md Abschnitt 2 Punkt 2): uebersteuert die
   Systemeinstellung, unabhaengig vom aktuellen `prefers-color-scheme`. */
:root[data-theme="dark"] {
  --color-bg: #0f172a;
  --color-surface: #1e293b;
  --color-surface-alt: #334155;
  --color-border: #475569;
  --color-text: #f1f5f9;
  --color-text-muted: #94a3b8;

  --color-primary: #2dd4bf;
  --color-primary-hover: #5eead4;
  --color-primary-contrast: #0f172a;
  --color-primary-bg: rgba(45, 212, 191, 0.16); /* F080, s. Hell-Theme-Kommentar oben */

  --color-success: #4ade80;
  --color-success-bg: rgba(74, 222, 128, 0.16);
  --color-warning: #fbbf24;
  --color-warning-bg: rgba(251, 191, 36, 0.16);
  --color-danger: #f87171;
  --color-danger-bg: rgba(248, 113, 113, 0.16);

  --color-focus-ring: #60a5fa;
}

:root[data-theme="light"] {
  --color-bg: #f8fafc;
  --color-surface: #ffffff;
  --color-surface-alt: #f1f5f9;
  --color-border: #cbd5e1;
  --color-text: #0f172a;
  --color-text-muted: #475569;

  --color-primary: #0f766e;
  --color-primary-hover: #115e59;
  --color-primary-contrast: #ffffff;
  --color-primary-bg: #e6f2f1; /* F080, s. :root-Kommentar oben */

  --color-success: #15803d;
  --color-success-bg: #dcfce7;
  --color-warning: #b45309;
  --color-warning-bg: #fef3c7;
  --color-danger: #b91c1c;
  --color-danger-bg: #fee2e2;

  --color-focus-ring: #2563eb;
}

/* ==========================================================================
   2. Reset/Basis
   ========================================================================== */

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

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  line-height: var(--line-height-body);
}

h1,
h2,
h3 {
  line-height: var(--line-height-tight);
}

h1 {
  font-size: var(--font-size-2xl);
}

h2 {
  font-size: var(--font-size-xl);
}

h3 {
  font-size: var(--font-size-lg);
}

a {
  color: var(--color-primary);
}

/* Fliesstext-Links: Unterstreichung als Unterscheidungsmerkmal, nicht nur
   Farbe (design.md Abschnitt 4.6/8). Navigation ueberschreibt dies gezielt. */
main a {
  color: var(--color-primary);
  text-decoration: underline;
}

/* Lange/variable Inhalte brechen um statt den Rahmen zu sprengen (FR-10). */
td,
th,
dd,
p {
  overflow-wrap: break-word;
  word-break: break-word;
}

/* ==========================================================================
   3. Layout/Shell (design.md Abschnitt 7)
   ========================================================================== */

body.app {
  display: flex;
  min-height: 100vh;
}

.app-sidebar {
  flex: 0 0 240px;
  width: 240px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--color-surface);
  border-right: var(--border-width) solid var(--color-border);
  padding: var(--space-4);
}

.app-brand {
  font-weight: 700;
  font-size: var(--font-size-lg);
}

.app-nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.app-nav a {
  text-decoration: none;
  color: var(--color-text);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
}

.app-nav a:hover {
  background: var(--color-surface-alt);
}

.app-nav a[aria-current="page"] {
  background: var(--color-surface-alt);
  color: var(--color-primary);
  font-weight: 600;
}

.app-sidebar-footer {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  border-top: var(--border-width) solid var(--color-border);
  padding-top: var(--space-3);
}

.app-user {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.app-content {
  flex: 1;
  min-width: 0;
  padding: var(--space-5) var(--space-6);
}

.app-content > * {
  max-width: 75rem;
}

/* F079 FR-01/FR-07: Tabellen-Container duerfen deutlich mehr Breite nutzen als
   Fliesstext/Formulare -- Ausnahme von der 75rem-Deckel-Konvention oben, selbst
   aber begrenzt (kein unbeschraenktes Wachstum auf 4K/Ultra-Wide, Begruendung/
   Geometrie: specs/features/F079-tabellen-breite-und-umbruch/plan.md,
   knowledge/design.md Abschnitt 7.1). Hoehere Selektor-Spezifitaet als
   `.app-content > *` durch die zusaetzliche Klasse -- kein `!important` noetig. */
.content-wide {
  max-width: 150rem;
}

/* Responsiver Kollaps < 640px: horizontale Kopfleiste, kein JS (design.md
   Abschnitt 7.3, "Offene Entscheidungen" Punkt 3). */
@media (max-width: 639px) {
  body.app {
    flex-direction: column;
  }

  .app-sidebar {
    position: static;
    width: 100%;
    height: auto;
    flex-direction: row;
    align-items: center;
    overflow-x: auto;
    flex: 0 0 auto;
  }

  .app-nav {
    flex-direction: row;
  }

  .app-sidebar-footer {
    margin-top: 0;
    flex-direction: row;
    border-top: none;
    padding-top: 0;
  }
}

/* Reduziertes Auth-Layout (EC-01): zentrierte Karte, kein Sidebar/Nav. */
body.app-auth {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}

.auth-card {
  width: 100%;
  max-width: 24rem;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-6);
}

/* ==========================================================================
   4. Komponenten (design.md Abschnitt 4)
   ========================================================================== */

/* --- 4.1 Tabellen ------------------------------------------------------- */

table {
  border-collapse: collapse;
  width: 100%;
  background: var(--color-surface);
}

th,
td {
  border: var(--border-width) solid var(--color-border);
  padding: var(--space-2) var(--space-3);
  text-align: left;
  font-size: var(--font-size-sm);
}

th {
  background: var(--color-surface-alt);
  font-weight: 600;
}

th.num,
td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; /* F070 FR-03: ein Zahlenwert bricht nie mitten im Wert um --
                           ueberschreibt gezielt die Basisregel "lange Inhalte brechen
                           um" (Abschnitt 2), die fuer Freitext-Spalten gedacht ist. */
  min-width: 4.5rem; /* F070 FR-03: Untergrenze gegen Zusammenpressen. F079: die
                         fruehere tabellenweite Mindestbreite auf `.table-scroll table`
                         (F042) wurde entfernt -- diese spaltenweite Untergrenze bleibt
                         unabhaengig davon bestehen. */
}

/* F079 FR-05/BR-05: atomare Nicht-Zahlen-Spalten (Datum/Uhrzeit, Kennungen,
   Ja/Nein) -- wie `.num` gegen Zusammenpressen/Umbruch gesichert, aber OHNE
   dessen Rechtsbuendigkeit/`tabular-nums` (die fuer diese Spalten eine
   unerwuenschte Nebenwirkung waere, s. plan.md). */
.cell-nowrap {
  white-space: nowrap;
  min-width: 3rem;
}

/* F079 FR-04/BR-04: Freitext-Spalten (Titel/Name/Beschreibung/Grund) brechen um,
   sobald ihnen die Spalte nicht mehr die volle, ungebrochene Breite zugesteht --
   statt die ganze Tabelle aufzublaehen. `overflow-wrap: anywhere` (nicht nur das
   bereits globale `break-word`, s. Abschnitt 2) ist noetig, weil nur `anywhere`
   von `table-layout: auto` bei der Spaltenbreitenberechnung beruecksichtigt wird
   (EC-05: auch ein einzelnes, sehr langes zusammenhaengendes Token bricht dann bei
   Bedarf). `max-width` haelt eine angenehme Lesebreite, auch wenn der verbreiterte
   Container (`.content-wide`) mehr Platz haette (BR-04). */
.cell-wraptext {
  overflow-wrap: anywhere;
  max-width: 28rem;
  min-width: 8rem; /* F090 FR-06/EC-03: verschiebt den Schwellenwert, ab dem
                       `overflow-wrap: anywhere` mitten im Wort statt an einer
                       Wortgrenze bricht -- 8rem (~128px bei 16px-Basis) fasst ein
                       realistisches deutsches Einzelwort (Vor-/Nachname,
                       "Ummeldung"/"Kapazitaet") bei `--font-size-sm` komfortabel,
                       ohne die bestehende `max-width`-Lesbarkeitsobergrenze relevant
                       einzuschraenken. Reicht die Summe aller Spalten-Mindestbreiten
                       einer Tabelle dennoch nicht (z.B. die 8-spaltige
                       Meldungstabelle bei 375px), bleibt der bestehende
                       `.table-scroll`-Scrollbalken der unveraenderte, akzeptierte
                       Notnagel (design.md Abschnitt 4.1, letzter Absatz) -- BR-04. */
}

/* F078: gruppierte Spaltenkoepfe (zweizeiliger `<thead>`, design.md Abschnitt 4.1,
   "Gruppierte Spaltenkoepfe"). `.table-header-group` markiert die erste, rein
   strukturelle Kopfzeile (kein `data-sort`); Basis-`th`-Regeln (Hintergrund/
   Fettung) gelten bereits generisch, nur die Zentrierung ist neu. */
.table-header-group {
  text-align: center;
}

/* Gruppenuebergang optisch hervorheben (BR-03/F078): staerkere linke Trennlinie,
   generisches Utility -- nicht auf eine einzelne Tabelle beschraenkt. */
.table-group-start {
  border-left-width: 2px;
}

/* Fettung fuer eine einzelne, fachlich hervorzuhebende Kennzahl-Spalte (F078
   BR-03) -- generisches Utility, auf `th`/`td` gleichermassen anwendbar. */
.cell-emphasis {
  font-weight: 600;
}

tbody tr:nth-child(even) {
  background: var(--color-surface-alt);
}

/* Zeilen-Hervorhebung fuer persoenliche Relevanz (F080, design.md Abschnitt 4.1):
   ein dezenter linker Akzentrand + sehr dezenter Hintergrundton, dieselbe
   Sprache wie der aktive Sidebar-Navigationseintrag (.app-nav a[aria-current]
   oben, --color-primary statt einer neu erfundenen Bedeutungsfarbe). Generisches
   Utility, nicht auf eine einzelne Tabelle beschraenkt. `tbody tr.…` matcht
   dieselbe Selektor-Spezifitaet wie `tbody tr:nth-child(even)` oben, damit die
   Hervorhebung auch auf einer geradzahligen (gestreiften) Zeile sichtbar bleibt
   (deklariert danach, gewinnt bei gleicher Spezifitaet). */
tbody tr.activity-row--relevant {
  border-left: 3px solid var(--color-primary);
  background: var(--color-primary-bg);
}

/* Grund-Icon je zutreffendem Kriterium (FR-05), IMMER begleitet von einem
   `.sr-only`-Text gleichen Informationsgehalts (NFR-01) -- das Icon selbst ist
   `aria-hidden="true"` und traegt keine eigenstaendige Bedeutung ohne den Text. */
.activity-relevance-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1em;
  height: 1em;
  margin-right: 0.35em;
  vertical-align: -0.15em;
  color: var(--color-primary);
}

/* Sortierbare Spaltenkoepfe (F027, design.md Abschnitt 6): `data-sort`
   markiert eine Spalte als klickbar sortierbar (Opt-in -- ein `<th>` ohne
   dieses Attribut bleibt ein normaler, nicht-klickbarer Kopf). Die aktive
   Sortierrichtung wird ueber `aria-sort` kommuniziert (NFR-03), zusaetzlich
   ueber ein sichtbares Chevron-Symbol (nicht ausschliesslich Farbe). */
th[data-sort] {
  cursor: pointer;
  user-select: none;
}

th[data-sort]::after {
  content: "";
  display: inline-block;
  width: 0.7em;
  margin-left: 0.4em;
  opacity: 0.6;
}

th[data-sort][aria-sort="ascending"]::after {
  content: "▲";
}

th[data-sort][aria-sort="descending"]::after {
  content: "▼";
}

@media (prefers-reduced-motion: no-preference) {
  th[data-sort]::after {
    transition: opacity 0.15s ease;
  }
}

/* --- 4.2 Badges/Pills ---------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
  padding: 0.125rem 0.625rem;
  border-radius: var(--radius-full);
  font-size: var(--font-size-xs);
  font-weight: 600;
  /* UX-Audit 2026-07-15 (Minor): eine Pille bleibt immer einzeilig, auch bei
     langen Phrasen (z.B. "laeuft noch / unvollstaendig", admin/scrape_runs auf
     schmalen Viewports) -- ein sehr langes Badge scrollt stattdessen mit dem
     umgebenden `.table-scroll`-Container (design.md 4.1), statt intern umzubrechen. */
  white-space: nowrap;
}

.badge-success {
  color: var(--color-success);
  background: var(--color-success-bg);
}

.badge-warning {
  color: var(--color-warning);
  background: var(--color-warning-bg);
}

.badge-neutral {
  color: var(--color-text-muted);
  background: var(--color-surface-alt);
}

.badge-danger {
  color: var(--color-danger);
  background: var(--color-danger-bg);
}

/* --- 4.3 Anmeldestatus-Indikator ------------------------------------------ */
/* F040 (2026-07-11): aktuell in keinem Template mehr referenziert (Turnierliste seit F036,
   Turnier-Detail seit F040) -- reserviertes Muster fuer den ECHTEN, F007-bestaetigten
   registration.status (design.md Abschnitt 4.3). Nicht entfernen. */

.reg-status-indicator {
  display: inline-flex;
  vertical-align: middle;
  margin-right: 0.4em;
}

.reg-status-check {
  color: var(--color-success);
}

/* --- 4.3a Kapazitaets-Ampel (Turnierliste, F094, 2026-07-16) --------------- */
/* Ein weiteres binaeres-plus-neutrales Icon-Muster (analog 4.3): ein kleiner,
   `aria-hidden="true"` gesetzter Farbkreis direkt vor der unveraenderten
   Zahlen-Anzeige der Plaetze-Zelle, IMMER begleitet von einem `.sr-only`-Text
   gleichen Informationsgehalts (nie ausschliesslich Farbe, Abschnitt 8). Vier
   Modifikatoren, ausschliesslich bestehende Farbrollen (Abschnitt 1)
   wiederverwendend -- keine neue Bedeutungsfarbe. Kein `.badge`-Pill (4.2):
   die Plaetze-Spalte ist rechtsbuendig/numerisch, ein Pill wuerde das kompakte
   Layout stoeren und Badge-Farben sind fuer den Turnier-Lebenszyklus reserviert. */
.capacity-indicator {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--radius-full);
  margin-right: 0.35em;
  vertical-align: middle;
}

.capacity-indicator--frei {
  background: var(--color-success);
}

.capacity-indicator--fast-voll {
  background: var(--color-warning);
}

.capacity-indicator--voll {
  background: var(--color-danger);
}

.capacity-indicator--unbekannt {
  background: var(--color-text-muted);
}

/* --- 4.4 Buttons ----------------------------------------------------------- */

.btn {
  display: inline-block;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-width) solid transparent;
  font-weight: 600;
  font-size: var(--font-size-sm);
  cursor: pointer;
  font-family: inherit;
}

.btn-primary {
  background: var(--color-primary);
  color: var(--color-primary-contrast);
}

.btn-primary:hover {
  background: var(--color-primary-hover);
}

.btn-secondary {
  background: transparent;
  border-color: var(--color-border);
  color: var(--color-text);
}

.btn-danger {
  background: var(--color-danger);
  color: var(--color-primary-contrast);
}

/* UX-Audit 2026-07-15 (Blocker): `.tournament-preview-toggle` (F076, Abschnitt 4.10)
   ist eine dezente Info-Affordanz (transparenter Hintergrund, gedaempfte Farbe) und
   braucht denselben Ausschluss wie `.theme-toggle`, sonst gewinnt diese generische
   Regel (hoehere Spezifitaet) und ueberdeckt sie als solide, gefuellte Pille. */
button:not(.btn):not(.theme-toggle):not(.tournament-preview-toggle) {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  font-weight: 600;
  font-size: var(--font-size-sm);
  cursor: pointer;
  font-family: inherit;
}

.theme-toggle {
  background: transparent;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
  align-self: flex-start;
}

/* --- 4.5 Formulare ---------------------------------------------------------- */

form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

form label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
}

input,
select {
  padding: var(--space-2) var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--font-size-base);
  background: var(--color-surface);
  color: var(--color-text);
}

/* Zusaetzliche, fuer sich allein NICHT ausreichende Absicherung (Live-Re-Check F109,
   2026-07-17): verhindert eine volle Streckung nur dort, wo bereits eine Zeilen-Ausrichtung
   greift (.checkbox-group label / .checkbox-field). Fuer ein freistehendes Checkbox-Label OHNE
   eine dieser beiden Klassen ist diese Regel wirkungslos (s. 4.5.4) -- neue Formulare tragen
   deshalb immer .checkbox-field oder .checkbox-group, nie ein blosses input[type=checkbox] in
   einem spaltenorientierten form label. */
input[type="checkbox"] {
  width: auto;
  flex: none;
}

form button[type="submit"] {
  margin-top: var(--space-1);
  align-self: flex-start;
}

.form-error {
  color: var(--color-danger);
  font-size: var(--font-size-sm);
}

.form-hint {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* Kurze Einzelwert-Felder (F103): E-Mail/Benutzername/Passwort -- kein Freitext,
   daher auf denselben Wert wie .combobox-input (4.5.3) begrenzt statt volle
   Formularbreite. */
.account-field {
  width: 100%;
  max-width: 24rem;
}

.flash {
  list-style: none;
  margin: 0 0 var(--space-4) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-alt);
  border-left: 3px solid var(--color-primary);
}

.notice {
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-alt);
  border-left: 3px solid var(--color-primary);
}

.notice-warning {
  border-left-color: var(--color-warning);
  color: var(--color-warning);
}

/* Filter-Formulare (design.md Abschnitt 6): immer sichtbarer Submit-Button,
   `app.js` blendet ihn bei aktivem JS aus. */
.filter-bar {
  flex-direction: row;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.filter-bar label {
  flex-direction: row;
  align-items: center;
  gap: var(--space-2);
}

/* --- 4.5.1 Checkbox-Gruppe (Mehrfachauswahl, F039, design.md 4.5.1) ---------
   Bewusst auf `.checkbox-group` gescopt (NICHT auf den blossen `fieldset`-
   Elementselektor) -- ein ungescopter `fieldset`/`fieldset label`-Selektor
   ueberschreibt sonst ungewollt das Label-ueber-Feld-Layout anderer, bereits
   bestehender `<fieldset>`-Nutzungen (z. B. F037s Partner-Seite,
   `settings/partner.html`, Label-neben-Feld waere dort ein Regressionsfund).
   Nur das Spielklassen- UND (F056) das Ort-Mehrfachauswahl-Fieldset in
   filter.html/filter_form.html tragen diese Klasse. */

.checkbox-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  border: none;
  padding: 0;
  margin: 0;
}

.checkbox-group legend {
  padding: 0;
  margin-bottom: var(--space-1);
  font-size: var(--font-size-sm);
}

.checkbox-group label {
  flex-direction: row;
  align-items: center;
  gap: var(--space-2);
}

/* --- 4.5.4 Einzelne Ja/Nein-Checkbox (kein Mehrfachauswahl-Kriterium, F109) -----------------
   Ergaenzt 4.5.1 (.checkbox-group ist an eine <fieldset>/<legend>-Mehrfachauswahl gebunden und
   fuer ein einzelnes Bool'sches Feld semantisch nicht passend). Dieselbe Zeilen-Ausrichtung wie
   .checkbox-group label -- eine reine width-Korrektur am input[type=checkbox] selbst genuegt
   NICHT, weil form label { flex-direction: column } sein Flex-Kind unabhaengig vom width-Wert
   ueber die Kreuzachse streckt (align-items: stretch, Live-Re-Check 2026-07-17). */
.checkbox-field {
  flex-direction: row;
  align-items: center;
  gap: var(--space-2);
}

/* --- 4.6 Links --------------------------------------------------------------- */

.link-external svg {
  vertical-align: middle;
  margin-left: 0.2em;
}

/* Kleine Sammel-Linklisten (z.B. Einstellungen-Uebersicht): kein Aufzaehlungs-
   Punkt, komfortabler Zeilenabstand -- Review-Fix (Minor): war zuvor
   referenziert, aber nirgends definiert. */
.link-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* --- 4.7 Einklappbare Bereiche ------------------------------------------------ */

details.accordion {
  margin-bottom: var(--space-3);
  border-radius: var(--radius-md);
}

details.accordion summary {
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
  font-weight: 600;
  list-style: none;
}

details.accordion summary::-webkit-details-marker {
  display: none;
}

details.accordion summary::before {
  content: "▸";
  display: inline-block;
  margin-right: var(--space-2);
}

@media (prefers-reduced-motion: no-preference) {
  details.accordion summary::before {
    transition: transform 0.15s ease;
  }
}

details.accordion[open] summary::before {
  transform: rotate(90deg);
}

details.accordion > :not(summary) {
  padding: var(--space-3) var(--space-4);
}

/* --- 4.8 Detail-Metadaten-Grid & Aktionsbereich (F030, design.md
   Abschnitt 11) ------------------------------------------------------------ */

.detail-meta-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5) var(--space-6);
}

.detail-meta-grid__group--primary {
  grid-column: 1 / -1;
}

@media (max-width: 639px) {
  .detail-meta-grid {
    grid-template-columns: 1fr;
  }

  .detail-meta-grid__group--primary {
    grid-column: auto;
  }
}

.detail-actions {
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  margin: var(--space-5) 0;
}

/* F114: Freitext-Hinweisblock (Host-Freitext, design.md Abschnitt 4.7a) --
   bewahrt vom Autor selbst gesetzte Absatzumbrueche (rohe \n aus der Quelle),
   ohne eigene HTML-Erzeugung (kein nl2br, kein |safe). */
.text-block--freitext {
  white-space: pre-line;
  overflow-wrap: break-word;
}

/* --- 4.9 Inline-Paar-Grid + Tier-Hierarchie fuer dt/dd-Paare (F071,
   design.md Abschnitt 11.7) ------------------------------------------------ */

.meta-pairs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--space-4) var(--space-5);
  margin: 0;
}

.meta-pairs > div {
  min-width: 0;
}

.meta-pairs dt {
  margin: 0;
  font-size: var(--font-size-xs);
  font-weight: 500;
  color: var(--color-text-muted);
}

.meta-pairs dd {
  margin: 0;
  font-size: var(--font-size-base);
}

.meta-pairs--emphasized dd {
  font-size: var(--font-size-lg);
  font-weight: 600;
}

.meta-pairs--inline {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--space-2);
  row-gap: var(--space-1);
}

.meta-pairs--inline > div {
  display: inline-flex;
  gap: var(--space-1);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.meta-pairs--inline > div:not(:last-child)::after {
  content: "·";
  margin-left: var(--space-2);
}

.meta-pairs--inline dt,
.meta-pairs--inline dd {
  display: inline;
  margin: 0;
  font-size: inherit;
  color: inherit;
}

.meta-pairs--muted dt,
.meta-pairs--muted dd {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* --- 4.10 Turnier-Vorschau-Karte (F076): Anker-Wrapper (Hover-Ziel), Toggle-
   Button, gemeinsame Karte. Existiert nur im Markup der Aktivitaets-/Meine-
   Spieler-Feeds (Anker/Button) bzw. einmalig in base.html (Karte). --------- */

.tournament-preview-anchor {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.tournament-preview-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  padding: 0;
  border: none;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}

.tournament-preview-toggle:hover,
.tournament-preview-toggle[aria-expanded="true"] {
  color: var(--color-primary);
  background: var(--color-surface-alt);
}

/* position: fixed (NICHT absolute) -- entkommt bewusst dem `overflow: auto` von
   `.table-scroll` (design.md 4.1), in dem die Toggle-Buttons sitzen. Von
   app.js bei jeder Anzeige per `style.top`/`style.left` positioniert. */
.tournament-preview-card {
  position: fixed;
  z-index: 100;
  max-width: 20rem;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

.tournament-preview-card[hidden] {
  display: none;
}

.tournament-preview-card__title {
  margin: 0 0 var(--space-2);
  font-weight: 600;
}

.tournament-preview-card__badge {
  margin-bottom: var(--space-2);
}

.tournament-preview-card__hint {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

/* ==========================================================================
   5. Utilities
   ========================================================================== */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Clientseitig injizierte Sucheingabe je sortier-/filterbarer Tabelle (F027,
   plan.md Design-Entscheidung 5) -- existiert NUR, wenn `app.js` sie zur
   Laufzeit einfuegt, nie im server-gerenderten Markup (FR-07). F064 ergaenzt
   in derselben Toolbar bis zu zwei Facetten-Widgets (.facet-filter,
   s.u.) -- `display: flex` haelt Sucheingabe und Facetten-Buttons in einer
   Zeile (umbricht auf schmalen Viewports). */
.table-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.table-filter-input {
  width: 100%;
  max-width: 20rem;
}

/* Client-seitiger Spalten-Facettenfilter (F064, design.md Abschnitt 6.1) --
   existiert NUR, wenn `app.js` ihn zur Laufzeit einfuegt, nie im
   server-gerenderten Markup (FR-09). Disclosure-Muster: `.facet-filter` ist
   der `position: relative`-Anker, `.facet-filter-panel` wird absolut relativ
   dazu positioniert (analog `.combobox`/`.combobox-listbox`). Die
   Checkbox-Zeilen im Panel wiederverwenden bewusst `.checkbox-group`
   (Abschnitt 4.5.1) -- keine eigene Zeilendarstellung noetig. */
.facet-filter {
  position: relative;
}

.facet-filter-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* F065 FR-05/FR-06: rein CSS-generierte Aufklapp-Affordanz, analog
   `th[data-sort]::after` (Abschnitt "Sortierbare Spaltenkoepfe") -- liest den
   bereits von app.js gepflegten `aria-expanded`-Zustand, kein neues DOM, kein
   Ersatz fuer die ARIA-Semantik (NFR-02). */
.facet-filter-toggle::after {
  content: "▾";
  display: inline-block;
  margin-left: var(--space-1);
}

.facet-filter-toggle[aria-expanded="true"]::after {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: no-preference) {
  .facet-filter-toggle::after {
    transition: transform 0.15s ease;
  }
}

.facet-filter-count {
  font-weight: 600;
  color: var(--color-primary);
}

.facet-filter-panel {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  margin: var(--space-1) 0 0;
  padding: var(--space-3);
  min-width: 12rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

.facet-filter-clear {
  margin-top: var(--space-2);
}

/* F065 Design-Entscheidung 3: "weitere"-Aufklappbereich innerhalb einer
   gruppierten Facette (opt-in ueber `data-facet-primary-values`, z. B. Art).
   Wiederverwendet dieselbe Aufklapp-Konvention wie `details.accordion`
   (Abschnitt 4.7, ▸-Pfeil, 90°-Rotation bei `[open]`), aber eine eigene,
   leichtgewichtige Klasse ohne Hintergrundflaeche/grosszuegiges Padding --
   passend fuer das schmale (`min-width: 12rem`) Facetten-Panel. */
.facet-filter-more {
  margin-top: var(--space-2);
}

.facet-filter-more summary {
  cursor: pointer;
  list-style: none;
}

.facet-filter-more summary::-webkit-details-marker {
  display: none;
}

.facet-filter-more summary::before {
  content: "▸";
  display: inline-block;
  margin-right: var(--space-1);
}

@media (prefers-reduced-motion: no-preference) {
  .facet-filter-more summary::before {
    transition: transform 0.15s ease;
  }
}

.facet-filter-more[open] summary::before {
  transform: rotate(90deg);
}

.facet-filter-more label {
  display: block;
  margin-top: var(--space-1);
}

/* Combobox / Autocomplete-Auswahl (F059, design.md Abschnitt 4.5.3) --
   ersetzt die frueher hier stehende `.player-select-filter`-Regel (F055).
   Existiert NUR, wenn `app.js` sie zur Laufzeit einfuegt, nie im
   server-gerenderten Markup. Hervorhebung einer Listenoption ueber
   `.combobox-option[aria-selected="true"]` -- kein Browser-natives `:focus`
   (der Fokus bleibt im Eingabefeld), zusaetzlich zur ARIA-Semantik
   (`aria-activedescendant`) fuer Screenreader. */
.combobox {
  position: relative;
}

.combobox-input {
  width: 100%;
  max-width: 24rem;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.combobox-listbox {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  right: 0;
  margin: var(--space-1) 0 0;
  padding: 0;
  list-style: none;
  max-height: 16rem;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

.combobox-option {
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
}

.combobox-option[aria-selected="true"] {
  background: var(--color-surface-alt);
  color: var(--color-primary);
}

.combobox-hint {
  padding: var(--space-2) var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  font-style: italic;
}

/* Clientseitig injizierte Sucheingabe je filterbarer Checkbox-Gruppe (F056
   FR-09/NFR-04, design.md Abschnitt 4.5.2) -- existiert NUR, wenn `app.js` sie
   zur Laufzeit einfuegt, nie im server-gerenderten Markup. */
.checkbox-group-filter {
  width: 100%;
  max-width: 20rem;
  margin-bottom: var(--space-2);
}

.table-scroll {
  max-height: 70vh;
  overflow-y: auto;
  overflow-x: auto;
  contain: layout; /* F100: verhindert, dass das Layout-Overflow-Rechteck der Tabelle trotz
                       eigenem overflow-x:auto weiterhin document.documentElement.scrollWidth
                       aufblaeht (Chromium-Verhalten, empirisch verifiziert, s. requirements.md
                       "Assumptions"). Aendert das sichtbare/optisch bereits korrekte Scroll-
                       Verhalten des Containers selbst nicht. */
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  /* F070 FR-04: dezente Scroll-Schatten-Affordanz -- rein CSS, kein JavaScript.
     Die beiden `local`-Ebenen laufen mit dem Tabelleninhalt mit und blenden den
     Rand-Schatten aus, sobald an diesem Rand nichts mehr weiter zu scrollen ist;
     die beiden `scroll`-Ebenen (fixiert am Container) erzeugen den sichtbaren
     Schatten selbst. Ergaenzt, ersetzt nicht, den nativen Scrollbalken (NFR-03:
     keine alleinige Farbcodierung). */
  background:
    linear-gradient(to right, var(--color-surface) 30%, transparent) left,
    linear-gradient(to left, var(--color-surface) 30%, transparent) right,
    linear-gradient(to right, var(--color-border), transparent) left,
    linear-gradient(to left, var(--color-border), transparent) right;
  background-repeat: no-repeat;
  background-color: var(--color-surface);
  background-size: 2rem 100%, 2rem 100%, 0.75rem 100%, 0.75rem 100%;
  background-attachment: local, local, scroll, scroll;
}

/* F079: die frühere, tabellenweite feste Mindestbreite (F042 FR-01/FR-02) wurde
   von dieser Regel entfernt -- sie zwang die GESAMTE Tabelle auf die
   ungebrochene Breite aller Spalten und verhinderte damit jeden Umbruch, selbst
   in einem verbreiterten Container (`.content-wide`). Die "nie
   zusammenpressen"-Garantie liegt jetzt bei der einzelnen Spalte (`.num`/
   `.cell-nowrap`), Freitext-Spalten (`.cell-wraptext`) duerfen umbrechen.
   `table-layout: auto` (Standardwert) verteilt die verfuegbare Breite
   entsprechend, s. knowledge/design.md Abschnitt 4.1. */
.table-scroll table {
  border: none;
}

.table-scroll thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}

/* F078: gruppierte Spaltenkoepfe (zweizeiliger `<thead>`) stapeln beide
   Kopfzeilen beim vertikalen Scrollen gemeinsam sichtbar uebereinander --
   Erweiterung, keine Aenderung, der obigen Regel: nur `<thead>` mit einer
   zweiten `<tr>` sind betroffen (`nth-child(2)`), jede bestehende einzeilige
   Tabelle (Turnierliste, Aktivitaet, Aenderungsprotokoll, ...) bleibt bei
   `top: 0` unveraendert (design.md Abschnitt 4.1). */
.table-scroll thead tr:nth-child(2) th {
  top: var(--table-header-row-height);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--color-primary);
  color: var(--color-primary-contrast);
  padding: var(--space-2) var(--space-4);
  z-index: 100;
}

.skip-link:focus {
  left: 0;
}

/* Einheitlicher Fokus-Ring (design.md Abschnitt 8) -- nie `outline: none` ohne
   Ersatz. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
