/* ============================================================
   TSC Wämpledon – "Doppelfehler international" – Designsystem
   Durchgängig dunkles Wimbledon-Theme (Grün/Gold/Lila).
   Ball-Cursor: Gold statt Gelb.
   ============================================================ */

:root {
    --gruen: #00704A;
    --gruen-hell: #28B463;
    --lila: #7B68A6;
    /* Helle Variante analog zu --gruen-hell: --lila selbst ist als kleiner
       Text auf dem dunklen Grund zu kontrastarm (Nav-Label, aktive Links). */
    --lila-hell: #9B8AC4;
    --gold: #D4AF37;

    --ink: #0A0E18;
    --ink-soft: #0F1420;
    --ink-line: rgba(0, 112, 74, .18);

    --seite: #0A0E18;
    --flaeche: #151C2E;
    --flaeche-2: rgba(255, 255, 255, .05);
    --linie: rgba(0, 112, 74, .2);
    --linie-stark: rgba(0, 112, 74, .38);

    --text: #E8EDF5;
    --text-2: #A6ADBB;
    --text-3: #7B8395;

    --gelb: var(--gruen-hell);
    --gelb-tief: #06210F;
    --gelb-tint: rgba(40, 180, 99, .16);

    --gold-tief: #0A0E18;
    --gold-tint: rgba(212, 175, 55, .16);

    --lila-tint: rgba(123, 104, 166, .16);
    --rot: #E5484D;
    --rot-tint: rgba(229, 72, 77, .14);

    --r: 14px;
    --r-klein: 10px;
    /* Die Ballgrafik einmal als reines Bild - so kann sie sowohl der Cursor
       als auch jede Deko-Animation nutzen (Ball im Button, Netzroller,
       Streuball). --ball haengt nur noch die Hotspot-Koordinaten an. */
    --ball-bild: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOCIgaGVpZ2h0PSIyOCIgdmlld0JveD0iMCAwIDI4IDI4Ij4KPGNpcmNsZSBjeD0iMTQiIGN5PSIxNCIgcj0iMTIiIGZpbGw9IiNENEFGMzciIHN0cm9rZT0iIzBBMEUxOCIgc3Ryb2tlLXdpZHRoPSIxLjIiLz4KPHBhdGggZD0iTTMuNSA2IFExNCAxNCAzLjUgMjIiIHN0cm9rZT0iIzBBMEUxOCIgc3Ryb2tlLXdpZHRoPSIxLjYiIGZpbGw9Im5vbmUiLz4KPHBhdGggZD0iTTI0LjUgNiBRMTQgMTQgMjQuNSAyMiIgc3Ryb2tlPSIjMEEwRTE4IiBzdHJva2Utd2lkdGg9IjEuNiIgZmlsbD0ibm9uZSIvPgo8L3N2Zz4=");
    --ball: var(--ball-bild) 14 14;
}

* { box-sizing: border-box; }

/* Sicherheitsnetz: ein <img> ohne eigene Größenregel darf nie breiter als
   sein Container werden (z.B. wenn ein hochgeladenes Foto sehr groß ist).
   Elemente mit eigener Breiten-/Höhenregel (.thumb, .artikel-bild img, ...)
   sind spezifischer und überschreiben das ganz normal. */
img { max-width: 100%; height: auto; }

body {
    font-family: 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, Inter, Roboto, sans-serif;
    background: var(--seite);
    color: var(--text);
    margin: 0;
    padding: 0;
    -webkit-font-smoothing: antialiased;
    cursor: var(--ball), auto;
}

a, button, .btn, label, select, summary,
input[type=checkbox], input[type=radio], input[type=submit] {
    cursor: var(--ball), pointer;
}

input[type=text], input[type=password], input[type=email], input[type=url],
input[type=number], input[type=datetime-local], input[type=date], input[type=time],
textarea { cursor: text; }

h1, h2, h3 {
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.7px;
    line-height: 1.15;
}

h1 { font-size: 1.9rem; margin: 0 0 1.2rem; letter-spacing: -1.1px; }
h2 { font-size: 1.15rem; margin: 0 0 0.6rem; }
h3 { font-size: 0.95rem; margin: 1.4rem 0 0.5rem; }

p { line-height: 1.6; }

/* ---------- Topbar (Glasnavbar wie auf der Startseite) ---------- */
header.topbar {
    background: rgba(10, 14, 24, .82);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    color: #fff;
    padding: 0.85rem 1.6rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    position: sticky;
    top: 0;
    z-index: 100;
    border-bottom: 1px solid var(--linie);
}

header.topbar .marke,
header.topbar strong {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
    font-style: normal;
}

