:root {
  /* DLRG-Rot – exakt aus dem Vereinslogo (static/img/dlrg-logo.png)
     entnommen (#e30613), damit Header und Logo nahtlos ineinander
     übergehen. Für den Status "Entschuldigt" gibt es bewusst eine eigene
     Farbe (--status-entschuldigt), damit er sich weiterhin klar von
     "Abwesend"/"Urlaub" unterscheidet, statt auch rot zu werden. */
  --brand: #e30613;
  --brand-dark: #a80410;
  --status-entschuldigt: #0057a3;
  --green: #1c8a4c;
  --red: #c0392b;
  --amber: #b8860b;
  /* Kräftiger als die pastelligen Badge-Farben oben, damit die Markierung
     auf der Live-Anzeige/dem Kiosk auch aus einigen Metern Entfernung noch
     klar als "hervorgehoben" erkennbar ist, nicht nur als leichter Tonwert. */
  --ziel-erreicht-bg: #bdeecb;
  --schwimmt-bg: #fff0a3;
  --bg: #f4f6f8;
  --card: #ffffff;
  --text: #1a2733;
  --muted: #63737f;
  --border: #dde3e8;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
}

header.app-header {
  background: var(--brand);
  color: white;
  padding: 14px 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

header.app-header .brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

header.app-header .logo {
  height: 44px;
  width: auto;
  display: block;
  border-radius: 4px;
}

header.app-header h1 {
  font-size: 1.05rem;
  margin: 0;
  font-weight: 600;
}

header.app-header .sub {
  font-size: 0.8rem;
  opacity: 0.85;
}

main {
  max-width: 780px;
  margin: 0 auto;
  padding: 16px;
}

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  margin-bottom: 16px;
}

button {
  font: inherit;
  cursor: pointer;
  border: none;
  border-radius: 8px;
  padding: 10px 16px;
  background: var(--brand);
  color: white;
}

button.secondary {
  background: white;
  color: var(--brand);
  border: 1px solid var(--brand);
}

button:disabled { opacity: 0.5; cursor: not-allowed; }

input, select {
  font: inherit;
  padding: 8px 10px;
  border-radius: 6px;
  border: 1px solid var(--border);
  width: 100%;
}

label { font-size: 0.85rem; color: var(--muted); display: block; margin-bottom: 4px; }

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

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 8px 6px; border-bottom: 1px solid var(--border); font-size: 0.92rem; }
th { color: var(--muted); font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.02em; }

.badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
}
.badge.unbekannt { background: #eceff1; color: var(--muted); }
.badge.anwesend { background: #e2f4e9; color: var(--green); }
.badge.abwesend_manuell { background: #fdeceb; color: var(--red); }
.badge.abwesend_urlaub { background: #fff4dc; color: var(--amber); }
.badge.entschuldigt { background: #eaf1fb; color: var(--status-entschuldigt); }

.btn-mini { padding: 5px 9px; font-size: 0.78rem; border-radius: 6px; }

/* Eltern-Ansicht: Liste der künftigen Kurstage */
.kt-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}
.kt-row:last-child { border-bottom: none; }
.kt-datum { flex: 1 1 160px; font-weight: 600; color: var(--text); font-size: 0.92rem; }
.kt-grund { flex: 1 1 140px; max-width: 200px; }

/* Kursziel erreicht / schwimmt – dieselben Markierungsfarben wie auf
   Live-Anzeige/Kiosk (siehe --ziel-erreicht-bg/--schwimmt-bg oben), hier
   zusätzlich in der internen Übersicht (Matrix) und der Teilnehmer-Liste. */
.kt-row.ziel-erreicht, .matrix td.person-col.ziel-erreicht, #roster-body tr.ziel-erreicht { background: var(--ziel-erreicht-bg); }
.kt-row.schwimmt-status, .matrix td.person-col.schwimmt-status, #roster-body tr.schwimmt-status { background: var(--schwimmt-bg); }
.btn-mini.schwimmt-active { background: var(--schwimmt-bg); color: var(--text); border-color: var(--amber); }
.btn-mini.ziel-active { background: var(--ziel-erreicht-bg); color: var(--text); border-color: var(--green); }

/* Erreichte Kursziele als kleine Chips (seit v67 mehrere pro Teilnehmer
   möglich statt eines einzelnen Häkchens, siehe ParticipantKursziel) –
   dieselbe grüne Markierungsfarbe wie zuvor der "Kursziel erreicht"-Button. */
.kursziel-chips { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.chip.ziel-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--ziel-erreicht-bg); border: 1px solid var(--green);
  border-radius: 999px; padding: 2px 4px 2px 9px; font-size: 0.78rem; color: var(--text);
}
.chip.ziel-chip .chip-remove {
  cursor: pointer; color: var(--muted); font-weight: 700; padding: 0 5px;
  border-radius: 50%; line-height: 1.4;
}
.chip.ziel-chip .chip-remove:hover { background: rgba(0,0,0,0.08); color: var(--red); }

/* Roster beim Scannen: Kursziel/schwimmt-Buttons deutlich von den
   Anwesenheits-Buttons (Anw/Ent/Abw/Url) absetzen – eigene, ganz rechts
   stehende Spalte mit Trennstrich zur Anwesenheit, damit beim schnellen
   Durchklicken der Anwesenheit kein Fehlklick auf die seltener genutzte
   Markierung passiert. */
#roster-body td.roster-markierung {
  border-left: 2px solid var(--border);
  padding: 6px 10px;
  white-space: nowrap;
}
#roster-body td.roster-markierung .btn-mini { margin-right: 6px; }

#reader { width: 100%; max-width: 420px; margin: 0 auto; }

.hint { color: var(--muted); font-size: 0.85rem; }

.flash { padding: 10px 14px; border-radius: 8px; margin-bottom: 12px; font-size: 0.9rem; }
.flash.ok { background: #e2f4e9; color: var(--green); }
.flash.error { background: #fdeceb; color: var(--red); }

.center { text-align: center; }

/* Kursübersicht: Matrix Teilnehmer × Kurstage */
.matrix-wrap { overflow-x: auto; }
table.matrix { border-collapse: collapse; }
table.matrix th, table.matrix td { padding: 6px 10px; border-bottom: 1px solid var(--border); white-space: nowrap; }
table.matrix thead th.date-col { background: var(--brand); color: white; text-align: center; font-weight: 600; }
table.matrix thead th.date-col .hint { color: rgba(255,255,255,0.85); }
.person-col { position: sticky; left: 0; background: var(--card); text-align: left; z-index: 1; box-shadow: 1px 0 0 var(--border); }
thead .person-col { background: var(--brand); color: white; z-index: 2; }

.count-badges { display: flex; gap: 3px; justify-content: center; margin-top: 4px; }
.count-badge { min-width: 18px; padding: 1px 5px; border-radius: 5px; font-size: 0.7rem; font-weight: 700; color: white; text-align: center; }
.count-badge.anwesend { background: var(--green); }
.count-badge.abwesend_manuell { background: var(--red); }
.count-badge.abwesend_urlaub { background: var(--amber); }

.pill-group { display: flex; gap: 3px; }
.pill {
  border: 1px solid var(--border);
  background: white;
  font-size: 0.68rem;
  padding: 4px 7px;
  border-radius: 5px;
  cursor: pointer;
  color: var(--muted);
}
.pill.active.anwesend { background: var(--green); border-color: var(--green); color: white; }
.pill.active.abwesend_manuell { background: var(--red); border-color: var(--red); color: white; }
.pill.active.abwesend_urlaub { background: var(--amber); border-color: var(--amber); color: white; }
.pill.active.entschuldigt { background: var(--status-entschuldigt); border-color: var(--status-entschuldigt); color: white; }

/* Tab-Navigation */
nav.tabs { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
nav.tabs .tab-btn {
  background: white;
  color: var(--brand);
  border: 1px solid var(--brand);
  padding: 10px 16px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.9rem;
}
nav.tabs .tab-btn.active { background: var(--brand); color: white; }

/* Statistik: Auswertung gezielt wählen statt alle Karten gleichzeitig
   untereinander anzuzeigen – bewusst kleiner/zurückhaltender als die
   Haupt-Tabs oben (nav.tabs), damit auf einen Blick klar bleibt, dass das
   eine Auswahl INNERHALB von "Statistik" ist, keine eigene App-Ebene. */
.subtabs { display: flex; gap: 6px; margin-bottom: 4px; flex-wrap: wrap; }
.subtabs .subtab-btn {
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 6px 13px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.82rem;
}
.subtabs .subtab-btn.active { background: var(--brand); color: white; border-color: var(--brand); }

/* /anzeige und /kiosk laufen auf fest eingerichteten Bildschirmen ohne Maus/
   Touch – ein Scrollbalken wäre dort schlicht unbedienbar. fitAnzeigeLists()
   in anzeige.js/kiosk.js sorgt bereits aktiv dafür, dass alle Namenslisten
   in die verfügbare Höhe passen; dieses overflow:hidden ist zusätzlich ein
   harter Sicherheitsnetz-Fallback, falls trotzdem mal ein paar Pixel Rand
   (z.B. Abstände zwischen Kurskarten) über den sichtbaren Bereich hinausgehen
   – dann wird lieber ein winziger Rand unsichtbar abgeschnitten, als dass
   ein Scrollbalken erscheint. Wichtig: NUR auf diesen beiden Kiosk-Seiten
   (Klasse no-scroll-page), nicht global – die Trainer-Ansicht etc. sollen
   ganz normal scrollen können. */
html:has(body.no-scroll-page), body.no-scroll-page { overflow: hidden; height: 100%; }

/* Live-Anzeige (zweiter Monitor) */
/* ALLE heute sichtbaren Kurse (egal ob zeitgleich oder nur zeitlich
   überlappend sichtbar, siehe ANZEIGE_SICHTBAR_MINUTEN_NACH_START im
   Backend) landen nebeneinander in einer Reihe statt untereinander
   gestapelt – so bekommt jeder Kurs die volle Bildschirmhöhe statt sich
   diese mit anderen Kursen teilen zu müssen, was gerade auf schmalen/
   hochkant montierten Bildschirmen deutlich lesbarer ist. flex: 1 1 300px
   teilt die verfügbare Breite gleichmäßig auf, lässt Karten dabei aber
   nicht unter eine noch gut lesbare Mindestbreite schrumpfen. Reicht die
   Breite für alle Kurse in einer Zeile nicht mehr aus (viele Kurse
   gleichzeitig sichtbar), bricht der Rest per flex-wrap automatisch in
   eine weitere Zeile um – fitAnzeigeLists() in anzeige.js/kiosk.js
   erkennt das anhand der tatsächlich gerenderten Position jeder Karte und
   reserviert für nachfolgende Zeilen ausreichend Platz, damit auch die
   letzte Zeile nicht über den Bildschirm hinausragt. */
.anzeige-time-row { display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-start; margin-bottom: 28px; }
.anzeige-time-row .anzeige-course {
  flex: 1 1 300px;
  min-width: 260px;
  margin-bottom: 0;
  border: 2px solid var(--brand-dark);
  border-radius: 16px;
  padding: 16px 16px 18px;
  background: #eef1f5;
}
.anzeige-course h2 { margin-bottom: 4px; }
/* Trainer-Name im Kiosk-Display (".kiosk-trainer-name", siehe kiosk.js):
   bewusst genauso groß wie der Kursname direkt darüber, damit er von
   Eltern auch auf Distanz am Beckenrand gut lesbar ist – 1.5em relativ
   zum selben Eltern-Element (.anzeige-course) wie h2 (kein eigener fester
   Wert), damit beide IMMER exakt gleich groß bleiben, auch wenn sich die
   Größe von h2 mal ändert. Nur im Kiosk, NICHT in der Live-Anzeige
   (dort weiterhin die kleine ".hint"-Zeile) – dort wurde nur die Größe
   im Kiosk gewünscht. */
.anzeige-course .kiosk-trainer-name {
  font-size: 1.5em;
  font-weight: 700;
  color: var(--text);
  margin: -4px 0 10px;
}
/* Bewusst IMMER genau 2 Spalten nebeneinander (nicht auto-fit/minmax), auch
   wenn die Kurskarte durch einen parallel laufenden zweiten Kurs sehr schmal
   wird: mit auto-fit würden die Spalten bei zu wenig Breite untereinander
   stapeln, was die Karte deutlich höher macht, als auf den Bildschirm passt.
   Bei wenig Breite werden die Namenslisten stattdessen automatisch schmaler
   und – falls nötig – von fitAnzeigeLists() (anzeige.js/kiosk.js) auf
   kleinere Schrift/mehr Spalten umgestellt. minmax(0, 1fr) statt minmax(min-content,1fr)
   verhindert, dass eine sehr lange Kurskarte die Grid-Spalten wieder aufbläht. */
.anzeige-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 14px; }
.anzeige-col { border-radius: 12px; padding: 14px; background: var(--card); border: 2px solid var(--border); }
.anzeige-col h3 { margin: 0 0 10px 0; font-size: 1.1rem; display:flex; justify-content:space-between; }
.anzeige-col.unbekannt { border-color: var(--border); }
.anzeige-col.anwesend { border-color: var(--green); }
.anzeige-col.entschuldigt { border-color: var(--status-entschuldigt); }
.anzeige-col.abwesend_urlaub { border-color: var(--amber); }
.anzeige-col.abwesend_manuell { border-color: var(--red); }
/* Live-Anzeige & Kiosk: die Anwesend-/Noch-nicht-da-/Entschuldigt-Summen
   sind auf Distanz (zweiter Monitor, Kiosk-Bildschirm) mit der sonst
   überall verwendeten kleinen .badge-Größe schwer ablesbar – hier deutlich
   größer, unabhängig von den (bewusst kleinen) Status-Badges in der
   Trainer-Ansicht. */
.anzeige-col h3 .badge, .anzeige-subdivider h4 .badge {
  font-size: 1.4rem;
  padding: 3px 15px;
  min-width: 2ch;
}
/* Namenslisten: Standardmäßig eine einfache Liste. Passt eine Liste nicht
   mehr ohne Scrollbalken in die verfügbare Höhe, rechnet fitAnzeigeLists()
   in anzeige.js/kiosk.js live aus, wie viele Spalten nötig sind, und setzt
   dafür per JS display:grid + grid-auto-flow:column direkt auf dem <ul>
   (siehe dort) – CSS column-width wurde bewusst NICHT verwendet, weil es
   nur auf verfügbare BREITE reagiert, nicht auf Höhe, und bei knapper Höhe
   Teilnehmer unbemerkt "verschluckt" statt sie in weitere Spalten zu
   verteilen. .list-compact/.list-tiny sind Ausweichstufen mit kleinerer
   Schrift, die fitAnzeigeLists() zuschaltet, wenn selbst mehrspaltig bei
   normaler Schriftgröße nicht genug Platz in der Breite ist. Die Karte
   selbst wächst in die Breite, wenn Platz ist (z.B. wenn nur ein Kurs
   läuft), siehe .anzeige-time-row .anzeige-course. */
.anzeige-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* white-space: nowrap + text-overflow: ellipsis ist hier keine Kosmetik,
   sondern PFLICHT für die JS-Einpassung (fitAnzeigeLists() in
   anzeige.js/kiosk.js): die rechnet mit einer einheitlichen Zeilenhöhe pro
   Liste. Dürfte ein langer Vor-/Nachname (z.B. "Sareena Raveendralingam")
   in einer schmalen Spalte umbrechen, wäre diese eine Zeile plötzlich
   doppelt so hoch wie angenommen – die ganze Höhenrechnung würde nicht mehr
   stimmen und Namen könnten wieder (unsichtbar) über den Rand hinausragen.
   Ein zu langer Name wird stattdessen mit „…" abgeschnitten – klar lesbar
   schlechter als der volle Name, aber niemals unsichtbar. */
.anzeige-col li {
  padding: 5px 0;
  font-size: 1.1rem;
  border-bottom: 1px solid var(--border);
  break-inside: avoid;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.anzeige-col li:last-child { border-bottom: none; }
.anzeige-col ul.list-compact li { padding: 3px 0; font-size: 0.88rem; }
.anzeige-col ul.list-tiny li { padding: 1px 0; font-size: 0.74rem; }
/* Kursziel erreicht / schwimmt – reine Hintergrundfarbe, verändert
   bewusst keine Höhe/Breite/Schrift, damit die JS-Einpassung oben
   (einheitliche Zeilenhöhe pro Liste) davon unberührt bleibt. */
.anzeige-col li.ziel-erreicht { background: var(--ziel-erreicht-bg); }
.anzeige-col li.schwimmt-status { background: var(--schwimmt-bg); }
.anzeige-empty { color: var(--muted); font-size: 1rem; }
.anzeige-clock { font-size: 1rem; opacity: 0.85; }

/* Trennlinie innerhalb der "Anwesend"-Spalte, darunter die entschuldigten/
   Urlaub-Kinder – zusammengelegt statt eigener Spalte. */
.anzeige-subdivider {
  border-top: 2px dashed var(--border);
  margin: 12px 0 8px;
  padding-top: 8px;
}
.anzeige-subdivider h4 { margin: 0; font-size: 0.95rem; color: var(--status-entschuldigt); display: flex; justify-content: space-between; }

/* Scan-Popup auf der Live-Anzeige: großer Hinweis bei jedem Scan */
#scan-popup {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px;
  font-size: 6rem;
  font-weight: 800;
  color: white;
  z-index: 1000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}
#scan-popup.show { opacity: 1; }
#scan-popup.ok { background: var(--green); }
#scan-popup.error { background: var(--red); font-size: 3.2rem; }

@media (max-width: 900px) {
  #scan-popup.ok { font-size: 3.5rem; }
  #scan-popup.error { font-size: 2rem; }
}

/* Scan-Leiste unten fest auf der Kiosk-Seite (/kiosk) – schlanker Streifen
   mit nur dem Scan-Feld, damit der Bildschirm überwiegend die große
   Live-Übersicht zeigt statt der vollen Trainer-Bedienoberfläche. */
#kiosk-scan-bar {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  align-items: center;
  gap: 16px;
  background: var(--card);
  border-top: 3px solid var(--brand);
  padding: 14px 24px;
  box-shadow: 0 -4px 14px rgba(0, 0, 0, 0.12);
  z-index: 400;
}
#kiosk-scan-bar label { width: auto; flex-shrink: 0; color: var(--muted); font-size: 0.9rem; }
#kiosk-scan-bar input {
  flex: 1;
  font-size: 1.3rem;
  padding: 12px 16px;
}
#kiosk-scan-bar span {
  flex-shrink: 0;
  font-size: 1.05rem;
  min-width: 220px;
  text-align: right;
}

@media (max-width: 700px) {
  #kiosk-scan-bar { flex-wrap: wrap; }
  #kiosk-scan-bar label { display: none; }
  #kiosk-scan-bar span { width: 100%; text-align: left; min-width: 0; }
}