header.topbar .marke-name,
header.topbar strong {
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: -0.3px;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

header.topbar .marke-name::before,
header.topbar strong::before {
    content: "";
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: #fff url("../waempledon_logo.png") center / 72% no-repeat;
    flex-shrink: 0;
    transition: transform .6s cubic-bezier(.34, 1.56, .64, 1);
}

header.topbar .marke-name:hover::before,
header.topbar strong:hover::before {
    transform: rotate(360deg);
}

@media (prefers-reduced-motion: reduce) {
    header.topbar .marke-name:hover::before,
    header.topbar strong:hover::before { transform: none; }
}

header.topbar .marke-tag {
    font-size: 0.66rem;
    color: var(--gold);
    letter-spacing: 0.04em;
    margin-left: 1.15rem;
}

header.topbar a {
    color: var(--text-2);
    text-decoration: none;
    margin-left: 1.1rem;
    font-size: 0.83rem;
    transition: color .15s ease;
}

header.topbar a:hover { color: #fff; }

header.topbar a:last-child {
    background: var(--gruen);
    color: #fff;
    padding: 0.45rem 1rem;
    border-radius: 999px;
    transition: background .2s ease, transform .2s ease;
}

header.topbar a:last-child:hover {
    background: var(--gruen-hell);
    transform: translateY(-1px);
}

header.topbar a.marke,
header.topbar a.marke-link {
    color: inherit;
    text-decoration: none;
}

header.topbar a.marke:hover,
header.topbar a.marke-link:hover {
    color: inherit;
    text-decoration: none;
}

/* ---------- Layout ---------- */
.container {
    max-width: 1000px;
    margin: 2.2rem auto;
    padding: 0 1.2rem;
}

.card {
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--r);
    padding: 1.4rem 1.5rem;
    margin-bottom: 1rem;
    transition: border-color .2s ease;
}

.login-box {
    max-width: 400px;
    margin: 4.5rem auto;
    padding: 2rem;
    text-align: center;
}

.login-marke {
    display: inline-flex;
    flex-direction: column;
    margin-bottom: 1.4rem;
}
.login-marke .name {
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: -0.3px;
    color: var(--text);
}
.login-marke .tag {
    font-size: 0.72rem;
    color: var(--gold);
    letter-spacing: 0.04em;
    margin-top: 0.2rem;
}

.login-box h1 { text-align: left; }
.login-box form { text-align: left; }

/* Bento-Grid für Dashboards */
.bento {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.bento .card { margin-bottom: 0; }

.stat {
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--r);
    padding: 1.1rem 1.2rem;
}

a.stat {
    display: block;
    color: inherit;
    text-decoration: none;
    transition: transform .12s ease, border-color .15s ease;
}

a.stat:hover {
    color: inherit;
    text-decoration: none;
    border-color: var(--linie-stark);
    transform: translateY(-1px);
}

.stat-zahl {
    font-size: 1.9rem;
    font-weight: 600;
    letter-spacing: -1.2px;
    line-height: 1;
    margin: 0;
    color: var(--text);
}

.stat-label {
    color: var(--text-3);
    font-size: 0.78rem;
    margin: 0.4rem 0 0;
}

.karte-gelb {
    background: linear-gradient(145deg, var(--gold), #B8912B);
    border-color: var(--gold);
    color: var(--gold-tief);
}

.karte-gelb h2, .karte-gelb .stat-zahl { color: var(--gold-tief); }
.karte-gelb p, .karte-gelb .stat-label { color: rgba(10, 14, 24, .72); }
.karte-gelb .btn { background: var(--gold-tief); border-color: var(--gold-tief); color: #fff; }
.karte-gelb .btn:hover { background: #000; }

/* ---------- Formulare ---------- */
label {
    display: block;
    margin: 1rem 0 0.35rem;
    font-weight: 600;
    font-size: 0.82rem;
    color: var(--text-2);
}

input[type=text], input[type=password], input[type=number],
input[type=email], input[type=url], input[type=datetime-local],
input[type=date], input[type=time],
textarea, select {
    width: 100%;
    padding: 0.65rem 0.8rem;
    border: 1px solid var(--linie);
    border-radius: var(--r-klein);
    font-size: 0.95rem;
    background: rgba(255, 255, 255, .04);
    font-family: inherit;
    color: var(--text);
    transition: background .15s ease, box-shadow .15s ease, border-color .15s ease;
}

input::placeholder, textarea::placeholder { color: var(--text-3); }

input:hover, textarea:hover, select:hover { border-color: var(--linie-stark); }

input:focus, textarea:focus, select:focus {
    outline: none;
    background: rgba(255, 255, 255, .06);
    border-color: var(--gruen-hell);
    box-shadow: 0 0 0 3px var(--gelb-tint);
}

textarea { resize: vertical; min-height: 90px; line-height: 1.5; }

input[type=file] { font-size: 0.85rem; color: var(--text-2); }

select option { background: var(--flaeche); color: var(--text); }

/* ---------- Buttons ---------- */
button, .btn {
    display: inline-block;
    background: var(--gruen);
    color: #fff;
    border: 1px solid var(--gruen);
    padding: 0.62rem 1.3rem;
    border-radius: 999px;
    font-size: 0.88rem;
    font-weight: 600;
    font-family: inherit;
    letter-spacing: -0.1px;
    text-decoration: none;
    margin-top: 1rem;
    transition: transform .12s ease, box-shadow .15s ease, background .15s ease;
}

button:hover, .btn:hover {
    background: var(--gruen-hell);
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(0, 112, 74, .4);
}

button:active, .btn:active { transform: translateY(0); box-shadow: none; }

.btn-hell {
    background: var(--flaeche-2);
    color: var(--text);
    border: 1px solid var(--linie-stark);
}

.btn-hell:hover { background: rgba(255, 255, 255, .09); color: var(--text); box-shadow: none; }

.btn-gelb {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--gold-tief);
}

.btn-gelb:hover { background: #E4C158; color: var(--gold-tief); box-shadow: 0 6px 18px rgba(212, 175, 55, .35); }

/* ---------- Meldungen ---------- */
.fehler, .erfolg {
    padding: 0.8rem 1rem;
    border-radius: var(--r-klein);
    margin: 1rem 0;
    font-size: 0.9rem;
    border: 1px solid transparent;
}

.fehler { background: var(--rot-tint); color: var(--rot); border-color: rgba(229, 72, 77, .3); }
.erfolg { background: var(--gelb-tint); color: var(--gruen-hell); border-color: rgba(40, 180, 99, .3); }

/* ---------- Tabellen ---------- */
table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 0.8rem;
}

/* Auf schmalen Screens würde eine breite Tabelle sonst die ganze Seite
   horizontal aufreißen - stattdessen scrollt nur die Tabelle selbst. */
@media (max-width: 760px) {
    table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

th, td {
    text-align: left;
    padding: 0.7rem 0.6rem;
    border-bottom: 1px solid var(--linie);
    font-size: 0.88rem;
    color: var(--text);
}

th {
    font-weight: 600;
    font-size: 0.72rem;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--text-3);
    border-bottom: 1px solid var(--linie-stark);
}

tbody tr:hover td, tr:hover td { background: rgba(255, 255, 255, .03); }
td:last-child, th:last-child { text-align: right; }

/* ---------- Status-Pills ---------- */
.tag {
    display: inline-block;
    font-size: 0.73rem;
    font-weight: 600;
    padding: 0.25rem 0.6rem;
    border-radius: 999px;
    white-space: nowrap;
}

.tag-gelb    { background: var(--gruen-hell); color: var(--gelb-tief); }
.tag-lila    { background: var(--lila-tint); color: #C9BEDF; }
.tag-neutral { background: rgba(255, 255, 255, .07); color: var(--text-2); }
.tag-inaktiv { color: var(--text-3); font-size: 0.85rem; }

/* ---------- Sonstiges ---------- */
.thumb {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: var(--r-klein);
    border: 1px solid var(--linie);
}

a { color: var(--lila); text-decoration: none; }
a:hover { text-decoration: underline; color: #9686C4; }

.aktionen a { margin-left: 0.7rem; font-size: 0.83rem; }
.aktionen a.loeschen { color: var(--rot); }
.byline { color: var(--text-3); font-size: 0.8rem; }

hr { border: none; border-top: 1px solid var(--linie); margin: 1.2rem 0; }

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0;
    margin-right: 8px;
    vertical-align: middle;
    flex-shrink: 0;
}

.avatar-name { display: inline-flex; align-items: center; }

@keyframes auf {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

.card, .stat { animation: auf .35s ease both; }

/* ============================================================
   Abstimmungen: Ergebnisbalken
   ============================================================ */
.abst-option { margin-bottom: 1rem; }
.abst-option:last-child { margin-bottom: 0; }

.abst-option-kopf {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.6rem;
    font-size: 0.92rem;
    margin-bottom: 0.35rem;
}

.abst-option-text { font-weight: 600; }
.abst-option-stimmen { color: var(--text-3); font-size: 0.8rem; white-space: nowrap; }

.abst-balken {
    background: var(--flaeche-2);
    border-radius: 999px;
    height: 10px;
    overflow: hidden;
}

.abst-balken-fuellung {
    background: var(--gruen-hell);
    height: 100%;
    border-radius: 999px;
    transition: width .4s ease;
}

.abst-option.abst-meins .abst-option-text { color: var(--gruen-hell); }
.abst-option.abst-meins .abst-balken-fuellung { background: var(--gold); }

.abst-waehler { margin: 0.35rem 0 0; }

.abst-option-titel { display: flex; align-items: center; gap: 0.5rem; }

.abst-rang {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.6rem;
    height: 1.6rem;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--flaeche-2);
    color: var(--text-2);
    font-size: 0.78rem;
    font-weight: 700;
}

.abst-option.abst-platz-1 .abst-rang { background: var(--gold); color: #08090B; }
.abst-option.abst-platz-1 .abst-balken-fuellung { background: var(--gold); }

/* ============================================================
   Termine: Ansichtswechsel, Filter, Liste, Kalender
   ============================================================ */

.ansicht-schalter {
    display: inline-flex;
    background: var(--flaeche-2);
    border: 1px solid var(--linie);
    border-radius: 999px;
    padding: 3px;
    margin-bottom: 1rem;
    gap: 2px;
}

.ansicht-schalter a, .ansicht-schalter .aktiv {
    padding: 0.4rem 1.1rem;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    color: var(--text-2);
}

.ansicht-schalter .aktiv { background: var(--gruen); color: #fff; }
.ansicht-schalter a:hover { color: var(--text); text-decoration: none; }

.filter-leiste {
    display: flex;
    gap: 0.7rem;
    flex-wrap: wrap;
    align-items: flex-end;
}

.filter-leiste > div { flex: 1; min-width: 130px; }
.filter-leiste label { margin-top: 0; }

.sammelleiste {
    display: flex;
    gap: 0.9rem;
    align-items: center;
    flex-wrap: wrap;
    position: sticky;
    top: 66px;
    z-index: 5;
    background: var(--flaeche);
}

.termin-kopf {
    display: flex;
    gap: 0.8rem;
    align-items: flex-start;
    flex-wrap: wrap;
}

.termin-datum {
    font-size: 0.78rem;
    color: var(--lila);
    font-weight: 600;
    letter-spacing: 0.2px;
}

.termin h2 { font-size: 1.05rem; }
.termin.vergangen { opacity: 0.55; }

/* Platz für den fixen Header, damit ein Sprung zu einer Karte (z.B. aus dem
   Kalender oder dem "Offene Aufgaben"-Hinweis im Dashboard) sie nicht unter
   der Topbar versteckt, plus kurze Hervorhebung des Sprungziels. */
.card { scroll-margin-top: 90px; }

.card:target {
    border-color: var(--gruen-hell);
    box-shadow: 0 0 0 3px var(--gelb-tint);
}

.termin-aktionen {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 0.9rem;
}

details summary {
    font-size: 0.8rem;
    color: var(--text-3);
    cursor: var(--ball), pointer;
}

details summary:hover { color: var(--text-2); }

/* ---------- Kalender ---------- */
.kal-kopf {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
}

.kal-gitter {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 3px;
}

.kal-wochentag {
    text-align: center;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--text-3);
    padding: 0.3rem 0;
}

.kal-tag {
    min-height: 74px;
    border: 1px solid var(--linie);
    border-radius: 8px;
    padding: 4px;
    background: rgba(255, 255, 255, .02);
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow: hidden;
}

.kal-tag.fremd { background: transparent; opacity: 0.4; }
.kal-tag.heute { border-color: var(--gruen-hell); box-shadow: 0 0 0 2px var(--gelb-tint); }

.kal-zahl { font-size: 0.72rem; color: var(--text-3); font-weight: 600; }
.kal-tag.heute .kal-zahl { color: var(--text); }

.kal-chip {
    display: block;
    font-size: 0.63rem;
    line-height: 1.25;
    padding: 2px 4px;
    border-radius: 4px;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.kal-chip:hover { text-decoration: none; filter: brightness(1.1); }

.chip-zusage     { background: var(--gruen-hell); color: var(--gelb-tief); }
.chip-vielleicht { background: var(--lila);       color: #fff; }
.chip-absage     { background: rgba(255,255,255,.06); color: var(--text-3); text-decoration: line-through; }
.chip-offen      { background: rgba(255,255,255,.12); color: var(--text); }

.kal-legende {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.9rem;
    font-size: 0.75rem;
    color: var(--text-3);
}

.kal-punkt {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 3px;
    margin-right: 4px;
    vertical-align: middle;
}

@media (max-width: 560px) {
    .kal-tag { min-height: 58px; padding: 3px; }
    .kal-chip { font-size: 0.55rem; }
    .sammelleiste { position: static; }
    header.topbar .marke-tag { display: none; }
}

/* ============================================================
   Liga: Meine Herausforderungen
   ------------------------------------------------------------
   Leitidee: Was ICH tun muss, sticht hervor (Gold + Puls), was auf
   die Gegenseite wartet, tritt zurueck (Lila, leicht gedimmt). Alle
   Effekte sind rein dekorativ und unter prefers-reduced-motion aus.
   ============================================================ */

/* ---------- Aufgaben-Kacheln ganz oben ---------- */
.liga-uebersicht {
    display: grid;
    /* Obergrenze 240px, damit sich Kacheln auf dem Desktop nicht aufblasen
       (2 Kacheln in postfach.php wurden sonst 475px breit). Bei einer
       Kachelzahl, die 240px nicht glatt aufteilt (z.B. 3 in liga_rangliste),
       bliebe sonst rechts eine Luecke - justify-content:center zentriert die
       Reihe stattdessen, statt sie links kleben zu lassen. */
    grid-template-columns: repeat(auto-fit, minmax(148px, 240px));
    justify-content: center;
    gap: 0.7rem;
    margin: 0 0 1.4rem;
}

.liga-kachel {
    position: relative;
    overflow: hidden;
    display: block;
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--r);
    padding: 0.9rem 1rem;
    text-decoration: none;
    transition: transform .16s ease, border-color .2s ease, box-shadow .22s ease;
}

.liga-kachel:hover {
    text-decoration: none;
    transform: translateY(-2px);
    border-color: var(--linie-stark);
    box-shadow: 0 10px 24px rgba(0, 0, 0, .32);
}

.liga-kachel-zahl {
    display: block;
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -1px;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.liga-kachel-label {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.71rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-3);
}

/* Kachel mit offener Aufgabe: goldener Rahmen + langsamer Lichtstreifen */
.liga-kachel.ist-aktiv {
    border-color: var(--gold);
    background: linear-gradient(180deg, var(--gold-tint), transparent 70%), var(--flaeche);
}
.liga-kachel.ist-aktiv .liga-kachel-zahl { color: var(--gold); }
.liga-kachel.ist-aktiv .liga-kachel-label { color: rgba(212, 175, 55, .8); }

.liga-kachel.ist-aktiv::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 35%, rgba(212, 175, 55, .16) 50%, transparent 65%);
    transform: translateX(-100%);
    animation: liga-sweep 4.5s ease-in-out infinite;
}

@keyframes liga-sweep {
    0%, 55%  { transform: translateX(-100%); }
    100%     { transform: translateX(100%); }
}

.liga-kachel.ist-leer { opacity: .55; }

/* Geboosteter Termin/Abstimmung: gleiche Gold-Hervorhebung wie oben bei
   .liga-kachel.ist-aktiv, nur auf normale Karten gemuenzt. */
.card.geboostet {
    position: relative;
    overflow: hidden;
    border-color: var(--gold);
    background: linear-gradient(180deg, var(--gold-tint), transparent 70%), var(--flaeche);
}
.card.geboostet::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 35%, rgba(212, 175, 55, .16) 50%, transparent 65%);
    transform: translateX(-100%);
    animation: liga-sweep 4.5s ease-in-out infinite;
}

/* Bewertungs-Vorschlag: eigene, ruhigere Farbe (Lila statt Gold). Die
   Bewertung steht zwar als Aufgabe im Postfach, blockiert aber - anders als
   die goldenen Kacheln - niemanden auf der Gegenseite. */
.liga-kachel.ist-bewerten {
    border-color: rgba(123, 104, 166, .5);
    background: linear-gradient(180deg, var(--lila-tint), transparent 70%), var(--flaeche);
}
.liga-kachel.ist-bewerten .liga-kachel-zahl { color: var(--lila); font-size: 1.4rem; }
.liga-kachel.ist-bewerten .liga-kachel-label { color: #C9BEDF; }

/* ---------- Match-Karte ---------- */
.liga-match {
    position: relative;
    overflow: hidden;
    padding-left: 1.5rem;
    transition: transform .18s ease, border-color .2s ease, box-shadow .22s ease;
}

/* Statusstreifen links - Farbe sagt auf einen Blick, wer am Zug ist */
.liga-match::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 4px;
    background: var(--linie-stark);
}
.liga-match.ist-dran::before       { background: linear-gradient(180deg, var(--gold), #E4C158); }
.liga-match.ist-warten::before     { background: var(--lila); }
.liga-match.ist-vereinbart::before { background: var(--gruen-hell); }
.liga-match.ist-pruefen::before    { background: var(--rot); }

.liga-match:hover {
    transform: translateY(-2px);
    border-color: var(--linie-stark);
    box-shadow: 0 12px 28px rgba(0, 0, 0, .34);
}

.liga-match.ist-dran {
    border-color: rgba(212, 175, 55, .45);
    background: linear-gradient(180deg, rgba(212, 175, 55, .07), transparent 55%), var(--flaeche);
}

.liga-match.ist-warten { opacity: .82; }
.liga-match.ist-warten:hover { opacity: 1; }

/* Offene Bewertung im Postfach: bleibt Lila wie der Vorschlag auf
   liga_meine.php. Sie steht dort zwar als Aufgabe, blockiert aber - anders
   als die goldenen Karten - niemanden auf der Gegenseite. */
.liga-match.ist-bewerten {
    border-color: rgba(123, 104, 166, .45);
    background: linear-gradient(180deg, var(--lila-tint), transparent 55%), var(--flaeche);
}
.liga-match.ist-bewerten::before { background: var(--lila); }

.liga-match-kopf {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    flex-wrap: wrap;
    margin-bottom: 0.55rem;
}

.liga-gegner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.3px;
    min-width: 0;
}
.liga-gegner .avatar-name { font-weight: 700; }

.liga-vs {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-3);
}

.liga-match-kopf .tag { margin-left: auto; }

/* Pulsierender Punkt: "du bist dran" */
.liga-puls {
    position: relative;
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--gold);
    flex-shrink: 0;
}
.liga-puls::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    animation: liga-puls 2.1s ease-out infinite;
}

@keyframes liga-puls {
    0%   { box-shadow: 0 0 0 0 rgba(212, 175, 55, .55); }
    70%  { box-shadow: 0 0 0 10px rgba(212, 175, 55, 0); }
    100% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0); }
}

/* ---------- Termin-Zeile mit Datumsblock ---------- */
.liga-termin {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    background: var(--flaeche-2);
    border: 1px solid var(--linie);
    border-radius: var(--r-klein);
    padding: 0.65rem 0.85rem;
    margin: 0.6rem 0 0.8rem;
}

.liga-datum-block {
    text-align: center;
    min-width: 46px;
    line-height: 1.15;
    flex-shrink: 0;
}
.liga-datum-wochentag {
    display: block;
    font-size: 0.64rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--gold);
}
.liga-datum-tag {
    display: block;
    font-size: 1.4rem;
    font-weight: 700;
    letter-spacing: -1px;
    font-variant-numeric: tabular-nums;
}
.liga-datum-monat {
    display: block;
    font-size: 0.64rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-3);
}

.liga-termin-info { flex: 1 1 auto; min-width: 0; }
.liga-termin-zeit { font-weight: 600; font-size: 0.92rem; }
.liga-termin-ort  { color: var(--text-3); font-size: 0.8rem; margin-top: 0.1rem; }

/* ---------- Countdown ---------- */
.liga-countdown {
    flex-shrink: 0;
    font-size: 0.71rem;
    font-weight: 700;
    padding: 0.28rem 0.62rem;
    border-radius: 999px;
    white-space: nowrap;
    background: rgba(255, 255, 255, .07);
    color: var(--text-2);
}
.liga-countdown.bald {
    background: var(--gold);
    color: var(--gold-tief);
    animation: liga-glow-gold 2.4s ease-in-out infinite;
}
.liga-countdown.heute {
    background: var(--rot);
    color: #fff;
    animation: liga-glow-rot 1.5s ease-in-out infinite;
}
.liga-countdown.vorbei { background: var(--rot-tint); color: var(--rot); }

@keyframes liga-glow-gold {
    0%, 100% { box-shadow: 0 0 0 0 rgba(212, 175, 55, 0); }
    50%      { box-shadow: 0 0 14px 2px rgba(212, 175, 55, .45); }
}
@keyframes liga-glow-rot {
    0%, 100% { box-shadow: 0 0 0 0 rgba(229, 72, 77, 0); }
    50%      { box-shadow: 0 0 14px 2px rgba(229, 72, 77, .5); }
}

/* ---------- Satz-Ergebnisse als Pills ---------- */
.liga-saetze { display: flex; gap: 0.35rem; flex-wrap: wrap; margin: 0.5rem 0 0.6rem; }
.liga-satz {
    font-size: 0.86rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    background: var(--flaeche-2);
    border: 1px solid var(--linie);
    border-radius: var(--r-klein);
    padding: 0.24rem 0.6rem;
    letter-spacing: 0.02em;
}
.liga-satz.ist-ctb { border-color: var(--gold); color: var(--gold); }

/* ---------- Aktionen ---------- */
.liga-aktionen {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 0.3rem;
}

/* Bewusst zurückhaltend (Text-Link statt Button) - "Nicht bewerten" ist eine
   endgültige Entscheidung, soll also nicht neben "Speichern" um Aufmerksamkeit
   konkurrieren. min-height 44px trotzdem fürs Touch-Ziel, siehe CLAUDE.md. */
.link-verzicht {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0;
    background: none;
    border: none;
    color: var(--text-3);
    font-size: 0.85rem;
    text-decoration: underline;
    cursor: pointer;
}
.link-verzicht:hover { color: var(--text-2); }
.liga-aktionen button,
.liga-aktionen .btn { margin-top: 0; }

.liga-kopf-aktionen {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-bottom: 1.6rem;
}
.liga-kopf-aktionen .btn { margin-top: 0; }

/* Gegenvorschlag-Formular */
.liga-vorschlag {
    margin-top: 0.8rem;
    border-top: 1px dashed var(--linie);
    padding-top: 0.7rem;
}
.liga-vorschlag > summary {
    cursor: pointer;
    color: var(--text-3);
    font-size: 0.82rem;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    transition: color .15s ease;
}
.liga-vorschlag > summary:hover { color: var(--text); }
.liga-vorschlag > summary::-webkit-details-marker { display: none; }
.liga-vorschlag > summary::before {
    content: "+";
    font-weight: 700;
    display: inline-block;
    transition: transform .2s ease;
}
.liga-vorschlag[open] > summary::before { transform: rotate(45deg); }

.liga-vorschlag-form {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: 0.6rem;
    align-items: end;
    margin-top: 0.7rem;
    animation: auf .28s ease both;
}
.liga-vorschlag-form label { margin-top: 0; }
.liga-vorschlag-form button { margin-top: 0; }

/* ---------- Leerzustaende ---------- */
.liga-leer {
    text-align: center;
    padding: 1.7rem 1rem;
    color: var(--text-3);
}
.liga-leer-icon {
    display: block;
    font-size: 1.5rem;
    margin-bottom: 0.4rem;
    opacity: .55;
}
.liga-leer p { margin: 0; font-size: 0.9rem; }

/* ---------- Abschnitts-Ueberschrift mit Zaehler ---------- */
.liga-abschnitt {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    margin: 1.9rem 0 0.7rem;
    scroll-margin-top: 96px;
}
.liga-abschnitt h2 { margin: 0; }
.liga-abschnitt-zahl {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-3);
    background: var(--flaeche-2);
    border-radius: 999px;
    padding: 0.12rem 0.5rem;
}

/* ---------- Gestaffeltes Einblenden ---------- */
.liga-stagger {
    animation: auf .42s cubic-bezier(.22, 1, .36, 1) both;
    animation-delay: calc(var(--i, 0) * 55ms);
}

/* ---------- Historie ---------- */
.liga-historie { padding: 0; overflow: hidden; }
.liga-historie table { margin-top: 0; }

/* ---------- Mobil ---------- */
@media (max-width: 560px) {
    .liga-uebersicht { grid-template-columns: repeat(2, 1fr); gap: 0.55rem; }
    .liga-kachel { padding: 0.75rem 0.8rem; }
    .liga-kachel-zahl { font-size: 1.5rem; }

    .liga-match { padding-left: 1.2rem; padding-right: 1.1rem; }
    .liga-match-kopf .tag { margin-left: 0; }
    .liga-gegner { font-size: 1rem; }

    .liga-termin { gap: 0.7rem; padding: 0.6rem 0.7rem; flex-wrap: wrap; }
    .liga-countdown { margin-left: auto; }

    /* Volle Breite + sichere Touch-Flaeche (44px) statt gedraengter Mini-Buttons */
    .liga-aktionen { width: 100%; }
    .liga-aktionen button,
    .liga-aktionen .btn {
        flex: 1 1 44%;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: 0.6rem 0.9rem;
    }
    .liga-kopf-aktionen { flex-direction: column; }
    .liga-kopf-aktionen .btn {
        width: 100%;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    .liga-vorschlag-form { grid-template-columns: 1fr; }
    .liga-vorschlag-form button { min-height: 44px; }

    /* Aufklapper ist per se nur textzeilenhoch - auf Touch zu klein */
    .liga-vorschlag > summary {
        min-height: 44px;
        padding: 0.5rem 0;
        font-size: 0.88rem;
    }

    /* Die Historie-Tabelle nutzt den generischen .tabelle-karten-Mechanismus
       weiter unten - hier braucht es keine Sonderregeln mehr. */
    .liga-historie.card { padding: 0.6rem; }
}

/* ---------- Bewegung reduzieren ---------- */
@media (prefers-reduced-motion: reduce) {
    .liga-kachel.ist-aktiv::after,
    .card.geboostet::after,
    .liga-puls::after,
    .liga-countdown.bald,
    .liga-countdown.heute,
    .liga-stagger,
    .liga-vorschlag-form { animation: none; }
    .liga-kachel:hover,
    .liga-match:hover { transform: none; }
    .liga-vorschlag > summary::before { transition: none; }
}

/* Gold-Pill "Du bist am Zug" - gleiche Signalfarbe wie Kachel und
   Statusstreifen, damit "Gold = deine Aufgabe" durchgaengig gilt. */
.tag-dran {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--gold);
    color: var(--gold-tief);
}
.tag-dran .liga-puls { background: var(--gold-tief); }
.tag-dran .liga-puls::after { animation-name: liga-puls-dunkel; }

@keyframes liga-puls-dunkel {
    0%   { box-shadow: 0 0 0 0 rgba(10, 14, 24, .5); }
    70%  { box-shadow: 0 0 0 9px rgba(10, 14, 24, 0); }
    100% { box-shadow: 0 0 0 0 rgba(10, 14, 24, 0); }
}

/* ============================================================
   Liga: Rangliste
   ------------------------------------------------------------
   Statt einer 5-spaltigen Tabelle (die mobil seitwaerts scrollt)
   eine Liste aus Zeilen, die auf schmalen Screens umbricht.
   Platz 1-3 bekommen Medaillenfarben, die eigene Zeile ist gruen
   markiert.
   ============================================================ */

.rang-liste {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.rang-zeile {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 0.9rem;
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--r);
    padding: 0.8rem 1.1rem;
    transition: transform .18s ease, border-color .2s ease, box-shadow .22s ease;
}

.rang-zeile:hover {
    transform: translateY(-2px);
    border-color: var(--linie-stark);
    box-shadow: 0 10px 24px rgba(0, 0, 0, .3);
}

/* ---------- Platz-Medaille ---------- */
.rang-platz {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.9rem;
    font-variant-numeric: tabular-nums;
    background: var(--flaeche-2);
    border: 1px solid var(--linie);
    color: var(--text-2);
}

.rang-zeile.ist-1 .rang-platz { background: var(--gold);  border-color: var(--gold);  color: var(--gold-tief); }
.rang-zeile.ist-2 .rang-platz { background: #C7CCD6;      border-color: #C7CCD6;      color: #14161A; }
.rang-zeile.ist-3 .rang-platz { background: #C98A5B;      border-color: #C98A5B;      color: #1A0F08; }

/* Platz 1 zusaetzlich mit goldenem Schimmer */
.rang-zeile.ist-1 {
    border-color: rgba(212, 175, 55, .5);
    background: linear-gradient(180deg, rgba(212, 175, 55, .09), transparent 60%), var(--flaeche);
}
.rang-zeile.ist-1::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 35%, rgba(212, 175, 55, .13) 50%, transparent 65%);
    transform: translateX(-100%);
    animation: liga-sweep 5s ease-in-out infinite;
}

/* ---------- Eigene Zeile ---------- */
.rang-zeile.ist-ich {
    border-color: rgba(40, 180, 99, .55);
    background: linear-gradient(180deg, rgba(40, 180, 99, .08), transparent 60%), var(--flaeche);
}
.rang-zeile.ist-ich.ist-1 {
    border-color: rgba(212, 175, 55, .6);
}

/* ---------- Name ---------- */
.rang-name {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 600;
    flex-wrap: wrap;
}
.rang-name .avatar-name { font-weight: 600; }

/* ---------- Bilanz ---------- */
.rang-bilanz {
    flex: 0 0 auto;
    display: flex;
    gap: 0.3rem;
}
.rang-bilanz span {
    font-size: 0.74rem;
    font-weight: 700;
    padding: 0.2rem 0.45rem;
    border-radius: var(--r-klein);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.rang-siege      { background: var(--gelb-tint); color: var(--gruen-hell); }
.rang-niederlagen{ background: rgba(255, 255, 255, .06); color: var(--text-3); }

/* ---------- ELO ---------- */
.rang-elo {
    flex: 0 0 auto;
    text-align: right;
    line-height: 1.1;
    min-width: 52px;
}
.rang-elo-zahl {
    display: block;
    font-size: 1.12rem;
    font-weight: 700;
    letter-spacing: -0.5px;
    font-variant-numeric: tabular-nums;
}
.rang-elo-label {
    display: block;
    font-size: 0.6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-3);
}

/* ---------- Aktion ---------- */
.rang-aktion { flex: 0 0 auto; }
.rang-aktion .btn {
    margin-top: 0;
    padding: 0.4rem 0.85rem;
    font-size: 0.78rem;
}

/* ---------- Mobil: Zeile bricht in zwei Ebenen um ---------- */
@media (max-width: 560px) {
    .rang-zeile {
        flex-wrap: wrap;
        gap: 0.55rem 0.7rem;
        padding: 0.75rem 0.9rem;
    }
    /* Zwingt alles nach der Namenszeile in die zweite Ebene */
    .rang-name { flex: 1 1 calc(100% - 46px); }
    .rang-aktion { margin-left: auto; }
    .rang-aktion .btn {
        min-height: 40px;
        display: inline-flex;
        align-items: center;
        padding: 0.5rem 1rem;
    }
    .rang-elo { text-align: left; min-width: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .rang-zeile.ist-1::after { animation: none; }
    .rang-zeile:hover { transform: none; }
}

/* ---------- Krone (Platz 1) und rote Laterne (Letzter) ----------
   Beide sitzen als kleines Abzeichen ueber bzw. unter der Platz-Medaille.
   Weil .rang-zeile overflow:hidden hat (fuer den Gold-Sweep), bekommen die
   betroffenen Zeilen zusaetzlichen Innenabstand - sonst wuerde das Abzeichen
   an der Zeilenkante abgeschnitten. */
.rang-zeile.hat-krone   { padding-top: 1.6rem; }
.rang-zeile.hat-laterne { padding-bottom: 1.5rem; }

.rang-platz { position: relative; }

.rang-krone,
.rang-laterne {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    pointer-events: none;
}
.rang-krone {
    top: -19px;
    color: var(--gold);
    filter: drop-shadow(0 1px 3px rgba(212, 175, 55, .45));
    animation: krone-wippen 4.5s ease-in-out infinite;
    transform-origin: 50% 100%;
}
.rang-laterne {
    bottom: -18px;
    color: var(--rot);
    filter: drop-shadow(0 1px 3px rgba(229, 72, 77, .4));
    animation: laterne-schaukeln 5.5s ease-in-out infinite;
    transform-origin: 50% 0;
}

@keyframes krone-wippen {
    0%, 100% { transform: translateX(-50%) rotate(-4deg); }
    50%      { transform: translateX(-50%) rotate(4deg); }
}
@keyframes laterne-schaukeln {
    0%, 100% { transform: translateX(-50%) rotate(-7deg); }
    50%      { transform: translateX(-50%) rotate(7deg); }
}

/* Letzter Platz: dezent rot statt der neutralen Zeile - klar erkennbar,
   aber bewusst schwaecher als der Gold-Auftritt von Platz 1. */
.rang-zeile.ist-letzter {
    border-color: rgba(229, 72, 77, .34);
    background: linear-gradient(0deg, rgba(229, 72, 77, .07), transparent 55%), var(--flaeche);
}
.rang-zeile.ist-letzter .rang-platz {
    background: rgba(229, 72, 77, .16);
    border-color: rgba(229, 72, 77, .45);
    color: #ff8a8a;
}

@media (prefers-reduced-motion: reduce) {
    .rang-krone,
    .rang-laterne { animation: none; }
}

/* ---------- Aufstieg seit dem letzten Besuch ----------
   Die eigene Zeile leuchtet einmal kurz gruen auf, dazu eine Pille mit der
   Zahl der gewonnenen Plaetze. Laeuft genau einmal: liga_rangliste.php
   schreibt den neuen Platz sofort fort, ein Neuladen feiert also nicht noch
   einmal. */
.rang-zeile.ist-aufstieg {
    animation: rang-aufstieg 2.4s cubic-bezier(.22, 1, .36, 1) .35s 1 both;
}

.rang-aufstieg-tag {
    background: var(--gelb-tint);
    color: var(--gruen-hell);
    font-weight: 700;
    white-space: nowrap;
}

@keyframes rang-aufstieg {
    0%   { transform: translateY(10px); box-shadow: 0 0 0 0 rgba(40, 180, 99, .55); }
    18%  { transform: translateY(0);    box-shadow: 0 0 0 7px rgba(40, 180, 99, .28); }
    55%  {                              box-shadow: 0 0 0 3px rgba(40, 180, 99, .16); }
    100% {                              box-shadow: 0 0 0 0 rgba(40, 180, 99, 0); }
}

/* ---------- Die Rangliste als Tennisplatz ----------
   Die Liste steht auf einem Platz von oben: Platz 1 liegt am Netz (goldene
   Linie oben, dasselbe Motiv wie im Hero und im Nav-Trenner), der Letzte mit
   der roten Laterne an der Grundlinie unten. Seitenlinien und Mittellinie
   rahmen die Zeilen.

   Warum als Rahmen und nicht als Flaeche dahinter: die Zeilen sind
   undurchsichtige Karten ueber die volle Breite - Linien hinter ihnen waeren
   schlicht verdeckt. Der Innenabstand schafft den Streifen, in dem der Platz
   ueberhaupt sichtbar werden kann.

   Reihenfolge im Malvorgang: ::before steht vor den Zeilen im DOM und liegt
   damit hinter ihnen, ::after kommt danach und liegt darueber - deshalb sitzt
   das Netz im ::after, es soll ueber allem liegen. */
.rang-liste {
    position: relative;
    padding: 1.5rem 1.05rem 1.7rem;
}

.rang-liste::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: .6;
    background:
        /* linke Seitenlinie */
        linear-gradient(var(--linie-stark), var(--linie-stark)) left .35rem top 0 / 2px 100% no-repeat,
        /* rechte Seitenlinie */
        linear-gradient(var(--linie-stark), var(--linie-stark)) right .35rem top 0 / 2px 100% no-repeat,
        /* Mittellinie */
        linear-gradient(var(--linie-stark), var(--linie-stark)) center top 0 / 2px 100% no-repeat,
        /* Grundlinie unten - dort steht der Letzte */
        linear-gradient(var(--linie-stark), var(--linie-stark)) left .35rem bottom .45rem / calc(100% - .7rem) 2px no-repeat;
}

/* Das Netz oben, an dem Platz 1 steht */
.rang-liste::after {
    content: "";
    position: absolute;
    left: .35rem;
    right: .35rem;
    top: .45rem;
    height: 3px;
    border-radius: 2px;
    background: var(--gold);
    opacity: .5;
    pointer-events: none;
}

@media (max-width: 560px) {
    /* Auf dem Handy ist die Breite zu kostbar fuer einen breiten Platzrand -
       der Rahmen rueckt enger an die Zeilen heran. */
    .rang-liste { padding: 1.1rem .5rem 1.25rem; }
    .rang-liste::before {
        background-position: left .1rem top 0, right .1rem top 0, center top 0, left .1rem bottom .3rem;
        background-size: 2px 100%, 2px 100%, 2px 100%, calc(100% - .2rem) 2px;
    }
    .rang-liste::after { left: .1rem; right: .1rem; top: .3rem; }
}

/* ============================================================
   Liga-Hero: Vereinslogo auf einem angedeuteten Tennisplatz
   ------------------------------------------------------------
   Kopfbereich der Rangliste. Der Platz liegt als SVG hinter dem
   Inhalt (aria-hidden, rein dekorativ), das Logo sitzt auf einer
   weissen Scheibe - die Bilddatei ist schwarze Strichzeichnung und
   waere auf dem dunklen Grund sonst unsichtbar.
   ============================================================ */
.liga-hero {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--linie);
    border-radius: var(--r);
    background: var(--flaeche);
    padding: 1.5rem 1.4rem;
    margin-bottom: 1.2rem;
    display: flex;
    align-items: center;
    gap: 1.2rem;
}

.liga-hero-court {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: .5;
    pointer-events: none;
}

.liga-hero-inhalt { position: relative; }
.liga-hero-inhalt h1 { margin: 0 0 .2rem; }
.liga-hero-inhalt .byline { margin: 0; }

.liga-hero-logo {
    position: relative;
    flex: 0 0 auto;
    width: 78px;
    height: 78px;
    border-radius: 50%;
    background: #fff url("../waempledon_logo.png") center / 76% no-repeat;
    border: 2px solid var(--gold);
    box-shadow: 0 0 0 5px rgba(212, 175, 55, .12), 0 6px 18px rgba(0, 0, 0, .4);
    transition: transform .6s cubic-bezier(.34, 1.56, .64, 1);
}
.liga-hero:hover .liga-hero-logo { transform: rotate(360deg); }

@media (max-width: 560px) {
    .liga-hero { padding: 1.2rem 1rem; gap: .9rem; }
    .liga-hero-logo { width: 58px; height: 58px; border-width: 1px; }
    .liga-hero-inhalt h1 { font-size: 1.35rem; }
}

@media (prefers-reduced-motion: reduce) {
    .liga-hero:hover .liga-hero-logo { transform: none; }
}

/* ============================================================
   Liga: Matches (liga_vergangen.php)
   ------------------------------------------------------------
   Lag vorher als <style>-Block in der Seite. Hier, damit es mit
   dem Rest ausgeliefert und gecacht wird - und damit die
   Mobil-Regeln an einer Stelle stehen.
   ============================================================ */

.liga-kopf {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin: 0 0 .3rem;
}
.liga-kopf svg { flex-shrink: 0; color: var(--gold); }

.match-abschnitt-titel {
    display: flex;
    align-items: center;
    gap: .55rem;
    font-size: 1.05rem;
    font-weight: 700;
    margin: 0 0 .9rem;
    color: var(--text);
}
.match-abschnitt-titel svg { flex-shrink: 0; }
.match-abschnitt-titel.zukunft svg { color: var(--gruen-hell); }
.match-abschnitt-titel.verlauf svg { color: var(--gold); }

/* Netz-Divider zwischen den Abschnitten - trennt "vor dem Match" von "nach dem Match" */
.netz-trenner {
    display: flex;
    align-items: center;
    gap: .9rem;
    margin: 2.2rem 0 1.6rem;
    color: var(--text-3);
}
.netz-trenner svg { flex: 1 1 auto; height: 22px; width: 100%; }
.netz-trenner span {
    flex-shrink: 0;
    font-size: .72rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--text-3);
}

.match-liste { display: flex; flex-direction: column; gap: .7rem; }

.match-zeile {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--r);
    padding: .95rem 1.15rem;
    transition: border-color .2s ease, transform .18s ease, box-shadow .22s ease;
}
.match-zeile:hover {
    border-color: var(--linie-stark);
    transform: translateY(-2px);
    box-shadow: 0 10px 24px rgba(0, 0, 0, .3);
}
.match-zeile.mein-match { border-color: rgba(212, 175, 55, .45); background: var(--gold-tint); }
.match-zeile.ausstehend { border-color: rgba(229, 72, 77, .35); }

.match-datum {
    flex: 0 0 auto;
    min-width: 92px;
    font-size: .82rem;
    color: var(--text-2);
    font-weight: 600;
}
.match-spieler {
    flex: 1 1 220px;
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    font-size: .95rem;
}
.match-spieler .vs { color: var(--text-3); font-size: .8rem; font-weight: 600; }
.match-spieler .gewinner { font-weight: 700; color: var(--gruen-hell); display: inline-flex; align-items: center; gap: .35rem; }

.ball-marker {
    display: inline-flex;
    width: 13px;
    height: 13px;
    flex-shrink: 0;
}

.match-ort { flex: 0 0 auto; font-size: .8rem; color: var(--text-3); }
.match-ergebnis { flex: 0 0 auto; }
.match-aktion { flex: 0 0 auto; margin-left: auto; }
.match-aktion form { display: flex; gap: .4rem; margin: 0; }
.match-aktion .btn,
.match-aktion .btn-gelb,
.match-aktion .btn-hell {
    margin-top: 0;
    padding: .4rem .85rem;
    font-size: .78rem;
}

.leer-hinweis {
    color: var(--text-3);
    font-size: .9rem;
    padding: 1.2rem 0;
    text-align: center;
}

/* ---------- Weitere Optionen (Löschung im Einvernehmen, Melden) ---------- */
.match-mehr {
    flex: 1 1 100%;
    margin-top: 0.4rem;
    border-top: 1px dashed var(--linie);
    padding-top: 0.6rem;
}
.match-mehr > summary {
    cursor: pointer;
    color: var(--text-3);
    font-size: 0.8rem;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    transition: color .15s ease;
}
.match-mehr > summary:hover { color: var(--text); }
.match-mehr > summary::-webkit-details-marker { display: none; }
.match-mehr > summary::before {
    content: "+";
    font-weight: 700;
    display: inline-block;
    transition: transform .2s ease;
}
.match-mehr[open] > summary::before { transform: rotate(45deg); }

.match-mehr-inhalt {
    margin-top: 0.7rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    animation: auf .28s ease both;
}
.match-mehr-inhalt form { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; margin: 0; }
.match-mehr-inhalt .byline { margin: 0; }

.match-melden-form { flex-direction: column !important; align-items: stretch !important; }
.match-melden-form textarea { min-height: 60px; }
.match-melden-form button { align-self: flex-start; }

/* ---------- Mobil ---------- */
@media (max-width: 560px) {
    .match-zeile { gap: .5rem .7rem; padding: .8rem .9rem; }

    .match-mehr-inhalt form:not(.match-melden-form) { width: 100%; }
    .match-mehr-inhalt form:not(.match-melden-form) button {
        flex: 1 1 44%;
        min-height: 44px;
    }
    .match-melden-form button { width: 100%; min-height: 44px; }

    /* Datum und Spielerpaarung jeweils auf eine eigene Ebene */
    .match-datum  { flex: 0 0 100%; }
    .match-spieler { flex: 1 1 100%; }

    /* Aktionen ueber die volle Breite, mit sicherer Touch-Flaeche */
    .match-aktion { flex: 1 1 100%; margin-left: 0; }
    .match-aktion form { width: 100%; }
    .match-aktion .btn,
    .match-aktion .btn-gelb,
    .match-aktion .btn-hell {
        flex: 1 1 44%;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: .55rem .9rem;
        font-size: .82rem;
    }

    .netz-trenner { margin: 1.6rem 0 1.2rem; gap: .6rem; }
}

@media (prefers-reduced-motion: reduce) {
    .match-zeile:hover { transform: none; }
}

/* Warn-Pill (z.B. "Ergebnis ausstehend") - ersetzt einen frueheren
   Inline-Style mit hartkodierten Farbwerten. */
.tag-warnung {
    background: rgba(229, 72, 77, .16);
    color: #ff8a8a;
}

/* Satz-Pills sitzen in der Matchzeile inline, ohne eigene Abstaende */
.match-ergebnis .liga-saetze { margin: 0; }

/* ============================================================
   Tabellen als Karten (mobil)
   ------------------------------------------------------------
   Greift bei <table class="tabelle-karten">. Die Klasse
   "karten-bereit" vergibt js/tabellen.js, nachdem es die
   data-label-Attribute aus der Kopfzeile gesetzt hat - ohne
   JavaScript bleibt es bei der normalen scrollenden Tabelle.
   ============================================================ */
@media (max-width: 560px) {
    table.tabelle-karten.karten-bereit {
        display: block;
        overflow-x: visible;
    }

    .tabelle-karten.karten-bereit thead,
    .tabelle-karten.karten-bereit .tabelle-kopf { display: none; }

    .tabelle-karten.karten-bereit tbody,
    .tabelle-karten.karten-bereit tr,
    .tabelle-karten.karten-bereit td {
        display: block;
        width: 100%;
    }

    .tabelle-karten.karten-bereit tr {
        background: var(--flaeche-2);
        border: 1px solid var(--linie);
        border-radius: var(--r-klein);
        padding: 0.75rem 0.9rem;
        margin-bottom: 0.6rem;
    }
    .tabelle-karten.karten-bereit tr:last-child { margin-bottom: 0; }
    .tabelle-karten.karten-bereit tr:hover td { background: transparent; }

    .tabelle-karten.karten-bereit td {
        border: none;
        padding: 0.15rem 0;
        text-align: left !important;
    }

    .tabelle-karten.karten-bereit td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: 0.66rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.06em;
        color: var(--text-3);
    }

    /* Erste Spalte ist praktisch immer der Bezeichner - der wird zur
       Kartenueberschrift und braucht kein eigenes Label. */
    .tabelle-karten.karten-bereit td:first-child {
        font-weight: 700;
        font-size: 0.98rem;
        margin-bottom: 0.35rem;
    }
    .tabelle-karten.karten-bereit td:first-child::before { display: none; }

    /* Aktionslinks brauchen auf Touch eine echte Flaeche */
    .tabelle-karten.karten-bereit td.aktionen { margin-top: 0.45rem; }
    .tabelle-karten.karten-bereit td.aktionen a {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
        margin-left: 0;
        margin-right: 1.1rem;
    }

    /* Bilder in Listen nicht auf Zellenbreite aufblasen */
    .tabelle-karten.karten-bereit td .thumb { max-width: 90px; }
}

/* ============================================================
   Ergebnis melden: Satz-Eingabe
   ------------------------------------------------------------
   Lag vorher als <style>-Block in liga_ergebnis_melden.php.
   ============================================================ */
.satz-reihe {
    display: flex;
    gap: 0.6rem;
    align-items: flex-end;
}
.satz-reihe input { width: 70px; }

@media (max-width: 560px) {
    /* Zahlenfelder duerfen wachsen, damit sie mit dem Daumen treffbar sind */
    .satz-reihe { gap: 0.5rem; }
    .satz-reihe input { width: auto; flex: 1 1 0; min-height: 44px; }
}

/* Checkbox + Text in einer Zeile - macht aus dem fett/block-formatierten
   Standard-<label> eine normale Inline-Zeile für Ja/Nein-Optionen. */
.checkbox-zeile {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: normal;
}
.checkbox-zeile input[type=checkbox] { flex-shrink: 0; }

@media (max-width: 560px) {
    /* 44px Touch-Flaeche auch fuer eine so kleine Checkbox - per
       transparentem Rahmen statt sichtbar vergroessert. */
    .checkbox-zeile { min-height: 44px; }
}

/* ============================================================
   Sammelbestellungen (shop.php)
   ------------------------------------------------------------
   Lag vorher als <style>-Block in shop.php.
   ============================================================ */
.shop-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}

.artikel {
    margin-bottom: 0;
    display: flex;
    flex-direction: column;
}

.artikel-bild {
    overflow: hidden;
    border-radius: 10px;
    margin-bottom: 1rem;
    background: var(--flaeche-2);
}
.artikel-bild img {
    width: 100%;
    height: 170px;
    object-fit: contain;
    display: block;
    cursor: zoom-in;
    transition: transform .2s ease;
}
.artikel:hover .artikel-bild img { transform: scale(1.03); }

@media (max-width: 480px) {
    /* Auf einem Handy ist die Karte einspaltig fast bildschirmbreit - eine
       170px hohe Vorschau wirkt darin unverhaeltnismaessig gross. */
    .artikel-bild img { height: 130px; }
}

.lightbox {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .85);
    display: none;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    z-index: 200;
    cursor: zoom-out;
    opacity: 0;
    transition: opacity .18s ease;
}
.lightbox.offen { display: flex; opacity: 1; }
.lightbox img {
    /* Bewusst nicht randlos bildschirmfuellend (100%/100%) - der Rand macht
       sichtbar, dass es ein Overlay ist, kein neuer Bildschirminhalt. */
    max-width: min(100%, 92vw);
    max-height: min(100%, 80vh);
    border-radius: 10px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, .5);
}
.lightbox-schliessen {
    position: absolute;
    top: 1rem;
    right: 1.1rem;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .25);
    color: #fff;
    font-size: 1.3rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background .15s ease;
}
.lightbox-schliessen:hover { background: rgba(255, 255, 255, .22); }

@media (prefers-reduced-motion: reduce) {
    .lightbox { transition: none; }
}

.artikel-kopf {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.6rem;
}
.artikel-kopf h2 { margin: 0; font-size: 1.05rem; }

.preis-pill {
    background: var(--gelb);
    color: var(--gelb-tief);
    font-size: 0.82rem;
    font-weight: 500;
    padding: 0.25rem 0.65rem;
    border-radius: 999px;
    white-space: nowrap;
}

.artikel-text { color: var(--text-2); font-size: 0.88rem; margin: 0.5rem 0 0.3rem; }

.feld-reihe { display: flex; gap: 0.6rem; }
.feld-reihe > div { flex: 1; }
.artikel form { margin-top: auto; }

@media (max-width: 380px) {
    .feld-reihe { flex-direction: column; }
}

@media (prefers-reduced-motion: reduce) {
    .artikel:hover .artikel-bild img { transform: none; }
}

/* ============================================================
   Admin: Bestellstatus-Aenderung in der Tabelle
   ------------------------------------------------------------
   Ersetzt drei frueher inline gestylte Elemente (Form, Select,
   Button) in admin/bestellungen_liste.php.
   ============================================================ */
.status-form {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}
.status-form select {
    width: auto;
    padding: 0.35rem 0.5rem;
    margin: 0;
}
.status-form button {
    margin-top: 0;
    padding: 0.35rem 0.8rem;
    font-size: 0.82rem;
}

@media (max-width: 560px) {
    /* In der Karten-Ansicht braucht das Formular die volle Breite,
       sonst quetschen sich Select und Button in die Restbreite
       neben ein imaginaeres Label. */
    .status-form { flex-wrap: wrap; }
    .status-form select { flex: 1 1 auto; min-height: 40px; }
    .status-form button { min-height: 40px; }
}

/* ============================================================
   Sterne-Bewertung (0-5) - Spielerbewertung nach einem Match
   ------------------------------------------------------------
   Reine CSS-Loesung ueber radiobuttons + Labels in umgekehrter
   DOM-Reihenfolge (5,4,3,2,1,0) mit flex-direction:row-reverse, damit
   sie visuell wieder 0..5 von links nach rechts erscheinen. Der
   allgemeine Sibling-Selektor (~) fuellt beim Hover/Checked alle davor
   liegenden Sterne gold. Die "0"-Option ist bewusst kein Stern, sondern
   ein eigener kleiner Kreis (eigene Klasse .stern-null), damit sie nicht
   versehentlich mit-golden wird, wenn ein Stern gehovert wird.
   ============================================================ */
.sterne-zeile {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--linie);
}
.sterne-zeile:last-child { border-bottom: none; }

.sterne-label-text {
    font-size: 0.9rem;
    color: var(--text-2);
    flex: 1 1 auto;
}

.sterne {
    display: flex;
    flex-direction: row-reverse;
    align-items: center;
    gap: 0.15rem;
    flex-shrink: 0;
}
.sterne input { display: none; }

.sterne label.stern {
    font-size: 1.6rem;
    line-height: 1;
    color: rgba(255, 255, 255, .15);
    cursor: pointer;
    transition: color .12s ease, transform .12s ease;
}
.sterne input:checked ~ label.stern,
.sterne label.stern:hover,
.sterne label.stern:hover ~ label.stern {
    color: var(--gold);
}
.sterne label.stern:hover { transform: scale(1.18); }
.sterne label.stern:active { transform: scale(0.92); }

.sterne label.stern-null {
    font-size: 0.62rem;
    font-weight: 700;
    color: var(--text-3);
    width: 19px;
    height: 19px;
    border-radius: 50%;
    border: 1px solid var(--linie-stark);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    margin-right: 0.35rem;
    transition: border-color .12s ease, color .12s ease;
}
.sterne label.stern-null:hover { border-color: var(--text-2); color: var(--text-2); }
.sterne input:checked + label.stern-null { border-color: var(--gold); color: var(--gold); }

@media (max-width: 560px) {
    .sterne-zeile { flex-direction: column; align-items: flex-start; gap: 0.4rem; }
    .sterne label.stern { font-size: 1.9rem; }
}

@media (prefers-reduced-motion: reduce) {
    .sterne label.stern:hover,
    .sterne label.stern:active { transform: none; }
}

/* Kleine Abschnitts-Überschrift innerhalb einer Karte/eines Formulars -
   bislang nur einmal inline auf dashboard.php verwendet (dort unverändert
   gelassen), hier als Klasse, weil das Trainings-Tagebuch mehrere Formular-
   Abschnitte braucht (Bewertungen/Schlaf/Schmerzen/Reflexion). */
.section-title {
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 0.7rem;
    color: var(--text-3);
    margin: 1.2rem 0 0.5rem;
}

/* ---------- Schmerz-Skala (0-10, Trainings-Tagebuch) ----------
   Gleiches CSS-only Radio-:checked-Prinzip wie .sterne, kein JS. Wenige
   Farbstufen statt Regenbogen-Gradient: 0-3 neutral, 4-6 Gold, 7-10 Rot -
   Farbe nur am eigenen :checked-Button, damit die Reihe im Ruhezustand
   nicht wie ein Ampel-Schema aussieht. */
.schmerz-skala {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin: 0.4rem 0;
}
.schmerz-skala input { display: none; }
.schmerz-skala label.schmerz-stufe {
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: 1px solid var(--linie-stark);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-2);
    cursor: pointer;
    transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.schmerz-skala label.schmerz-stufe:hover { border-color: var(--text-2); }
.schmerz-skala input:checked + label.schmerz-stufe {
    color: var(--text);
    border-color: transparent;
    background: var(--text-3);
}
.schmerz-skala input:checked + label.schmerz-stufe[data-stufe="4"],
.schmerz-skala input:checked + label.schmerz-stufe[data-stufe="5"],
.schmerz-skala input:checked + label.schmerz-stufe[data-stufe="6"] {
    background: var(--gold);
    color: var(--gold-tief);
}
.schmerz-skala input:checked + label.schmerz-stufe[data-stufe="7"],
.schmerz-skala input:checked + label.schmerz-stufe[data-stufe="8"],
.schmerz-skala input:checked + label.schmerz-stufe[data-stufe="9"],
.schmerz-skala input:checked + label.schmerz-stufe[data-stufe="10"] {
    background: var(--rot);
    color: #fff;
}
@media (max-width: 560px) {
    .schmerz-skala label.schmerz-stufe { width: 30px; height: 30px; font-size: 0.8rem; }
}

/* ---------- Ergebnis-Ansicht (Durchschnitt, read-only) ---------- */
.sterne-anzeige { display: flex; gap: 0.1rem; font-size: 1rem; }
.sterne-anzeige .stern-voll   { color: var(--gold); }
.sterne-anzeige .stern-leer   { color: rgba(255, 255, 255, .15); }
.sterne-anzeige .stern-halb   { color: var(--gold); opacity: .5; }

.bewertung-zeile {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--linie);
}
.bewertung-zeile:last-child { border-bottom: none; }
.bewertung-zeile-label { font-size: 0.88rem; color: var(--text-2); }
.bewertung-zeile-wert {
    font-size: 0.78rem;
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
    margin-left: 0.4rem;
}

/* ---------- Nachrichten von Gegnern (Kommentar zur Bewertung) ---------- */
.liga-kommentar {
    border-left: 3px solid var(--lila);
}
.liga-kommentar-text {
    margin: 0 0 0.4rem;
    font-style: italic;
    color: var(--text);
}

/* ---------- Kompakter Bewertungs-Chip (Rangliste, Matchlisten) ---------- */
.mini-bewertung {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.76rem;
    color: var(--text-3);
    white-space: nowrap;
}
.mini-bewertung .sterne-anzeige { font-size: 0.85rem; }
.mini-bewertung-anzahl { font-variant-numeric: tabular-nums; }

/* ---------- Selbstbewertungs-Notizen (Profil, privat) ---------- */
.selbst-notiz {
    padding: 0.7rem 0;
    border-bottom: 1px solid var(--linie);
}
.selbst-notiz:last-child { border-bottom: none; }
.selbst-notiz-zeile {
    margin: 0 0 0.3rem;
    font-size: 0.88rem;
    line-height: 1.5;
}
.selbst-notiz-zeile:last-child { margin-bottom: 0; }
.selbst-notiz-label {
    display: block;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-3);
    margin-bottom: 0.15rem;
}

/* ============================================================
   Tennis-Bewegung: Seitenwechsel, Platzlinien, kleine Baelle
   ------------------------------------------------------------
   Gehoert zusammen mit js/uebergang.js, das die Klassen setzt
   (ball-springt, rollt, streu-ball). Aufbau wie ueberall sonst:
   erst Basis, dann Mobil, ganz unten der reduced-motion-Block.
   ============================================================ */

/* ---------- Seitenwechsel ----------
   Native View-Transitions-API: der Browser blendet beim Navigieren
   selbst zwischen alter und neuer Seite ueber, ohne dass wir die
   Navigation verzoegern muessten. Browser ohne Unterstuetzung (aktuell
   u.a. Firefox) ignorieren die Regel und laden ganz normal - deshalb
   braucht es keinen Fallback. */
@view-transition { navigation: auto; }

::view-transition-old(root) { animation: seite-raus .16s cubic-bezier(.4, 0, 1, 1) both; }
::view-transition-new(root) { animation: seite-rein .24s cubic-bezier(0, 0, .2, 1) both; }

@keyframes seite-raus { to   { opacity: 0; transform: translateY(-6px); } }
@keyframes seite-rein { from { opacity: 0; transform: translateY(9px); } }

/* ---------- Platzlinien im Hintergrund ----------
   Ein Tennisplatz von oben, fest hinter allem, sehr schwach. Gibt allen
   Seiten denselben Untergrund, ohne beim Lesen aufzufallen. Als fixed
   positioniertes Pseudo-Element - dadurch scrollt es nicht mit und kann
   auch keinen horizontalen Ueberlauf erzeugen. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    opacity: .045;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 1000' preserveAspectRatio='xMidYMid slice'%3E%3Cg fill='none' stroke='%2328B463' stroke-width='3'%3E%3Crect x='60' y='40' width='680' height='920'/%3E%3Cline x1='150' y1='40' x2='150' y2='960'/%3E%3Cline x1='650' y1='40' x2='650' y2='960'/%3E%3Cline x1='150' y1='260' x2='650' y2='260'/%3E%3Cline x1='150' y1='740' x2='650' y2='740'/%3E%3Cline x1='400' y1='260' x2='400' y2='740'/%3E%3Cline x1='400' y1='40' x2='400' y2='70'/%3E%3Cline x1='400' y1='930' x2='400' y2='960'/%3E%3Cline x1='60' y1='500' x2='740' y2='500' stroke-width='6'/%3E%3C/g%3E%3C/svg%3E") center / cover no-repeat;
}

/* ---------- Ball-Feedback beim Absenden ----------
   Zwischen Klick und neuer Seite passiert sonst sichtbar nichts, und
   Leute tippen ein zweites Mal. Der Ball huepft, bis die Seite wechselt -
   die Klasse setzt js/uebergang.js beim submit. */
button.ball-springt,
.btn.ball-springt { position: relative; }

button.ball-springt::after,
.btn.ball-springt::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 3px;
    width: 8px;
    height: 8px;
    margin-left: -4px;
    background: var(--ball-bild) center / contain no-repeat;
    animation: ball-huepft .52s ease-in-out infinite;
    pointer-events: none;
}

@keyframes ball-huepft {
    0%, 100% { transform: translateY(0)    scale(1.06, .9); }
    50%      { transform: translateY(-7px) scale(.94, 1.04); }
}

/* ---------- Netzroller ----------
   Rollt einmal ueber den Netz-Trenner, wenn der ins Bild scrollt. Der
   Ball steckt als Hintergrundbild in einem Pseudo-Element ueber die volle
   Breite und wandert per background-position - so muss die Animation die
   Containerbreite nicht kennen. */
.netz-trenner { position: relative; }

.netz-trenner.rollt::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--ball-bild) -16px 42% / 13px 13px no-repeat;
    animation: netz-roller 1.25s ease-in-out 1 both;
    pointer-events: none;
}

@keyframes netz-roller {
    from { background-position: -16px 42%; }
    to   { background-position: calc(100% + 16px) 42%; }
}

/* ---------- Gelegentlicher Ball ----------
   Rollt unten durchs Bild, ohne Anlass. js/uebergang.js erzeugt das
   Element nur bei etwa jedem vierten Seitenaufruf und raeumt es nach der
   Animation wieder weg. z-index bleibt unter der Topbar (100). */
.streu-ball {
    position: fixed;
    left: 0;
    bottom: 14px;
    width: 19px;
    height: 19px;
    z-index: 90;
    opacity: .45;
    pointer-events: none;
    background: var(--ball-bild) center / contain no-repeat;
    animation: streu-ball-rollt 6.5s linear 1 both;
}

@keyframes streu-ball-rollt {
    from { transform: translateX(-40px) rotate(0deg); }
    to   { transform: translateX(calc(100vw + 40px)) rotate(1080deg); }
}

/* ---------- Aufschlag zur Begruessung ----------
   Laeuft einmal nach dem Login auf dem Dashboard: der Ball wird hochgeworfen,
   getroffen und fliegt quer ueber die Seite; ein Lichtstreifen zieht im
   Moment des Treffers mit (dasselbe Motiv wie liga-sweep). Ob das Overlay
   ueberhaupt im HTML landet, entscheidet ein Session-Flag in dashboard.php -
   die Bewegungs-Einstellung des Systems kennt PHP aber nicht, deshalb schaltet
   der reduced-motion-Block unten es zusaetzlich hier ab. */
.aufschlag {
    position: fixed;
    inset: 0;
    z-index: 300;
    overflow: hidden;
    pointer-events: none;
    animation: aufschlag-weg 0s linear 1.7s both;
}

.aufschlag-ball {
    position: absolute;
    left: 0;
    top: 0;
    width: 44px;
    height: 44px;
    background: var(--ball-bild) center / contain no-repeat;
    animation: aufschlag-flug 1.5s cubic-bezier(.36, 0, .62, 1) 1 both;
}

.aufschlag-spur {
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, transparent 42%, rgba(212, 175, 55, .12) 50%, transparent 58%);
    animation: aufschlag-spur 1.5s ease-out 1 both;
}

@keyframes aufschlag-flug {
    0%   { transform: translate(-10vw, 34vh) rotate(0deg)    scale(.75); opacity: 0; }
    10%  { opacity: 1; }
    /* Ball wird hochgeworfen */
    24%  { transform: translate(4vw, -4vh)   rotate(120deg)  scale(1); }
    /* Treffpunkt, dann quer ueber den Platz nach unten */
    42%  { transform: translate(20vw, 10vh)  rotate(320deg)  scale(1.06); }
    72%  { transform: translate(64vw, 48vh)  rotate(700deg)  scale(.92); }
    90%  { opacity: 1; }
    100% { transform: translate(110vw, 80vh) rotate(980deg)  scale(.72); opacity: 0; }
}

@keyframes aufschlag-spur {
    0%, 26% { transform: translateX(-100%); opacity: 0; }
    38%     { opacity: 1; }
    100%    { transform: translateX(100%);  opacity: 0; }
}

@keyframes aufschlag-weg { to { visibility: hidden; } }

/* ---------- Ass ----------
   Kurzer Jubel, wenn ein selbst gewonnenes Match gemeldet wurde: der Ball
   zischt mit Speedline durchs Bild, das Wort springt einmal auf. Deutlich
   kuerzer als der Aufschlag, weil es mitten im Arbeitsfluss passiert. */
.ass {
    position: fixed;
    inset: 0;
    z-index: 300;
    overflow: hidden;
    pointer-events: none;
    animation: aufschlag-weg 0s linear 1.6s both;
}

.ass-ball {
    position: absolute;
    top: 38%;
    left: 0;
    width: 30px;
    height: 30px;
    background: var(--ball-bild) center / contain no-repeat;
    animation: ass-flug .85s cubic-bezier(.2, .6, .3, 1) 1 both;
}

/* Speedline hinter dem Ball */
.ass-ball::after {
    content: "";
    position: absolute;
    right: 100%;
    top: 50%;
    width: 95px;
    height: 2px;
    margin-top: -1px;
    background: linear-gradient(to left, rgba(212, 175, 55, .55), transparent);
}

.ass-wort {
    position: absolute;
    top: 28%;
    left: 50%;
    font-size: clamp(2rem, 9vw, 4.2rem);
    font-weight: 700;
    letter-spacing: -1px;
    color: var(--gold);
    text-shadow: 0 4px 26px rgba(212, 175, 55, .35);
    animation: ass-wort .95s cubic-bezier(.34, 1.56, .64, 1) .18s 1 both;
}

@keyframes ass-flug {
    0%   { transform: translateX(-14vw) scale(.7); opacity: 0; }
    12%  { opacity: 1; }
    100% { transform: translateX(114vw) scale(1);  opacity: 0; }
}

@keyframes ass-wort {
    0%   { opacity: 0; transform: translate(-50%, 14px) scale(.7); }
    35%  { opacity: 1; transform: translate(-50%, 0)    scale(1.06); }
    70%  { opacity: 1; transform: translate(-50%, 0)    scale(1); }
    100% { opacity: 0; transform: translate(-50%, -12px) scale(1); }
}

@media (max-width: 560px) {
    /* Auf dem Handy ist der Untergrund bei so wenig Deckkraft ohnehin
       kaum wahrnehmbar - lieber ganz weg als als Grauschleier. */
    body::before { opacity: .03; }
    .streu-ball { width: 15px; height: 15px; }
    .aufschlag-ball { width: 32px; height: 32px; }
}

@media (prefers-reduced-motion: reduce) {
    /* js/uebergang.js steigt bei reduzierter Bewegung schon vorher aus,
       diese Regeln fangen den Rest ab (Seitenwechsel laeuft rein im
       Browser, kommt also nie durch das Skript). */
    @view-transition { navigation: none; }

    .netz-trenner.rollt::after,
    button.ball-springt::after,
    .btn.ball-springt::after { animation: none; display: none; }

    .streu-ball { display: none; }

    /* Die Overlays stehen schon im HTML, wenn Login bzw. Siegmeldung sie
       angefordert haben - hier fallen sie komplett weg, statt nur ohne
       Bewegung zu laufen. */
    .aufschlag,
    .ass { display: none; }

    .rang-zeile.ist-aufstieg { animation: none; }
}

/* ---------- Training: Trainingskarten & Tiebreak-Karten ---------- */
/* Farbcodierung pro Kategorie, angelehnt an die Original-Karten (Warm-up,
   Technik, Taktik, Spielform) - nutzt die vorhandene Akzentpalette statt
   neue Farben einzufuehren. */
.trainingskarte { border-top: 4px solid var(--linie-stark); transition: box-shadow .25s ease, transform .25s ease; }
.trainingskarte-warmup    { border-top-color: var(--lila); }
.trainingskarte-aufschlag { border-top-color: var(--lila-hell); }
.trainingskarte-technik   { border-top-color: var(--gruen-hell); }
.trainingskarte-taktik    { border-top-color: var(--gold); }
.trainingskarte-spielform { border-top-color: var(--rot); }

.trainingskarte-kicker {
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 0.7rem;
    color: var(--text-3);
    margin: 0 0 0.3rem;
}
.trainingskarte-lerneffekt {
    margin: 0.8rem 0 0;
    padding-top: 0.6rem;
    border-top: 1px solid var(--linie);
}

.trainingskarte.hervorgehoben {
    box-shadow: 0 0 0 3px var(--gold-tint), 0 0 24px rgba(212, 175, 55, .3);
    transform: translateY(-3px);
}
@media (prefers-reduced-motion: reduce) {
    .trainingskarte.hervorgehoben { transform: none; }
}

.trainingskarten-filter {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.2rem;
}
.trainingskarten-filter button {
    background: var(--flaeche);
    border: 1px solid var(--linie);
    color: var(--text-2);
    border-radius: 999px;
    padding: 0.5rem 1rem;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    min-height: 44px;
    margin: 0;
}
.trainingskarten-filter button.aktiv { background: var(--gruen); color: #fff; border-color: var(--gruen); }

.trainingskarten-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1rem;
}

/* ---------- Training: Virtueller Trainer (Bausteine anklicken) ----------
   Gleiche Technik wie die Sterne-Bewertung: echte Checkboxen versteckt,
   Label direkt danach im DOM (fuer den Sibling-Selektor) uebernimmt die
   Pillen-Optik. Funktioniert ohne JavaScript. Die linke Randfarbe pro
   Kategorie ist dieselbe wie bei den Trainingskarten (.trainingskarte-*),
   damit Auswahl und Ergebnis optisch zusammengehoeren. */
.bausteine-auswahl {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin: 0.5rem 0 1.2rem;
}
.bausteine-auswahl input { display: none; }
.bausteine-auswahl label {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    margin: 0;
    padding: 0.55rem 1.1rem 0.55rem 0.9rem;
    min-height: 44px;
    border-radius: 999px;
    border: 1px solid var(--linie);
    border-left: 4px solid var(--linie-stark);
    background: var(--flaeche);
    color: var(--text-2);
    font-weight: 600;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease, color .15s ease, box-shadow .15s ease;
}
.bausteine-auswahl label::before {
    content: '';
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid var(--linie-stark);
    flex-shrink: 0;
    transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.bausteine-auswahl label:hover { color: var(--text); background: rgba(255, 255, 255, .04); }
.bausteine-auswahl input:checked + label {
    background: var(--gelb-tint);
    color: var(--text);
    box-shadow: 0 3px 10px rgba(0, 112, 74, .25);
}
.bausteine-auswahl input:checked + label::before {
    background: var(--gruen-hell);
    border-color: var(--gruen-hell);
    box-shadow: inset 0 0 0 3px var(--flaeche);
}
.bausteine-auswahl input:disabled + label {
    opacity: 0.4;
    cursor: not-allowed;
}

.bausteine-auswahl label.baustein-warmup    { border-left-color: var(--lila); }
.bausteine-auswahl label.baustein-aufschlag { border-left-color: var(--lila-hell); }
.bausteine-auswahl label.baustein-technik   { border-left-color: var(--gruen-hell); }
.bausteine-auswahl label.baustein-taktik    { border-left-color: var(--gold); }
.bausteine-auswahl label.baustein-spielform { border-left-color: var(--rot); }

/* ---------- Training: Tiebreak-Tool ---------- */
.tiebreak-satz-label {
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 0.7rem;
    color: var(--gold);
    font-weight: 700;
    margin: 0 0 0.4rem;
}
.tiebreak-karte {
    border: 1px solid var(--linie);
    border-radius: var(--r);
    padding: 1.2rem;
    background: var(--flaeche);
}
.tiebreak-karte.sonderkarte {
    border-color: var(--gold);
    background: linear-gradient(180deg, var(--gold-tint), transparent 70%), var(--flaeche);
}
.tiebreak-karte-anker {
    margin-top: 0.9rem;
    padding: 0.7rem 0.9rem;
    background: var(--gelb-tint);
    border-radius: var(--r-klein);
    font-size: 0.85rem;
}
.tiebreak-karte-anker strong { display: block; font-size: 1rem; letter-spacing: 0.5px; }
.tiebreak-grid {
    max-width: 420px;
    margin: 1.2rem auto 0;
}
