/* ============================================================================
   bbc08.css - der Stil jeder Seite der Vereinsseite.

   Abschnitte A (SYSTEM) und B (SEITE) sind der Stilblock der schlanken
   Arbeitskopie des Templates 30_Design/BBC08_Vereinsseite_Template.html,
   Zeilen 35 bis 1702, uebernommen am 28.09.2026 - ohne Auslassung und
   ohne Umformulierung. Einzige Aenderung: die Bildpfade gelten jetzt von
   web/assets/css/ aus ("../img/..." statt "assets/img/...").

   Abschnitt C am Ende traegt die Nachtraege des Rahmens: Kopf- und
   Fusskorrekturen der Live-Seite, den Menueknopf im Telefonkopf, den
   Platzhalter und (C5) die gemeinsamen Bausteine, die jede Seite nimmt,
   statt eine eigene Form zu bauen. Seiteneigene Regeln gehoeren in
   assets/css/<bereich>.css, nicht hierher.
   ========================================================================= */

/* ============================================================================
   BIRKENWERDER BC 1908 — VEREINSSEITE (Designtemplate)
   Referenzanalyse: fc-koeln.de, werder.de · Siehe 30_Design/README.md

   Zwei Schichten, strikt getrennt:

   A  SYSTEM   wörtlich aus bbc08-design-system.html. Nicht hier ändern —
               Änderungen gehören in die Quelldatei und werden von dort
               herüberkopiert.
   B  SEITE    nur was eine öffentliche Startseite braucht und das System
               nicht kennt. Alles mit p- präfigiert, damit nichts kollidiert
               (das System belegt .sec, .card, .badge, .btn, .brand, .vs).

   Eine Datei, keine externen Verweise. Das ist Absicht: Die
   Datenschutzerklärung von bbc08.de sagt genau das zu.
   ========================================================================= */


/* ██ A · SYSTEM ██████████████████████████████████████████████████████████ */

/* ─── A1 · THEMA ─────────────────────────────────────────────────────────── */
:root                     { color-scheme: light dark; }
:root[data-thema="hell"]  { color-scheme: light; }
:root[data-thema="dunkel"]{ color-scheme: dark; }

/* ─── A2 · TOKENS ────────────────────────────────────────────────────────── */
:root {
  --bg-app:        #050505;  --bg-app:        light-dark(#ececec, #050505);
  --bg-body:       #0a0a0a;  --bg-body:       light-dark(#f4f4f4, #0a0a0a);
  --surface-1:     #121212;  --surface-1:     light-dark(#ffffff, #121212);
  --surface-2:     #191919;  --surface-2:     light-dark(#f1f2f3, #191919);
  --surface-3:     #222222;  --surface-3:     light-dark(#e5e7e9, #222222);
  --surface-hover: #1d1d1d;  --surface-hover: light-dark(#f5f6f7, #1d1d1d);

  --border-subtle:  #1b1b1b; --border-subtle:  light-dark(#e8e8e8, #1b1b1b);
  --border-default: #2a2a2a; --border-default: light-dark(#d7d7d7, #2a2a2a);
  --border-strong:  #3d3d3d; --border-strong:  light-dark(#b0b0b0, #3d3d3d);

  --fg-1: #ffffff; --fg-1: light-dark(#111111, #ffffff);
  --fg-2: #bbbbbb; --fg-2: light-dark(#555555, #bbbbbb);
  --fg-3: #7c7c7c; --fg-3: light-dark(#767676, #7c7c7c);
  --fg-4: #545454; --fg-4: light-dark(#9a9a9a, #545454);

  --accent-500:  #0c5729;
  --accent-down: #094320;
  --accent-fg:   #ffffff;
  --accent-glow: rgba(12,87,41,.40);
  --accent-text:  #17ab52; --accent-text:  light-dark(#0c5729, #17ab52);
  --accent-hover: #17ab52; --accent-hover: light-dark(#0e6b33, #17ab52);
  --accent-tint:        rgba(12,87,41,.20); --accent-tint:        light-dark(rgba(12,87,41,.12), rgba(12,87,41,.20));
  --accent-tint-strong: rgba(12,87,41,.30); --accent-tint-strong: light-dark(rgba(12,87,41,.20), rgba(12,87,41,.30));
  --accent-border:      rgba(12,87,41,.50); --accent-border:      light-dark(rgba(12,87,41,.35), rgba(12,87,41,.50));

  --danger:  #f24747; --danger:  light-dark(#c81a1a, #f24747);
  --warning: #e8b400; --warning: light-dark(#806200, #e8b400);
  --success: #3dbe7a; --success: light-dark(#1e7a48, #3dbe7a);
  --info:    #5b8db8; --info:    light-dark(#3d6a91, #5b8db8);

  --danger-tint:  rgba(230,32,32,.13);  --danger-tint:  light-dark(rgba(200,26,26,.10),  rgba(230,32,32,.13));
  --warning-tint: rgba(232,180,0,.12);  --warning-tint: light-dark(rgba(128,98,0,.10),   rgba(232,180,0,.12));
  --success-tint: rgba(61,190,122,.12); --success-tint: light-dark(rgba(30,122,72,.10),  rgba(61,190,122,.12));
  --info-tint:    rgba(91,141,184,.12); --info-tint:    light-dark(rgba(61,106,145,.10), rgba(91,141,184,.12));

  --danger-border:  rgba(242,71,71,.40);   --danger-border:  light-dark(rgba(200,26,26,.32),  rgba(242,71,71,.40));
  --warning-border: rgba(232,180,0,.34);   --warning-border: light-dark(rgba(128,98,0,.32),   rgba(232,180,0,.34));
  --success-border: rgba(61,190,122,.34);  --success-border: light-dark(rgba(30,122,72,.32),  rgba(61,190,122,.34));
  --info-border:    rgba(91,141,184,.34);  --info-border:    light-dark(rgba(61,106,145,.32), rgba(91,141,184,.34));

  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, Menlo, monospace;

  --t-display: 30px; --t-h1: 22px; --t-h2: 17px; --t-h3: 15px;
  --t-body: 14px; --t-sm: 13px; --t-xs: 12px; --t-label: 11px;

  /* ---- Die Leiter der Umschaltgrenzen ----------------------------

       480   Telefon hochkant
       640   schmal      - eine Spalte
       900   mittel      - zwei Spalten
      1000   breit       - drei Spalten
      1300   sehr breit  - volle Fensterbreite
      1500   Hauptnavigation weicht den drei Strichen

     Die 480 ist an echten Geraeten gemessen, nicht geschaetzt.
     Logische Breiten hochkant: 320 iPhone SE, 375 SE 2/3 und 13
     mini, 390 iPhone 12 bis 15, 412 viele Androiden, 428 die Pro
     Max bis 14, 430 die Pro Max ab 15, 448 Pixel 8 Pro - das
     breiteste gaengige. 480 liegt ueber allen und unter jedem
     Tablett.

     JEDE Umschaltgrenze der Seite ist eine dieser sechs Zahlen. Wer
     eine neue braucht, nimmt die naechste der Leiter - nicht eine
     dazwischen. Sonst steht am Ende an jeder Stelle eine andere und
     die Seite kippt in Stufen, die niemand mehr ueberblickt.

     Aufbauend gedacht heisst die Gegenrichtung: 481, 641, 901, 1001,
     1301, 1501 - nie zweimal dieselbe Zahl fuer max und min, sonst
     gelten bei genau dieser Breite beide Regeln.

     Die Zahlen stehen hier NICHT als Variable: CSS kann in einer
     Umschaltbedingung keine Variable verwenden. Sie muessen
     ausgeschrieben stehen - dieselben sechs, ueberall. */

  --lh-tight: 1.15; --lh-body: 1.55;
  --tr-tight: -0.01em; --tr-label: 0.08em; --tr-btn: 0.12em; --tr-wide: 0.14em;

  --s1: 2px;  --s2: 4px;  --s3: 6px;  --s4: 8px;
  --s5: 12px; --s6: 16px; --s7: 20px; --s8: 24px;
  --s9: 32px; --s10: 40px; --s11: 48px; --s12: 64px;

  --r-sm: 4px; --r-md: 6px; --r-lg: 10px; --r-xl: 14px; --r-full: 999px;

  --h-btn: 32px; --h-btn-sm: 26px; --h-btn-lg: 38px;
  --h-input: 38px; --h-badge: 22px; --h-chip: 28px; --h-nav: 38px;

  --sh-md: 0 6px 20px rgba(0,0,0,.45);  --sh-md: light-dark(0 6px 20px rgba(0,0,0,.10), 0 6px 20px rgba(0,0,0,.45));
  --focus: 0 0 0 3px var(--accent-glow);

  --ease: cubic-bezier(.2,0,0,1);
  --fast: 120ms; --normal: 180ms;
}

/* ─── A3 · GRUNDLAGEN ────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

/* Das hidden-Attribut gilt immer. Ein display aus einer Klasse schlug es
   sonst: auf /live stand "Vollbild" trotz hidden da, weil .btn
   inline-flex traegt (Auftrag 156, 01.10.2026). */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg-body);
  color: var(--fg-1);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0; font-weight: 600; line-height: var(--lh-tight);
  letter-spacing: var(--tr-tight); color: var(--fg-1);
}
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-sm); }

p { margin: 0; color: var(--fg-2); }
.sm { font-size: var(--t-sm); } .xs { font-size: var(--t-xs); }

.label {
  font-size: var(--t-label); font-weight: 600; letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--fg-3); line-height: 1;
}

/* :where() hält die Spezifität bei 0 — sonst schlüge diese Regel jede
   Komponentenklasse. */
:where(a) { color: var(--accent-text); text-decoration: none; }
:where(a):hover { text-decoration: underline; text-underline-offset: .2em; }

/* Nicht entfernen — sonst ist die Seite per Tastatur unbedienbar. */
:focus-visible { outline: none; box-shadow: var(--focus); border-radius: var(--r-sm); }
::selection { background: var(--accent-tint-strong); color: var(--fg-1); }

/* ─── A4 · GERÜST (nur was eine Seite braucht) ───────────────────────────── */
.brand { display: inline-flex; align-items: center; gap: var(--s4); text-decoration: none; }
.brand:hover { text-decoration: none; }

/* ─── A5 · BAUSTEINE ─────────────────────────────────────────────────────── */

/* Buttons — Rundung wie die Kästchen (--r-lg), versal. Eine Hauptaktion pro Ansicht. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s3);
  height: var(--h-btn); padding: 0 18px;
  font-family: inherit; font-size: var(--t-xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: var(--tr-btn); line-height: 1;
  color: var(--fg-1); background: transparent;
  border: 1px solid var(--border-default); border-radius: var(--r-lg);
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease),
              color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.btn:hover { text-decoration: none; }

.btn--primary { background: var(--accent-500); color: var(--accent-fg); border-color: var(--accent-500); }
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); box-shadow: 0 0 16px var(--accent-glow); }
.btn--primary:active { background: var(--accent-down); border-color: var(--accent-down); box-shadow: none; }

.btn--secondary { background: var(--surface-2); color: var(--fg-1); border-color: var(--border-default); }
.btn--secondary:hover { background: var(--surface-3); border-color: var(--border-strong); }

.btn--ghost { background: transparent; border-color: transparent; color: var(--fg-2); }
.btn--ghost:hover { background: var(--surface-2); color: var(--fg-1); }

.btn--sm { height: var(--h-btn-sm); padding: 0 var(--s5); font-size: var(--t-label); }
.btn--lg { height: var(--h-btn-lg); padding: 0 var(--s8); font-size: var(--t-sm); }
/* Auf dem Telefon darf die Beschriftung eines Knopfes umbrechen. Ohne
   das schiebt ein langes Wortpaar die ganze Seite aus dem Bild -
   gemessen an "Aufnahmeantrag herunterladen": 327px breit in einer
   280px breiten Spalte, bei 320px Fensterbreite.

   Mit dem Umbruch muss die feste Hoehe weichen, sonst schneidet sie
   die zweite Zeile ab. Aus der Hoehe wird eine Mindesthoehe. */
@media (max-width: 480px) {
  .btn { white-space: normal; text-align: center;
         height: auto; min-height: var(--h-btn);
         padding-block: var(--s4); }
  .btn--lg { height: auto; min-height: var(--h-btn-lg); }
}

/* Themenschalter — segmentierte Auswahl, drei Zustände.
   Statt der Woerter Hell/Auto/Dunkel steht je ein Zeichen: Sonne,
   halb gefuellter Kreis, Mond. Die Beschriftung bleibt am Knopf als
   aria-label und als title stehen. Knopf 22x22, Zeichen 14px — der
   Schalter ist damit rund ein Drittel so breit wie vorher. */
/* Rundung wie die Kaestchen (01.10.2026, "Die gelten auch fuer die
   Button!"): aussen --r-lg. Die drei Knoepfe darin --r-md - 22px mit
   10px Rundung waeren fast Kreise; 10px aussen weniger 2px Innenabstand
   und 1px Rand lassen innen gut 6px, die Ecken laufen gleich. */
.theme {
  display: inline-flex; align-items: center; gap: 2px; padding: 2px; flex: none;
  background: var(--surface-2); border: 1px solid var(--border-default);
  border-radius: var(--r-lg);
}
.theme button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0;
  color: var(--fg-3); background: transparent; border: 0;
  border-radius: var(--r-md); cursor: pointer;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.theme svg { width: 14px; height: 14px; display: block; fill: currentColor; }
.theme button:hover { color: var(--fg-1); }
.theme button[aria-pressed="true"] { background: var(--accent-tint); color: var(--accent-text); }

/* Badges — jede Familie geschlossen: Tint-Fläche, gleichfarbiger Text und Rand.
   Keine Pille mehr (01.10.2026), aber --r-md statt --r-lg: bei 22px
   Hoehe waeren 10px Rundung fast wieder eine Pille (11px). */
.badge {
  display: inline-flex; align-items: center; gap: var(--s2);
  height: var(--h-badge); padding: 0 var(--s4);
  font-size: var(--t-label); font-weight: 600; letter-spacing: .02em;
  border: 1px solid transparent; border-radius: var(--r-md); white-space: nowrap;
}
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.badge--neutral { color: var(--fg-2);        background: var(--surface-2);    border-color: var(--border-default); }
.badge--accent  { color: var(--accent-text); background: var(--accent-tint);  border-color: var(--accent-border); }
.badge--success { color: var(--success);     background: var(--success-tint); border-color: var(--success-border); }
.badge--warning { color: var(--warning);     background: var(--warning-tint); border-color: var(--warning-border); }
.badge--danger  { color: var(--danger);      background: var(--danger-tint);  border-color: var(--danger-border); }
.badge--info    { color: var(--info);        background: var(--info-tint);    border-color: var(--info-border); }

/* Status — Farbe ist nie das einzige Signal, immer Punkt plus Text */
.status { display: inline-flex; align-items: center; gap: var(--s3); font-size: var(--t-sm); font-weight: 500; }
.status .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.status--live { color: var(--accent-text); }
.status--live .dot { background: var(--accent-text); box-shadow: 0 0 0 3px var(--accent-tint); animation: pulse 1.6s var(--ease) infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .4; } }

/* Chip (auswählbar). Rundung wie die Kaestchen und Knoepfe, --r-lg -
   keine Pille (Auftraggeber 01.10.2026 zu den Reitern: "Buttonform?????"). */
.chip {
  display: inline-flex; align-items: center; gap: var(--s3);
  height: var(--h-chip); padding: 0 var(--s5);
  font-family: inherit; font-size: var(--t-xs); font-weight: 500;
  color: var(--fg-2); background: var(--surface-2);
  border: 1px solid var(--border-default); border-radius: var(--r-lg);
  cursor: pointer; user-select: none; white-space: nowrap;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease), color var(--fast) var(--ease);
}
.chip:hover { border-color: var(--border-strong); color: var(--fg-1); }
.chip.on { color: var(--accent-text); background: var(--accent-tint); border-color: var(--accent-border); }

/* Karten — ruhende Karte wirft keinen Schatten */
.card {
  background: var(--surface-1); border: 1px solid var(--border-subtle);
  border-radius: var(--r-lg); padding: var(--s8);
  display: flex; flex-direction: column;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.card--link { cursor: pointer; }
.card--link:hover { background: var(--surface-2); border-color: var(--border-strong); }

.panel { background: var(--surface-1); border: 1px solid var(--border-subtle);
         border-radius: var(--r-lg); overflow: hidden; }

/* Tabelle */
.tw { overflow-x: auto; }
table.t { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
table.t thead th {
  text-align: left; padding: var(--s4) var(--s6); white-space: nowrap;
  font-size: var(--t-label); font-weight: 600; letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--fg-3);
  border-bottom: 1px solid var(--border-default);
}
table.t tbody td { padding: var(--s5) var(--s6); border-bottom: 1px solid var(--border-subtle);
                   color: var(--fg-2); vertical-align: middle; }
table.t tbody tr { transition: background var(--fast); }
table.t tbody tr:hover { background: var(--surface-hover); }
table.t tbody tr:last-child td { border-bottom: 0; }
table.t .strong { color: var(--fg-1); font-weight: 600; }
table.t .num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
table.t .right { text-align: right; white-space: nowrap; }
/* Auf dem Telefon nehmen die Zellenraender zu viel Platz: 16px je
   Seite sind 32px je Spalte, bei drei Spalten fast ein Drittel eines
   278px breiten Kastens. Bis 480px stehen 8px. */
@media (max-width: 480px) {
  table.t thead th, table.t tbody td { padding-inline: var(--s4); }
}
/* Das Ergebnis steht mittig in seiner Spalte, in der Kopfzeile wie
   in den Zeilen darunter.

   Die Regel MUSS table.t vorangestellt bekommen: table.t thead th
   hat (0,1,2) und schlaegt eine blosse Klasse (0,1,0) - der Kopf
   waere sonst weiter linksbuendig, waehrend die Zellen darunter
   schon mittig stehen. */
table.t .p-erg { text-align: center; white-space: nowrap; }

/* Hinweisstreifen */
.note { border-left: 2px solid var(--accent-text); padding: var(--s2) 0 var(--s2) var(--s6);
        color: var(--fg-2); font-size: var(--t-sm); }
.note--warn { border-left-color: var(--warning); }

/* Leerzustand — sachlich, kein Bedauern */
.empty { display: flex; align-items: center; justify-content: center; gap: var(--s4);
         padding: var(--s10) var(--s8); font-size: var(--t-sm); color: var(--info);
         background: var(--info-tint); border: 1px solid var(--info-border);
         border-radius: var(--r-lg); text-align: center; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}


/* ██ B · SEITE ███████████████████████████████████████████████████████████ */
/* Erweiterung für die öffentliche Startseite. Alles p- präfigiert, nichts
   davon überschreibt einen Systembaustein.                                 */

:root {
  /* Dunkle Vollbreitbänder — eine Anwendung mit Seitenleiste hat so etwas
     nicht, eine Startseite lebt davon. In beiden Themen dunkel. */
  --p-band:      #050505;
  --p-band-2:    #121212;
  --p-band-fg:   #ececec;
  --p-band-fg-2: #9a9a9a;
  --p-band-fg-3: #7c7c7c;
  --p-on-band:   #17ab52;   /* Bänder sind immer dunkel → immer die helle Grünstufe */
  --p-buehne-luft: clamp(calc(var(--s10) * 3), 27vw, 396px);  /* Platz fürs Motiv */
  --p-wappen-h: 46px;       /* Wappen im Kopf. Der Textblock daneben ist genauso hoch. */
  --p-draw:      #7c7c7c;   /* Unentschieden: im System nicht vorgesehen */

  /* OFFENE ENTSCHEIDUNG (README, Punkt 1)
     Das System schreibt gemischte Schreibung und system-ui vor. Köln und
     Werder tragen ihre Seiten mit schmalen Versalien — ohne die gibt es
     diesen Charakter nicht. Bis das entschieden ist, gilt hier ein zweites
     Register. Rückbau = diesen Block und alle .p-display-Regeln löschen. */
  --p-font-display: "Bahnschrift", "Archivo Narrow", "Roboto Condensed",
                    "Arial Narrow", "Helvetica Neue", sans-serif;

  /* KEINE Untergrenze. Mit einer hoert die Schrift unterhalb einer
     bestimmten Fensterbreite auf zu schrumpfen, waehrend die Spalten der
     Paarung weiter schmaler werden - der laengste Name laeuft dann aus
     dem Bild. Der Faktor ist gerechnet: "BIRKENWERDER" braucht in dieser
     Schrift rund das 7,7-fache der Schriftgroesse an Breite und muss in
     eine der beiden Spalten passen. */
  --p-t-hero: min(4.9vw, 4rem);
  --p-t-h1:   clamp(2.2rem, 4.6vw, 3.4rem);
  --p-t-h2:   clamp(1.7rem, 3vw, 2.5rem);
  --p-t-h3:   clamp(1.1rem, 1.5vw, 1.35rem);
  --p-t-body: 17px;

  /* Abstand von der Kante bis zum ersten Inhalt. Gilt in der Buehne
     unter der Kopfzeile und in jeder Sektion darunter - eine Zahl,
     damit die beiden nicht auseinanderlaufen. */
  --p-sp-oben: clamp(var(--s6), 2vw, 24px);
  /* Sektionen ab Spielplan/Tabelle bis zum Fuss: das Doppelte davon,
     an Anfang und Ende. Abgeleitet, nicht getrennt gesetzt. */
  --p-sp-sektion: calc(var(--p-sp-oben) * 2);
  --p-sp-s: clamp(2.5rem, 4vw, 3rem);
  --p-sp-m: clamp(3.5rem, 6vw, 5rem);
  --p-wrap: 1280px;
  --p-gut:  clamp(1.25rem, 5vw, 4rem);
  /* Lesemass: hoechste Zeilenbreite fuer Einleitungen unter dem
     Sektionskopf und fuer Fliesstext (Textseiten, Artikel). Wert der
     Begleitseiten des Templates (.p-recht, 30_Design/impressum.html
     Z. 1577). Das Mitgliedsband behaelt 52ch (.p-join p, Template
     Z. 1416). ch rechnet mit der Schrift des Elements, an dem der Wert
     steht. */
  --p-lesemass: 78ch;
}

/* Öffentlicher Fließtext ist größer als der Anwendungstext — 14 px wäre auf
   einer Vereinsseite zu klein. */
body { font-size: var(--p-t-body); }

.p-display {
  font-family: var(--p-font-display); font-stretch: 82%; font-weight: 700;
  text-transform: uppercase; line-height: .94; letter-spacing: .005em;
  text-wrap: balance; color: var(--fg-1);
}
h1.p-display { font-size: var(--p-t-h1); }
/* Die Kapitelueberschriften sind genauso gross wie die Mannschaftsnamen
   in der Buehne und schrumpfen mit dem Fenster genauso mit. Deshalb
   --p-t-hero und nicht --p-t-h2. */
h2.p-display { font-size: var(--p-t-hero); }
h3.p-display { font-size: var(--p-t-h3); line-height: 1.05; }

.p-wrap { max-width: var(--p-wrap); margin-inline: auto; padding-inline: var(--p-gut); }
.p-sec { padding-block: var(--p-sp-sektion); }
.p-sec--alt { background: var(--surface-1); }
.p-sec--tight { padding-block: var(--p-sp-sektion); }

/* Kicker = .label aus dem System plus Akzentlinie. Versalien sind hier
   regelkonform: das System erlaubt sie für Überzeilen. */
.p-kicker { display: inline-flex; align-items: center; gap: var(--s5); }
.p-kicker::before {
  content: ""; width: var(--s8); height: 3px; background: var(--accent-text);
  transition: width var(--normal) var(--ease);
}
.p-onband .p-kicker { color: var(--p-band-fg-2); }
.p-onband .p-kicker::before { background: var(--p-on-band); }

/* Alle Zwischenabstaende innerhalb einer Sektion tragen denselben
   schmalen Wert wie oben in der Buehne: --p-sp-oben. */
.p-head { display: flex; flex-wrap: wrap; align-items: flex-end;
          justify-content: space-between; gap: var(--s6) var(--s9);
          margin-bottom: var(--p-sp-oben); }
.p-head__lead { display: flex; flex-direction: column; gap: var(--s5); }

.p-onband { background: var(--p-band); color: var(--p-band-fg); }
.p-onband a { color: inherit; }
.p-onband .btn--secondary { background: rgba(255,255,255,.06); color: var(--p-band-fg);
                            border-color: rgba(255,255,255,.22); }
.p-onband .btn--secondary:hover { background: rgba(255,255,255,.12); border-color: var(--p-on-band); }

/* ---- Servicezeile ---- */
/* Beim Laden zu. Sie oeffnet sich erst, wenn der Besucher unten war und
   wieder ganz oben ankommt - siehe die Funktion servicezeile() im
   Skript. Der Rahmen unten faehrt mit, sonst bliebe eine Linie stehen,
   wo nichts mehr ist. */
.p-utility { background: var(--p-band-2); color: var(--p-band-fg-2);
             border-bottom: 0 solid rgba(255,255,255,.07); font-size: var(--t-xs);
             max-height: 0; overflow: hidden;
             transition: max-height .35s var(--ease),
                         border-bottom-width .35s var(--ease); }
.p-utility.p-offen { max-height: 200px; border-bottom-width: 1px; }
.p-utility .p-wrap { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s7);
                     align-items: center; justify-content: space-between; min-height: 38px; }
.p-utility nav { display: flex; flex-wrap: wrap; gap: var(--s7); }
.p-utility a { color: inherit; }
.p-utility a:hover { color: #fff; }
/* Der Kontextschalter der Servicezeile.
   Unter 1001px verschwinden die fuenf Textpunkte; an ihrer Stelle steht
   dann dieser Schalter und zeigt dieselben Punkte als Klappmenue. Es
   sind dieselben Verweise, nur anders dargestellt - die Navigation
   selbst wird zum Menuefeld, eine zweite Liste gibt es nicht. */
.p-servicefeld { position: relative; display: flex; align-items: center; }
.p-servicemenu__knopf { display: none; background: none; border: 0;
                        padding: 0; color: inherit; cursor: pointer;
                        font-size: 20px; line-height: 1; }
.p-servicemenu__knopf:hover { color: #fff; }
/* Die Servicezeile faehrt ueber max-height auf und beschneidet dabei,
   was ueber ihre Kante hinausgeht - ein Klappmenue haengt genau dort.
   Solange eines offen ist, beschneidet sie nicht. Sie ist dann ohnehin
   ganz aufgefahren; das Auffahren selbst bleibt beschnitten. */
.p-utility.p-offen:has(.p-servicemenu.p-offen) { overflow: visible; }
/* Der automatische Rand sitzt am Themenschalter, der in der Servicezeile
   direkt vor den Zeichen steht. Er schiebt beide gemeinsam an den rechten
   Rand, auch wenn die Textpunkte daneben im schmalen Fenster ausgeblendet
   sind. Zwei automatische Raender wuerden den freien Platz unter sich
   aufteilen und Schalter und Zeichen auseinanderziehen. */
.p-social { display: flex; gap: var(--s6); align-items: center; }
.p-utility .theme { margin-left: auto; }
.p-social svg { width: 17px; height: 17px; fill: currentColor; }

/* ---- Kopf ---- */
.p-masthead { position: sticky; top: 0; z-index: 50;
              background: var(--bg-body); border-bottom: 1px solid var(--border-subtle); }
/* Sprungmarken landen UNTER dem klebenden Kopf, nicht dahinter - der
   angesprungene Abschnitt steht komplett oben (Auftraggeber 30.09.2026).
   --p-kopf setzt bbc08.js aus der gemessenen Kopfhoehe; 73px (72px
   Mindesthoehe plus Linie) gilt, bis das Skript laeuft. Gilt fuer jede
   Seite und jeden Sprung, auch scrollIntoView. */
html { scroll-padding-top: var(--p-kopf, 73px); }
/* Kindzeichen: nur die Kopfzeile selbst ist der Flexkasten, nicht jedes
   .p-wrap im <header>. Sonst legt diese Regel auch die Punkte der
   aufgeklappten Leiste nebeneinander. */
.p-masthead > .p-wrap { display: flex; align-items: center; gap: var(--s7); min-height: 72px; }
/* Kein automatischer Rand mehr am Wappen — er sitzt jetzt beidseitig an
   der Navigation, siehe .p-nav. Sonst haengt sie in der breitesten
   Ansicht rechts am Rand statt oben in der Mitte. */
/* Das Wappen ist hoeher als breit (Verhaeltnis 0,83) — Hoehe fuehrt. */
.p-wappen { height: var(--p-wappen-h); width: auto; flex: none; }
.p-foot .p-wappen { height: 54px; }
@media (max-width: 640px) { :root { --p-wappen-h: 38px; } }
/* Der Textblock ist immer so hoch wie das Wappen: "BBC 08" oben buendig,
   der Vereinsname unten buendig. Was an Hoehe uebrig bleibt, steht als
   Abstand zwischen den beiden Zeilen — die Schriftgroessen bleiben, wie
   sie sind. Bei jeder Fensterbreite dieselbe Hoehe. */
.p-brandtext { display: flex; flex-direction: column; justify-content: space-between;
               height: var(--p-wappen-h); }
/* Keine der beiden Zeilen bricht um. Ohne das bricht der Vereinsname von
   selbst, sobald Wappen, Navigation, Knopf und Schalter um den Platz
   streiten — in zwei und drei Zeilen, an Stellen ohne Bedeutung. */
.p-brandname { font-family: var(--p-font-display); font-stretch: 75%; font-weight: 700;
               font-size: 26px; line-height: 1; letter-spacing: .02em; color: var(--fg-1);
               display: block; white-space: nowrap; }
/* Zeilenhoehe 10px, nicht 1. Zwei Namenszeilen brauchen damit 20px und
   passen mit den 26px von "BBC 08" genau in die 46px des Wappens. Steht
   der Name in einer Zeile, bleiben 10px Abstand — die Hoehe des Blocks
   aendert sich dadurch bei keiner Fensterbreite. */
.p-brandsub { display: block; font-size: var(--t-label); letter-spacing: var(--tr-wide);
              text-transform: uppercase; color: var(--fg-3); line-height: 10px; font-weight: 600;
              white-space: nowrap; }
/* Eine Namensform, keine Stufen. Die kuerzere Form "Birkenwerder BC 1908"
   war fast genauso breit wie die lange — das Umspringen bei 1300px hat
   nichts gewonnen und ist nur aufgefallen. Im schmalen Fenster faellt der
   Name ohnehin ganz weg. */
/* margin-inline: auto teilt den freien Platz gleichmaessig links und
   rechts auf. Die Navigation steht damit mittig zwischen Wappen und den
   beiden Bedienelementen. */
.p-nav { display: flex; gap: clamp(var(--s5), 1.6vw, var(--s9));
         margin-inline: auto; }
.p-nav a {
  font-family: var(--p-font-display); font-stretch: 82%; font-weight: 600;
  text-transform: uppercase; letter-spacing: var(--tr-label); font-size: 15px;
  color: var(--fg-2); padding: var(--s2) 0; border-bottom: 3px solid transparent;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.p-nav a:hover, .p-nav a[aria-current] { color: var(--fg-1); border-color: var(--accent-text);
                                         text-decoration: none; }
/* Kasten aus Knopf und Menue. Er ist der Bezugspunkt fuer die Lage des
   Menues und traegt im schmalen Fenster den automatischen Rand. */
.p-menufeld { display: none; position: relative; flex: none; }
/* Drei Striche. Im breiten Fenster ist der ganze Kasten nicht da. */
.p-menuknopf { display: inline-flex; align-items: center; justify-content: center;
               width: 34px; height: 34px; padding: 0; flex: none;
               background: transparent; border: 0; border-radius: var(--r-md);
               color: var(--fg-1); cursor: pointer;
               transition: background var(--fast) var(--ease); }
.p-menuknopf:hover { background: var(--surface-2); }
.p-menuknopf svg { width: 22px; height: 22px; display: block; }
/* Das aufklappbare Menue liegt als Overlay UEBER der Seite und schiebt
   nichts nach unten. Linksbuendig unter dem Wappen, derselbe
   Seitenabstand. Nur so breit wie der laengste Eintrag - width:
   max-content nimmt die Breite des breitesten Rasterfeldes.
   Die Flaeche ist durchscheinend und zeichnet weich, was darunter
   liegt. Die erste background-Zeile ist die Ruecklage fuer Browser
   ohne color-mix: dann steht die Flaeche eben deckend da.
   Eigene [hidden]-Regel, weil sonst das display aus der Klasse das
   hidden-Attribut schlaegt. */
.p-menu { display: none; position: absolute; top: calc(100% + var(--s4));
          left: 0; z-index: 60; width: max-content;
          max-width: calc(100vw - 2 * var(--p-gut));
          background: var(--bg-body);
          background: color-mix(in srgb, var(--bg-body) 30%, transparent);
          -webkit-backdrop-filter: blur(26px) saturate(180%);
          backdrop-filter: blur(26px) saturate(180%);
          border: 1px solid color-mix(in srgb, var(--fg-1) 12%, transparent);
          border-radius: var(--r-lg);
          box-shadow: 0 24px 60px rgba(0,0,0,.28); }
.p-menu[hidden] { display: none; }
.p-menu nav { display: grid; padding: var(--s4) var(--s8); }
.p-menu a { font-family: var(--p-font-display); font-stretch: 82%; font-weight: 600;
            text-transform: uppercase; letter-spacing: var(--tr-label); font-size: 16px;
            color: var(--fg-2); padding: var(--s5) 0;
            border-bottom: 1px solid var(--border-subtle); }
.p-menu a:last-child { border-bottom: 0; }
.p-menu a:hover { color: var(--fg-1); text-decoration: none; }
.p-menu a[aria-current] { color: var(--accent-text); }
/* Zwei Grenzen, nicht eine.

   1500px: Die Hauptnavigation braucht mit acht Punkten viel Platz. Neben
   Wappen und "Mitglied werden" passt das darunter nicht mehr, und weil
   die Kopfzeile nicht umbricht, laeuft sie aus dem Bild - die Seite
   bekommt einen waagerechten Rollbalken. Ab hier traegt der
   Drei-Striche-Knopf die Navigation. Die Luecke dazwischen haengt dann
   am Knopf statt am Wappen.

   1000px: Erst hier faellt die Schrift neben dem Wappen weg und die
   Punkte der Servicezeile. Der Themenschalter steht eine Zeile hoeher
   und ist von beidem nicht betroffen. */
/* Ist die Buehne durchgescrollt, schaltet der Kopf auf dieselbe knappe
   Fassung wie im schmalen Fenster: Wappen, drei Striche, "Mitglied
   werden". Die Klasse setzt das Skript beim Scrollen. */
.p-masthead.p-knapp .p-nav { display: none; }
.p-masthead.p-knapp .brand > span { display: none; }
.p-masthead.p-knapp .p-menufeld { display: block; }
.p-masthead.p-knapp .p-menu:not([hidden]) { display: block; }
/* Auch in der knappen Fassung stehen die Striche vorn und das Wappen
   rechts daneben. Ohne diese drei Zeilen sprang das Wappen beim
   Scrollen zurueck nach links. */
.p-masthead.p-knapp > .p-wrap > * { order: 3; }
.p-masthead.p-knapp > .p-wrap > .p-menufeld { order: 1; }
.p-masthead.p-knapp > .p-wrap > .brand { order: 2; margin-right: auto; }
@media (max-width: 1500px) {
  .p-nav { display: none; }
  .p-menufeld { display: block; }
  .p-menu:not([hidden]) { display: block; }
  /* Sobald es den Drei-Striche-Knopf gibt, steht er vorn und das
     Wappen rechts daneben.

     Alles ohne eigene Angabe steht auf order: 0 und stuende damit
     VOR beiden - deshalb bekommt der Rest der Kopfzeile eine eigene
     Stelle. Der automatische Rand haengt am Wappen, nie an beiden. */
  .p-masthead > .p-wrap > * { order: 3; }
  .p-masthead > .p-wrap > .p-menufeld { order: 1; }
  .p-masthead > .p-wrap > .brand { order: 2; margin-right: auto; }
}
@media (max-width: 1000px) {
  /* Die fuenf Textpunkte weichen dem Kontextschalter. Es bleibt
     dieselbe Navigation: aus der Flexzeile wird das Ueberlagerungs-
     feld, durchscheinend mit Weichzeichner wie das Menue im Kopf.
     Der Selektor nennt Element UND Klasse, sonst schlaegt ihn die
     Zeile '.p-utility nav { display: flex }' weiter oben. */
  .p-servicemenu__knopf { display: block; }
  .p-utility nav.p-servicemenu {
                   position: absolute; top: calc(100% + var(--s4));
                   gap: 0;
                   left: 0; z-index: 60; display: none;
                   width: max-content;
                   max-width: calc(100vw - 2 * var(--p-gut));
                   padding: var(--s4) var(--s8);
                   background: var(--bg-body);
                   background: color-mix(in srgb, var(--bg-body) 30%, transparent);
                   -webkit-backdrop-filter: blur(26px) saturate(180%);
                   backdrop-filter: blur(26px) saturate(180%);
                   border: 1px solid color-mix(in srgb, var(--fg-1) 12%, transparent);
                   border-radius: var(--r-lg);
                   box-shadow: 0 24px 60px rgba(0,0,0,.28); }
  .p-utility nav.p-servicemenu.p-offen { display: grid; }
  /* Auf der durchscheinenden Flaeche gilt die helle Bandschrift
     nicht mehr - im hellen Modus stuende sie dort auf Weiss. */
  .p-utility .p-servicemenu a { color: var(--fg-2); padding: var(--s5) 0;
                                white-space: nowrap;
                                border-bottom: 1px solid var(--border-subtle); }
  .p-utility .p-servicemenu a:last-child { border-bottom: 0; }
  .p-utility .p-servicemenu a:hover { color: var(--fg-1); }
  /* Nur das Wappen, keine Schrift daneben. Beide Zeilen stecken in
     einem gemeinsamen <span>; der Fuss ist nicht betroffen. */
  .p-masthead .brand > span { display: none; }
}

/* ---- Bühne: der Spieltag ist die Schlagzeile ---- */
/* Luftbild des eigenen Sportplatzes, Schraegansicht mit Vereinsheim,
   vom Auftraggeber am 30.09.2026 uebergeben, 2000x1122. Es ersetzt das
   Luftbild vom 27.08.2026 (2000x1334). Beide Originale liegen
   unangetastet unter 40_Umsetzung/abrufprotokolle/
   (buehne-sportplatz-2026-09-30.jpg, buehne-sportplatz-2026-08-27.jpg).
   Der Platzhalter buehne-platzhalter.jpg bleibt daneben liegen.
   Ausschnitt, Blende und WebP: C5.2a. */
.p-stage { --p-stage-bild: url("../img/buehne-sportplatz.jpg");
           position: relative; overflow: hidden;
           padding-block: var(--p-sp-oben); }
/* Hintergrundmotiv. Liegt hinter den Kreisen und dem Inhalt. Der
   Verlauf haelt die Schrift lesbar, sobald ein Bild gesetzt ist:
     .p-stage { --p-stage-bild: url("../img/buehne-sportplatz.jpg"); }
   Ohne gesetzte Eigenschaft aendert sich nichts. */
.p-stage__bild { position: absolute; top: 0; left: 0; right: 0;
                 --p-stage-bild-h: clamp(420px, 62vw, 940px);
                 height: var(--p-stage-bild-h);
                 pointer-events: none;
                 background-image:
                   linear-gradient(180deg, rgba(5,5,5,.72) 0%,
                     rgba(5,5,5,.30) 45%, rgba(5,5,5,.92) 100%),
                   var(--p-stage-bild, none);
                 background-size: cover; background-position: center; }
/* Flutlicht: ein einziger Lichtstrich beim Laden */
.p-stage::after {
  content: ""; position: absolute; inset: -20% -60%; pointer-events: none;
  background: linear-gradient(105deg, transparent 42%, rgba(255,255,255,.075) 50%, transparent 58%);
  transform: translateX(-40%); animation: sweep 2.4s var(--ease) .35s both;
}
@keyframes sweep { to { transform: translateX(40%); } }
.p-stage .p-wrap { position: relative; z-index: 2; }

/* Kein gemeinsamer Spalt: die beiden Abstaende sind verschieden gross und
   werden einzeln gesetzt — oben viel Luft fuers Motiv, unten wenig.
   Der Abstand ueber der weissen Linie ist derselbe wie darunter zwischen
   Linie und Zeitanzeige: beide var(--s5). */
.p-fixture { display: grid; gap: 0; }
.p-countdown { margin-top: var(--s5); }

/* Die drei Woerter am Anfang der Infozeile sind anklickbar. Kein Kasten,
   kein Rahmen, keine Flaeche. Jedes traegt einen Punkt: weiss, solange es
   nicht gewaehlt ist, gruen und pulsend, sobald es gewaehlt wird. Dadurch
   bleibt die Breite gleich und nichts rueckt beim Umschalten.
   Der Abstand zwischen den drei Woertern ist knapp — gerade so breit wie
   der Punkt selbst. */
/* Die Wortgruppe nimmt die volle Breite und erzwingt den Umbruch selbst.
   Vorher stand dafuer ein leeres Element dazwischen — das war ein
   eigener Flexkasten und hat einen ZWEITEN Zeilenabstand erzeugt, der
   Abstand nach unten war also doppelt so gross wie eingestellt. */
.p-wege { display: flex; align-items: center; flex-wrap: wrap;
          flex-basis: 100%; gap: var(--s4); }
.p-weg { display: inline-flex; align-items: center; gap: var(--s3);
         font: inherit; letter-spacing: inherit; text-transform: inherit;
         font-weight: 600; color: var(--p-band-fg);
         background: none; border: 0; padding: 0; cursor: pointer;
         transition: color var(--fast) var(--ease); }
.p-weg:hover { color: #fff; }
.p-weg:focus-visible { outline: 3px solid var(--p-on-band); outline-offset: 3px; }
.p-weg .dot { width: 7px; height: 7px; border-radius: 50%; flex: none;
              background: var(--p-band-fg);
              transition: background-color var(--fast) var(--ease); }
.p-weg.on { color: var(--p-on-band); }
.p-weg.on .dot { background: var(--p-on-band);
                 animation: pulse 1.6s var(--ease) infinite; }

/* Ein Wort mit Bindestrich bleibt zusammen. */
.p-block { white-space: nowrap; }
.p-meta { display: flex; flex-wrap: wrap; gap: var(--s3) 0; align-items: center;
          font-size: var(--t-label); font-weight: 600; letter-spacing: var(--tr-label);
          text-transform: uppercase; color: var(--p-band-fg-2); }
/* Trennpunkte zwischen Liga, Datum und Ort. Der Punkt bringt seinen
   Abstand als Leerzeichen selbst mit - dadurch steht er genauso wie die
   Punkte, die das Skript in "Landesklasse Nord · Herren" schreibt.
   Deshalb hat die Zeile auch keinen Spaltenabstand mehr. Der erste
   Eintrag bekommt keinen Punkt, weil vor ihm die Wortgruppe steht. */
.p-meta > span + span::before { content: " · ";
                               color: var(--p-band-fg-3); }
.p-meta .status--live { font-size: var(--t-label); letter-spacing: var(--tr-label);
                        text-transform: uppercase; font-weight: 600; color: var(--p-on-band); }
.p-meta .status--live .dot { background: var(--p-on-band); }

/* Der Abstand zwischen Infozeile und Paarung ist bewusst gross —
   dort soll ein Motiv Platz haben. Ueber --p-buehne-luft zu regeln.
   Die Paarung haelt eine feste Hoehe fuer drei Zeilen Anzeigeschrift,
   damit die Buehne beim Umschalten nicht springt. Braucht der laengste
   Name nur zwei Zeilen, entsteht der frei bleibende Platz OBEN in der
   Luft: align-content: end setzt die Paarung an den unteren Rand ihrer
   Flaeche. Der Abstand nach unten zur weissen Linie bleibt dadurch
   immer gleich. Frueher stand diese Hoehe an .p-side — dann sass das
   Loch zwischen Namen und Linie.
   --p-ausgleich setzt startseite.js: der Hoehenunterschied zwischen den
   drei Umschaltwoertern (Infozeile, Countdown), ebenfalls oben in die
   Luft - damit die Buehne auch beim Selbstwechsel nicht springt. */
.p-pairing { margin-top: calc(var(--p-buehne-luft) + var(--p-ausgleich, 0px));
            display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
            align-items: stretch;
            min-height: calc(2.64 * var(--p-t-hero) + 1.6rem);
            align-content: end;
             gap: clamp(var(--s6), 3vw, var(--s10)); }
/* Heim- und Gastseite stehen immer auf gleicher Hoehe: das Raster streckt
   beide auf die Hoehe der laengeren, der Inhalt sitzt oben. Dadurch stehen
   "Heim" und "Gast" auf einer Linie und die Namen beginnen auf derselben
   Zeile — hat eine Seite drei Zeilen, ist die andere genauso hoch.
   Die feste Hoehe fuer drei Zeilen steht an der Paarung, nicht hier:
   sonst bliebe bei zweizeiligen Namen eine ganze Zeile Loch ueber der
   weissen Linie stehen. */
.p-side { display: grid; gap: var(--s3); align-content: start; }
.p-side--away { text-align: right; justify-items: end; }
/* Die weiteren Bloecke bei gleichzeitigen Spielen: kein Motivabstand
   darueber und keine feste Hoehe fuer drei Zeilen - die traegt nur der
   erste Block, damit die Buehne beim Umschalten nicht springt. */
.p-pairing--weiter { margin-top: var(--s10); min-height: 0; }
.p-team { font-family: var(--p-font-display); font-stretch: 75%; font-weight: 700;
          font-size: var(--p-t-hero); line-height: .88; text-transform: uppercase; }
.p-side--home .p-team { color: #fff; }
.p-side--away .p-team { color: var(--p-band-fg-2); }
/* HEIM und GAST im helleren Grau des Gastnamens (30.09.2026) - im
   dunkleren (--p-band-fg-3) waren sie vor dem Luftbild zu blass. */
.p-tag { font-size: var(--t-label); font-weight: 600; letter-spacing: var(--tr-label);
         text-transform: uppercase; color: var(--p-band-fg-2); }
/* Bleibt mittig, obwohl das Raster die beiden Seiten streckt. */
.p-vs { font-family: var(--p-font-display); font-stretch: 75%; font-weight: 700;
        align-self: center;
        font-size: clamp(1.4rem, 3vw, 2.2rem); line-height: 1; color: var(--p-on-band); }
/* Bei laufendem Spiel stehen dort zwei Zeilen: "Anpfiff" und darunter die
   Uhrzeit. Beide zusammen sind genauso hoch wie eine Zeile der Vereins-
   namen. Die traegt 0,88 der Anzeigeschrift (.p-team line-height), also
   bekommt jede der beiden Zeilen 0,44 davon. */
.p-vs--anpfiff { font-size: calc(var(--p-t-hero) * .44); line-height: 1;
                 text-align: center;
                 /* Nicht mittig, sondern an den Namenszeilen ausgerichtet:
                    Unterkante "Anpfiff" auf der Unterkante der ersten
                    Namenszeile, Oberkante der Uhrzeit auf der Oberkante der
                    zweiten. Gerechnet vom oberen Rand der Zeile, damit die
                    Regel bei zwei wie bei drei Namenszeilen gleich gilt. */
                 align-self: start;
                 margin-top: calc(var(--t-label) * var(--lh-body)
                                  + var(--s3) + .44 * var(--p-t-hero)); }
.p-vs--anpfiff span { display: block; }
/* Einzeiliger Name: es gibt keine zweite Zeile, zwischen die das Feld
   gehoert. Dann sitzt es AUF der einen Zeile - "Anpfiff" in der oberen
   Haelfte, die Uhrzeit in der unteren. Beide zusammen sind so hoch wie
   die Namenszeile, decken sie also genau. */
.p-vs--einzeilig { margin-top: calc(var(--t-label) * var(--lh-body)
                                    + var(--s3)); }

.p-countdown { display: flex; flex-wrap: wrap; gap: clamp(var(--s7), 3vw, var(--s10));
               align-items: flex-end; border-top: 1px solid rgba(255,255,255,.12);
               padding-top: var(--s5); }
.p-unit { display: grid; gap: var(--s1); }
/* Eigene [hidden]-Regel, sonst schlaegt das display aus der Klasse das
   hidden-Attribut und der Countdown bleibt bei laufendem Spiel stehen.
   Gleiche Falle wie bei .p-tabs, .p-matches und .p-alle. */
.p-unit[hidden] { display: none; }
.p-num { font-family: var(--p-font-display); font-stretch: 82%; font-weight: 700;
         font-size: clamp(2rem, 4.4vw, 3rem); line-height: 1;
         font-variant-numeric: tabular-nums lining-nums; }
.p-countdown .label { color: var(--p-band-fg-3); }
.p-spacer { flex: 1 1 var(--s9); }
.p-acts { display: flex; flex-wrap: wrap; gap: var(--s5); }
/* Laeuft ein Heimspiel, steht an Stelle des Countdowns "Anpfiff um" und
   die Uhrzeit - in der Schrift der Countdown-Ziffern. Auf Startseite und
   Mannschaftsseite gleich.
   Auf der Startseite ist der Platz so breit angelegt wie der Countdown
   (--p-zeitfeld, misst startseite.js), und ohne Countdown und ohne
   Heimspiel steht dort ein leerer Platzhalter derselben Breite
   (.p-anpfiff--leer). Dadurch brechen die Knoepfe daneben in jedem Zustand
   an derselben Fensterbreite um und stehen bei jedem Wort an derselben
   Stelle. Reicht der Platz nicht, bricht "Anpfiff um" selbst um. */
.p-anpfiff { font-family: var(--p-font-display); font-stretch: 82%; font-weight: 700;
             font-size: clamp(2rem, 4.4vw, 3rem); line-height: 1;
             text-transform: uppercase;
             font-variant-numeric: tabular-nums lining-nums;
             flex: 9 1 var(--p-zeitfeld, auto); }
.p-anpfiff[hidden] { display: none; }
.p-anpfiff--leer { height: 0; }

/* Weicher Wechsel der Umschaltwoerter (startseite.js setzt .p-blendbar und
   beim Wechsel .p-blendet): Infozeile ohne die Woerter, Paarung, Countdown
   und weitere Bloecke blenden aus und wieder ein. Woerter und Knoepfe
   bleiben stehen. Ausblenden 0,4 s - dieselbe Zahl steht in startseite.js
   (AUS) -, Einblenden 0,6 s. Bei "weniger Bewegung" blendet das Skript
   nicht; die allgemeine Regel dafuer setzt jede Dauer ohnehin auf null. */
/* Nur die direkten Teile des ersten Blocks - die weiteren Bloecke blenden
   als Ganzes, sonst haette ihr Inhalt die Deckkraft zum Quadrat. Der
   freigehaltene Platz der weiteren Bloecke (min-height, startseite.js)
   waechst und schrumpft weich, wenn ein zweites Heimspiel anfaengt oder
   endet. */
.p-blendbar > .p-meta > span, .p-blendbar > .p-pairing,
.p-blendbar > .p-countdown > .p-unit, .p-blendbar > .p-countdown > .p-anpfiff {
  transition: opacity .6s var(--ease); }
.p-blendbar > #weitere-spiele {
  transition: opacity .6s var(--ease), min-height .6s var(--ease); }
.p-blendet > .p-meta > span, .p-blendet > .p-pairing,
.p-blendet > .p-countdown > .p-unit, .p-blendet > .p-countdown > .p-anpfiff,
.p-blendet > #weitere-spiele {
  opacity: 0; transition-duration: .4s; }
/* Die Linie ueber dem Countdown rueckt mit der Paarung, wenn die Zeile
   darunter anders hoch ist ("Anpfiff um", laufendes Auswaertsspiel) - also
   blendet sie mit, statt sichtbar zu springen. Die Knoepfe bleiben. */
.p-blendbar > .p-countdown { transition: border-top-color .6s var(--ease); }
.p-blendet > .p-countdown { border-top-color: transparent; transition-duration: .4s; }

/* ---- Kurzmeldungen ---- */
.p-strip { background: var(--p-band-2); color: var(--p-band-fg);
           border-top: 1px solid rgba(255,255,255,.08); }
/* Drei Spalten. Die vierte und fuenfte Meldung steht im Markup, wird aber
   erst ab 1301px gezeigt — die Auswahl liegt in CSS, nicht im Skript. */
.p-strip .p-wrap { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); }
.p-strip a:nth-child(n+4) { display: none; }
.p-strip a { display: grid; gap: var(--s4); align-content: start;
             padding: var(--s7) var(--s8); border-left: 1px solid rgba(255,255,255,.08);
             color: inherit; transition: background var(--fast) var(--ease); }
.p-strip a:first-child { border-left: 0; padding-left: 0; }
.p-strip a:hover { background: rgba(255,255,255,.04); text-decoration: none; }
.p-strip a:hover .p-kicker::before { width: var(--s10); }
.p-strip h3 { color: var(--p-band-fg); }
@media (max-width: 900px) {
  .p-strip .p-wrap { grid-template-columns: minmax(0,1fr); }
  .p-strip a { border-left: 0; padding-inline: 0; border-top: 1px solid rgba(255,255,255,.08); }
  .p-strip a:first-child { border-top: 0; }
}

/* ---- Breiteste Ansicht ----------------------------------------------
   Ab 1300px faellt der Deckel von 1280px fuer die drei obersten Baender.
   Kopf, Buehne und Kurzmeldungsband gehen dann bis an den Rand, alles
   darunter bleibt bei 1280px. Die Buehne braucht fuer die Mannschafts-
   namen dadurch weniger Zeilen — weil die Paarung ihre feste Hoehe
   behaelt und unten sitzt, wird oben mehr vom Motiv sichtbar.
   Die Marke bleibt unberuehrt: zwei Zeilen, wie sie ist. */
@media (min-width: 1301px) {
  .p-utility .p-wrap,
  .p-masthead > .p-wrap,
  .p-stage .p-wrap,
  .p-strip .p-wrap { max-width: none; }
  .p-strip .p-wrap { grid-template-columns: repeat(5, minmax(0,1fr)); }
  .p-strip a:nth-child(n+4) { display: grid; }
}

/* ---- Spieltag ---- */
/* Die Reiterreihe bricht um, sobald sie nicht mehr in eine Zeile
   passt. Vorher lief sie seitlich aus dem Bild. */
.p-tabs { display: flex; flex-wrap: wrap; gap: var(--s4);
          margin-bottom: var(--p-sp-oben); padding-bottom: var(--s2); }
/* Neben den Reitern steht der Verweis auf die Unterseite. Er ist
   kein Reiter und darf deshalb nicht in der Reiterliste stehen.
   Die Liste traegt display:contents, damit die Reihe trotzdem
   eine einzige Flexzeile bleibt. */
.p-tabs__gruppe, .p-tabs__liste, .p-titelwahl__liste { display: contents; }
/* Die beiden Knoepfe der Klappmenues gibt es nur in der schmalen
   Ansicht. Darueber stehen die Reiter und die Titel unmittelbar da. */
.chip.p-tabs__auswahl, .p-titel.p-titelwahl__auswahl { display: none; }
a.p-tabs__zu, a.p-tabs__zu:hover { text-decoration: none; }
.p-matches { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--s6); }
/* ---- Der Ausschnitt: die drei Ansichten etwa gleich hoch ----------
   Mass und Vorbild ist die Tabellenansicht. Sie zeigt sechs Zeilen um
   die eigene Mannschaft und darunter den Aufklappknopf - 415px bei
   1366px, 390px bei 320px Inhaltshoehe. Ergebnisliste, Gesamtuebersicht
   und Spielkacheln bekommen denselben Ausschnitt und denselben Knopf.
   Nicht dieselbe ZAHL: eine Listenzeile ist bei 320px fast doppelt so
   hoch wie bei 1366px, eine Spielkachel so hoch wie fuenf Listenzeilen.
   Darum haengt das Budget an der Breite.

     Ergebnisliste, Gesamtuebersicht   ab 641px  8 Zeilen, darunter 5
     Spielkacheln                      ab 901px  6 Kacheln, darunter 2

   Sechs Kacheln sind ueber 900px zwei Rasterzeilen zu dreien; darunter
   ist das Raster einspaltig, und zwei Kacheln sind dieselben zwei
   Rasterzeilen. Es ist ueberall derselbe Ausschnitt.

   Abgeschnitten wird nur die Sicht: alles bleibt im Markup und kommt
   mit dem Aufklappknopf zurueck. Ohne Skript steht ohnehin alles da. */

/* Die Gesamtuebersicht kann nicht ueber nth-child gehen: welche Zeile
   im Ausschnitt steht, haengt am Datum, und ein Datum ist kein
   Selektor. Das Skript setzt dort zwei Klassen - p-ausserhalb liegt
   auch im breiten Ausschnitt draussen, p-schmal nur im schmalen. */
.p-eingeklappt .p-ausserhalb { display: none; }
@media (max-width: 640px) {
  .p-eingeklappt .p-schmal { display: none; }
}
/* Die Ergebnisliste steht der Reihe nach da - hier genuegt nth-child. */
@media (min-width: 641px) {
  .p-liste--kurz tbody tr:nth-child(n+9) { display: none; }
}
@media (max-width: 640px) {
  .p-liste--kurz tbody tr:nth-child(n+6) { display: none; }
}
/* Ein Knopf ohne Wirkung ist schlimmer als keiner: passt die Liste
   ohnehin in den Ausschnitt, verschwindet er. Aufgeklappt faellt
   p-liste--kurz weg - dann steht "Zuklappen" wieder da. */
@media (min-width: 641px) {
  .p-liste--kurz:not(:has(tbody tr:nth-child(9))) > .p-tabellen__zeile {
    display: none; }
}
@media (max-width: 640px) {
  .p-liste--kurz:not(:has(tbody tr:nth-child(6))) > .p-tabellen__zeile {
    display: none; }
}
/* Mannschaftsansicht: die beiden Zahlen gehoeren zu KACHELN_BREIT und
   KACHELN_SCHMAL im Skript. Der Knopf ist selbst ein Kind des Rasters
   und darf nicht mit ausgeblendet werden. Ueber 900px stehen alle
   sechs Kacheln da - dort gibt es nichts aufzuklappen, und der Knopf
   geht mit. */
@media (max-width: 900px) {
  .p-matches.p-eingeklappt > :nth-child(n+3):not(.p-tabellen__zeile) {
    display: none; }
}
@media (min-width: 901px) {
  .p-matches > .p-tabellen__zeile { display: none; }
}
/* Im Rahmen der Gesamtuebersicht braucht die Meldung seitlich Abstand,
   sonst klebt sie an der Kante. */
.p-leer { color: var(--fg-3); padding: var(--s7) 0; }
.panel > .p-leer { padding-inline: var(--s6); }
.p-mehr { display: flex; justify-content: center; margin-top: var(--p-sp-oben); }
.p-mehr[hidden] { display: none; }
/* Tabellarische Gesamtuebersicht ueber alle Mannschaften */
td.p-alle__team { white-space: nowrap; }
/* Wird das Fenster schmal, geben Gesamtuebersicht UND Ergebnisse Spalten
   auf, von rechts nach links nach Wichtigkeit. Datum, Zeit und Begegnung
   stehen immer da. Ganz schmal faellt zusaetzlich der Wochentag weg.

   Vier Spalten, vier Stufen der Leiter - keine eigenen Zahlen. */
@media (max-width: 1000px) { .p-alle__ort  { display: none; } }
@media (max-width:  900px) { .p-alle__wett { display: none; } }
@media (max-width:  640px) { .p-alle__team { display: none; } }
@media (max-width:  480px) { .p-alle__tag  { display: none; }
                             .p-alle__jahr { display: none; } }
/* Die Platzspalte nimmt nur die Breite, die sie braucht - dort steht
   hoechstens eine zweistellige Zahl. width: 1% heisst im
   Tabellenlayout "so schmal wie moeglich"; der frei werdende Platz
   geht an die Vereinsspalte. */
.p-tabelle table.t th:first-child,
.p-tabelle table.t td:first-child { width: 1%; white-space: nowrap; }

/* Die Ligatabelle ist AUFBAUEND gedacht: die schmalste Ansicht ist
   der Grundzustand, mit mehr Platz kommen Angaben hinzu. Deshalb
   min-width und nicht max-width - so steht die Reihenfolge des
   Hinzukommens in den Regeln und laesst sich nicht verdrehen.

     immer         Platz, Verein, Spiele, Punkte
     ab  481px     dazu die Tordifferenz - auf dem Telefon passt sie
                   nicht mehr in die Breite
     ab  641px     dazu das Torverhaeltnis - dieselbe Grenze, an der
                   das Nachrichten-Mauerwerk auf zwei Spalten geht und
                   die Dreierzeile im Kopf sich aufloest. Eine Zahl,
                   nicht drei nebeneinander.
     ab  901px     dazu Gewonnen, Unentschieden, Verloren
     ab 1001px     dazu das Vereinswappen in der Vereinsspalte

   Die Tordifferenz sagt in einer Zahl, was das Torverhaeltnis in
   zweien sagt - deshalb steht sie im Grundzustand und das
   Verhaeltnis kommt als erste Stufe dazu. G/U/V stecken in Spielen
   und Punkten und kommen danach. Das Wappen traegt gar keine
   Angabe - es kommt zuletzt.

   Ueber Klassen an den Zellen, nicht ueber nth-child: Klassen
   ueberleben eine Spaltenaenderung, Positionsangaben nicht. */
.p-tab__diff, .p-tab__tore, .p-tab__guv { display: none; }
@media (min-width:  481px) { .p-tab__diff { display: table-cell; } }
@media (min-width:  641px) { .p-tab__tore { display: table-cell; } }
@media (min-width:  901px) { .p-tab__guv  { display: table-cell; } }

/* Das Wappen steht nur, wenn es als Datei vorliegt (img.sb-wappen aus
   spiel_tabelle.php). Die leere runde Flaeche ist entfallen -
   Auftraggeber am 01.10.2026 auf die Frage "Leere Wappenkreise in den
   Tabellen: raus oder bleiben?": "raus". Ohne Wappen steht der
   Vereinsname buendig; ein leeres Feld (Startseite, start_spieltag.php)
   bleibt in jeder Breite verborgen.

   Geprueft am 25.08.2026: die Wappen liegen bei fussball.de als PNG
   an einer festen Adresse und sind beschaffbar. Sie kommen aber NICHT
   als externer Verweis hierher - das bricht die Zusage aus ADR-0001.
   Der Abrufjob holt sie und legt sie als Datei ab. */
.p-tab__wappen { display: none; }
@media (min-width: 1001px) {
  img.p-tab__wappen { display: inline-block; width: 22px; height: 22px;
                      margin-right: var(--s5); vertical-align: middle; }
}
/* Jede Ergebniszeile fuehrt auf die Mannschaftsseite. */
.p-ergebnisse tbody tr { cursor: pointer; }

/* Zwei gleichrangige Titel nebeneinander. Der aktive traegt die volle
   Schriftfarbe, der andere ist zurueckgenommen - klickbar bleiben beide. */
/* Ueber die volle Breite verteilt: Ergebnisse linksbuendig, Tabellen
   mittig, Spielplan rechtsbuendig. Der Kopf der Spieltagssektion hat
   rechts nichts stehen, deshalb darf sein Lead die Breite nehmen. */
.p-titelwahl { display: flex; align-items: baseline;
               justify-content: space-between;
               gap: clamp(var(--s6), 2vw, var(--s9));
               flex-wrap: wrap; }
.p-kopfreihe .p-head__lead { flex: 1; }
/* Im schmalen Fenster untereinander. Nebeneinander wirken drei Woerter
   in Anzeigegroesse zu wuchtig, und sie stehen ohnehin dicht an der
   Kante - die Schrift haengt an der Fensterbreite. */
@media (max-width: 640px) {
  .p-titelwahl { flex-direction: column; align-items: flex-end;
                 gap: var(--s3); }
}
/* Solange die drei Titel nebeneinander stehen, steht die
   Reiterreihe darunter - .p-kopfreihe ist dann ein gewoehnlicher
   Block. Stehen die Titel untereinander, ruecken die beiden
   nebeneinander: links die Titel, rechts die Auswahl. Es ist immer
   nur eine der drei Reiterreihen sichtbar, deshalb teilen sie sich
   dieselbe Rasterzelle. */
@media (max-width: 640px) {
  /* Zwei Zeilen:

       Zeile 1   die Saisonzeile, ueber alle Spalten
       Zeile 2   links das Klappmenue der Mannschaften, in der Mitte
                 das der Ansicht, rechts der Verweis

     Die drei stehen auf einer Hoehe und sind nur so breit, wie ihre
     Beschriftung es verlangt. Damit sie sich eine Rasterzeile teilen
     koennen, tragen ihre Huellen display:contents.

     Der Titel steht mittig ZWISCHEN den beiden Schaltern, nicht
     mittig auf der Seite. Bei ungleich breiten Schaltern ist das
     nicht dasselbe: mit gleich breiten Aussenspalten bleibt neben
     dem schmaleren Schalter mehr Luft, und der Titel wirkt nach
     rechts gerueckt. Deshalb aussen auto, in der Mitte der Rest -
     und der Titel darin zentriert.

     Unter der Saisonzeile steht der doppelte Standardabstand, nach
     unten der einfache. */
  .p-kopfreihe { display: grid;
                 grid-template-columns: auto minmax(0,1fr) auto;
                 column-gap: var(--s5); row-gap: var(--p-sp-sektion);
                 align-items: center; position: relative;
                 margin-bottom: var(--p-sp-oben); }
  .p-kopfreihe > .p-head,
  .p-kopfreihe > .p-head > .p-head__lead,
  .p-kopfreihe > .p-tabs { display: contents; }
  .p-kopfreihe .p-kicker { grid-column: 1 / -1; grid-row: 1; }
  .p-kopfreihe .chip.p-tabs__auswahl { grid-column: 1; grid-row: 2;
                                       justify-self: start; }
  .p-kopfreihe .p-titelwahl { grid-column: 2; grid-row: 2;
                              justify-self: center; }
  .p-kopfreihe .p-tabs__zu { grid-column: 3; grid-row: 2;
                             justify-self: end; }
  /* Die beiden Felder aussen bekommen hier weniger Innenabstand.
     Sonst ist die Reihe zu voll: der Titel laeuft beidseitig in die
     Luecken hinein, und statt der eingestellten 12px bleiben 4. */
  .p-kopfreihe .chip { padding-inline: var(--s4); }

  /* Die beiden Felder behalten Hoehe, Schrift und Innenabstand der
     Reiter. Ihre Breite richtet sich nach der Beschriftung und
     aendert sich daher mit der gewaehlten Mannschaft. */
  .chip.p-tabs__auswahl { display: inline-flex; gap: .35em; }
  .p-tabs__pfeil { font-size: .6em; line-height: 1; }

  /* Die Ansicht als Auswahlmenue: kein Kasten, nur der Titel und
     ein Pfeil. Die gruene Unterkante bleibt den drei Titeln im
     Menue vorbehalten.

     Der Knopf traegt hier weder Innenabstand noch Unterkante. Sein
     Kasten ist damit die Schrift selbst - sonst liegt seine Mitte
     ueber der Schriftmitte, und die beiden Schalter daneben stehen
     an der Unterkante des Titels statt auf seiner Mitte. */
  /* In der schmalsten Ansicht steht dort nur eine Tabelle und nur
     ein Auswahlmenue - dann heisst der Titel "Tabelle". Beide
     Formen stehen im Markup, umgeschaltet wird per CSS; ohne Skript
     steht die lange da. */
  .p-nurbreit { display: none; }

  /* Das Feld des Pfeils. Links wie rechts gleich breit - und als
     Laenge angegeben, nicht in em, damit auch das Menue damit
     rechnen kann. Es haengt an .p-titelwahl, weil Knopf und Menue
     beide darunter liegen. */
  .p-titelwahl { position: relative; flex-direction: row;
                 align-items: center; gap: 0;
                 --p-pfeil: calc(var(--p-t-hero) * .34); }

  /* Der Knopf ist um das Wort herum symmetrisch: rechts der Pfeil,
     links ein unsichtbarer Zwilling derselben Breite, beide IM
     Fluss. Damit steht das Wort genau in der Mitte des Kastens -
     und weil der Kasten mittig im Raster sitzt, mittig zwischen den
     beiden Schaltern. */
  .p-titel.p-titelwahl__auswahl { display: inline-flex;
                                  align-items: center; gap: var(--s3);
                                  color: var(--fg-1);
                                  padding: 0; border-bottom: 0; }
  .p-titelwahl__auswahl .p-tabs__pfeil,
  .p-titelwahl__auswahl::before { width: var(--p-pfeil); flex: none;
                                  text-align: center; }
  .p-titelwahl__auswahl::before { content: ''; }

  /* Die beiden Klappmenues liegen ueber dem Inhalt darunter - wie
     das Menue im Kopf. Geschlossen sind sie display:none, offen ein
     Raster. Das der Mannschaften haengt am linken Rand, das der
     Ansicht mittig unter seinem Titel. */
  .p-tabs__liste, .p-titelwahl__liste {
                   position: absolute; top: calc(100% + var(--s4));
                   left: 0; z-index: 60; display: none;
                   width: max-content;
                   max-width: calc(100vw - 2 * var(--p-gut));
                   padding: var(--s4) var(--s8);
                   background: var(--bg-body);
                   background: color-mix(in srgb, var(--bg-body) 30%, transparent);
                   -webkit-backdrop-filter: blur(26px) saturate(180%);
                   backdrop-filter: blur(26px) saturate(180%);
                   border: 1px solid color-mix(in srgb, var(--fg-1) 12%, transparent);
                   border-radius: var(--r-lg);
                   box-shadow: 0 24px 60px rgba(0,0,0,.28); }
  .p-tabs__liste.p-offen, .p-titelwahl__liste.p-offen { display: grid; }
  /* Das Menue haengt an der Mitte von Wort UND Pfeil - hier zaehlt
     der Pfeil optisch mit, der unsichtbare Zwilling nicht. Das ist
     die Mitte des Kastens, um die halbe Breite von Zwilling plus
     Spalt nach rechts gerueckt.

     Zwei verschiedene Mitten an einem Knopf: der Titel steht mittig
     ohne den Pfeil, das Menue mittig mit ihm. Genau deshalb braucht
     der Pfeil ein Feld bekannter Breite. */
  .p-titelwahl__liste { top: calc(100% + var(--s4));
                        left: calc(50% + (var(--p-pfeil) + var(--s3)) / 2);
                        transform: translateX(-50%); }
  /* Die Titel im Menue in Menueschrift, nicht in Anzeigegroesse,
     und linksbuendig - ein Knopf steht sonst von sich aus mittig.
     Die gruene Unterkante des aktiven bleibt und wird hier zur
     Trennlinie. */
  .p-titelwahl__liste .p-titel { font-size: var(--t-xs);
                                 padding: var(--s5) 0;
                                 text-align: left;
                                 border-bottom: 1px solid var(--border-subtle);
                                 white-space: nowrap; }
  .p-titelwahl__liste .p-titel:last-child { border-bottom: 0; }
  /* Rahmen, Rundung und Innenabstand hier; die FUELLUNG steht
     weiter unten hinter der Flaechenumkehr - siehe dort. */
  .p-tabs__liste .chip { border: 0; border-radius: 0;
                         height: auto; padding: var(--s5) 0;
                         justify-content: flex-start;
                         border-bottom: 1px solid var(--border-subtle); }
  .p-tabs__liste .chip:last-child { border-bottom: 0; }

}
.p-titel {
  font-family: var(--p-font-display); font-stretch: 87%; font-weight: 700;
  /* Gleiche Groesse wie die Kapitelueberschriften und die
     Mannschaftsnamen in der Buehne. */
  font-size: var(--p-t-hero); line-height: 1.05;
  letter-spacing: .01em; text-transform: uppercase;
  background: none; border: 0; padding: 0 0 4px; cursor: pointer;
  color: var(--fg-3); border-bottom: 3px solid transparent;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.p-titel:hover { color: var(--fg-2); }
.p-titel.on { color: var(--fg-1); border-bottom-color: var(--accent-500); }
.p-titel:focus-visible { outline: 3px solid var(--accent-500); outline-offset: 4px; }

/* Ohne diese drei Zeilen bleiben Reiter und Spielplan beim Umschalten
   sichtbar: display:flex bzw. display:grid schlagen das hidden-Attribut,
   dessen Browserregel nur display:none mit niedriger Spezifitaet setzt. */
.p-tabs[hidden], .p-matches[hidden], .p-alle[hidden] { display: none !important; }

/* Es steht immer genau eine Tabelle da - das Raster hat nur noch
   eine Spalte. Die frueheren zwei nebeneinander und ihr Umbruch bei
   900px sind damit entfallen. */
.p-tabellen { display: grid; grid-template-columns: minmax(0,1fr);
              gap: clamp(var(--s7), 2.5vw, var(--s10)); align-items: start; }
.p-tabelle__kopf { display: flex; flex-wrap: wrap; align-items: baseline;
                   gap: var(--s5); margin: 0 0 var(--s5);
                   font-family: var(--p-font-display); font-stretch: 87%;
                   font-size: 1.15rem; text-transform: uppercase;
                   letter-spacing: .02em; }
.p-tabelle__kopf .label { color: var(--fg-3); }
.p-tabelle table.t { font-size: var(--t-sm); }
.p-tabelle .empty { margin: 0; }
/* Tabellenansicht: eigene Mannschaftsauswahl, Kurzform.
   Ohne Skript stehen alle Tabellen vollstaendig untereinander — die
   Auswahl auf eine und die Klasse p-tabelle--kurz setzt erst
   JavaScript.
   .p-tabelle traegt eine eigene [hidden]-Regel, damit es nicht wie bei
   .p-tabs und .p-matches am display-Wert scheitert. */
.p-tabelle[hidden] { display: none !important; }
/* Der Ausschnitt um die eigene Zeile — zwei drueber, eigene, drei
   drunter — wird hier ausgewaehlt, nicht im Skript. :has() kann die
   Zeilen VOR der eigenen treffen, das ging frueher nicht.
   Die vier Zeilen ganz unten sind die Sonderfaelle: eigene Mannschaft
   auf Platz 1 oder 2, unter den letzten dreien, gar nicht in der
   Tabelle, und Tabellen mit hoechstens sechs Zeilen.
   Geprueft ueber 444 Kombinationen (7 bis 30 Zeilen, jede Position). */
.p-tabelle--kurz tbody tr { display: none; }
.p-tabelle--kurz tr.p-own:not(:nth-child(-n+2)):not(:nth-last-child(-n+3)),
.p-tabelle--kurz tr:has(+ tr.p-own:not(:nth-child(-n+2)):not(:nth-last-child(-n+3))),
.p-tabelle--kurz tr:has(+ tr + tr.p-own:not(:nth-child(-n+2)):not(:nth-last-child(-n+3))),
.p-tabelle--kurz tr.p-own:not(:nth-child(-n+2)):not(:nth-last-child(-n+3)) + tr,
.p-tabelle--kurz tr.p-own:not(:nth-child(-n+2)):not(:nth-last-child(-n+3)) + tr + tr,
.p-tabelle--kurz tr.p-own:not(:nth-child(-n+2)):not(:nth-last-child(-n+3)) + tr + tr + tr,
.p-tabelle--kurz tbody:has(tr.p-own:nth-child(-n+2)) tr:nth-child(-n+6),
.p-tabelle--kurz tbody:has(tr.p-own:nth-last-child(-n+3)) tr:nth-last-child(-n+6),
.p-tabelle--kurz tbody:not(:has(tr.p-own)) tr:nth-child(-n+6),
.p-tabelle--kurz tbody:not(:has(tr:nth-child(7))) tr { display: table-row; }
/* Die Zeile mit dem Aufklappknopf. Sie stand zuerst nur unter den
   Ligatabellen; seit dem 27.08.2026 traegt sie denselben Knopf auch
   unter der Ergebnisliste, der Gesamtuebersicht und den Spielkacheln.
   Im Raster spannt sie ueber alle Spalten, im gewoehnlichen Block
   traegt sie den Zwischenabstand selbst - dort gibt es keinen
   Rasterspalt. Eigene [hidden]-Regel, weil display:flex das Attribut
   sonst schlaegt. */
.p-tabellen__zeile { grid-column: 1 / -1; display: flex;
                     justify-content: center; }
.p-tabellen__zeile[hidden] { display: none !important; }
.p-ergebnisse > .p-tabellen__zeile,
.p-alle > .p-tabellen__zeile { margin-top: var(--p-sp-oben); }
/* Zwei Verweise oben rechts statt einem */
.p-head__links { display: flex; flex-wrap: wrap; gap: var(--s5); }
.p-alle tr.p-alle__vorbei td { color: var(--fg-3); }
.p-alle .p-match__row--own { display: inline; padding: 0; font-size: inherit; }
@media (max-width: 900px) { .p-matches { grid-template-columns: minmax(0,1fr); } }
.p-match { gap: var(--s6); }
.p-match__when { display: flex; justify-content: space-between; gap: var(--s6); }
.p-match__row { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: center;
                gap: var(--s5); font-family: var(--p-font-display); font-stretch: 87%;
                font-weight: 600; font-size: 18px; text-transform: uppercase;
                color: var(--fg-2); padding-block: 2px; }
.p-match__row--own { color: var(--fg-1); font-weight: 700; }
.p-match__goals { font-variant-numeric: tabular-nums lining-nums; font-size: 21px;
                  min-width: 1.6ch; text-align: right; }
.p-match__foot { display: flex; justify-content: space-between; align-items: center;
                 gap: var(--s6); border-top: 1px solid var(--border-subtle);
                 padding-top: var(--s5); margin-top: auto;
                 font-size: var(--t-sm); color: var(--fg-2); }

/* ---- Nachrichten ---- */
.p-two { display: grid; grid-template-columns: minmax(0,1.7fr) minmax(0,1fr);
         gap: clamp(var(--s9), 4vw, var(--s12)); align-items: start; }
@media (max-width: 1000px) { .p-two { grid-template-columns: minmax(0,1fr); } }
.p-news { display: grid; grid-template-columns: minmax(0,1.15fr) minmax(0,1fr);
          gap: clamp(var(--s8), 3vw, var(--s10)); }
@media (max-width: 900px) { .p-news { grid-template-columns: minmax(0,1fr); } }
.p-story { display: grid; gap: var(--s5); align-content: start; color: inherit; }
.p-story:hover { text-decoration: none; }
.p-story:hover .p-kicker::before { width: var(--s10); }
.p-story:hover h3 { color: var(--accent-text); }
.p-story h3 { transition: color var(--fast) var(--ease); }
.p-story--lead h3 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); }
.p-date { font-size: var(--t-sm); color: var(--fg-3); }
.p-list { display: grid; gap: var(--s7); align-content: start; }
.p-list .p-story { grid-template-columns: 92px minmax(0,1fr); gap: var(--s6);
                   padding-bottom: var(--s7); border-bottom: 1px solid var(--border-subtle); }
.p-list .p-story:last-child { border-bottom: 0; padding-bottom: 0; }
.p-list .p-story > div { display: grid; gap: var(--s3); }

/* Bildfläche: ehrlich als Platzhalter gekennzeichnet */
.p-shot { position: relative; aspect-ratio: 16/9; border-radius: var(--r-md);
          border: 1px solid var(--border-subtle); overflow: hidden;
          display: grid; place-items: center;
          background: repeating-linear-gradient(-45deg,
            color-mix(in oklab, var(--accent-text) 9%, var(--surface-2)) 0 12px,
            var(--surface-2) 12px 24px); }
.p-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.p-shot:has(img)::after { content: none; }
.p-shot::after { content: attr(data-label); font-size: var(--t-label); font-weight: 600;
                 letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--fg-3);
                 background: var(--surface-1); padding: var(--s2) var(--s5);
                 border: 1px solid var(--border-subtle); border-radius: var(--r-sm); }
.p-list .p-shot { aspect-ratio: 4/3; }
.p-list .p-shot::after { content: none; }

/* ---- Newsraster: Kopfzeile + Mauerwerk (nach ADR-0003) ----
   Die Zahlen sind aufeinander abgestimmt: Bild + Abstand + Textblock ergibt
   genau ein Vielfaches des 8-px-Rasters, span * (8 + 16) - 16.
     192 + 12 + 116 = 320 = span 14
     240 + 12 + 116 = 368 = span 16
     288 + 12 + 116 = 416 = span 18                                        */
.p-filter { display: flex; flex-wrap: wrap; gap: var(--s3);
            margin-bottom: var(--p-sp-oben); }
.p-filter .chip { cursor: pointer; }

.p-kopfzeile { display: grid; grid-template-columns: repeat(3, minmax(0,1fr));
               gap: var(--s6); margin-bottom: var(--p-sp-oben);
               align-items: stretch; }
.p-kopfzeile .p-story--lead { grid-column: span 2; }
.p-kopfzeile .p-story--lead .p-shot { aspect-ratio: 2/1; }
.p-kopfzeile .p-story--neben { grid-column: span 1; }
.p-kopfzeile .p-story--neben .p-shot { aspect-ratio: auto; height: 100%; min-height: 180px; }
.p-kopfzeile .p-story--neben { grid-template-rows: 1fr auto; }

.p-mauerwerk { display: grid; grid-template-columns: repeat(3, minmax(0,1fr));
               gap: var(--s6); grid-auto-rows: 8px;
               /* Ohne align-items:start streckt das Raster jede Kachel auf ihre
                  Zeilenhoehe - das Mauerwerk faellt dann in sich zusammen. */
               align-items: start; }
.p-mauerwerk .p-story { gap: 12px; }
.p-mauerwerk .p-kachel__text { height: 116px; overflow: hidden;
                               display: grid; gap: var(--s3); align-content: start; }
.p-mauerwerk .p-kachel__text h3 { font-size: 1.05rem; line-height: 1.3;
                                  display: -webkit-box; -webkit-line-clamp: 2;
                                  -webkit-box-orient: vertical; overflow: hidden; }
@media (min-width: 901px) {
  .p-mauerwerk .p-h1 { grid-row: span 14; }
  .p-mauerwerk .p-h2 { grid-row: span 16; }
  .p-mauerwerk .p-h3 { grid-row: span 18; }
  .p-mauerwerk .p-h1 .p-shot { aspect-ratio: auto; height: 192px; }
  .p-mauerwerk .p-h2 .p-shot { aspect-ratio: auto; height: 240px; }
  .p-mauerwerk .p-h3 .p-shot { aspect-ratio: auto; height: 288px; }
}
@media (max-width: 900px) {
  /* Die Span-Regeln der Hoehenklassen gelten erst ab 901px. Bliebe hier
     grid-auto-rows: 8px stehen, bekaeme jede Kachel eine 8px hohe Zeile,
     wuerde aber auf ihre echte Hoehe wachsen - alles laege uebereinander. */
  .p-kopfzeile, .p-mauerwerk { grid-template-columns: repeat(2, minmax(0,1fr));
                               grid-auto-rows: auto; }
  .p-kopfzeile .p-story--lead { grid-column: span 1; }
  .p-kopfzeile .p-story--lead .p-shot { aspect-ratio: 16/9; }
}
@media (max-width: 640px) {
  /* Eine Spalte ist kein Mauerwerk, sondern eine Liste. */
  .p-kopfzeile, .p-mauerwerk { grid-template-columns: minmax(0,1fr); grid-auto-rows: auto; }
  .p-mauerwerk .p-shot { aspect-ratio: 16/9; height: auto; }
  .p-mauerwerk .p-kachel__text { height: auto; }
  /* Die Mindesthoehe aus der breiten Fassung MUSS hier zurueck auf 0.
     Sonst rechnet aspect-ratio aus 180px Hoehe 320px Breite - und die
     Seite laeuft bei schmalen Geraeten aus dem Bild. */
  .p-kopfzeile .p-story--neben .p-shot { aspect-ratio: 16/9;
                                         height: auto; min-height: 0; }
}

/* ---- Hoechstens drei Zeilen auf der Startseite ----
   Alle acht Kacheln stehen immer im Markup; welche davon zu sehen sind,
   entscheidet allein das CSS - so steht ohne JavaScript der vollstaendige
   Inhalt da. Dasselbe Muster traegt schon das Kurzmeldungsband, das seine
   vierte und fuenfte Meldung ebenso ausblendet.
     drei Spalten (ab 901px):   Kopfzeile 1 Zeile + 2 Mauerwerkszeilen = 8
     zwei Spalten (641-900px):  Kopfzeile 1 Zeile + 2 Mauerwerkszeilen = 6
     eine Spalte  (bis 640px):  Kopfzeile 2 Zeilen + 1 Mauerwerkszeile  = 3
   Beide Klassen plus nth-child sind noetig, weil .p-mauerwerk .p-story
   bereits ein eigenes display traegt - ein schwaecherer Selektor bliebe
   wirkungslos. */
@media (max-width: 900px) {
  .p-mauerwerk .p-story:nth-child(n+5) { display: none; }
}
@media (max-width: 640px) {
  .p-mauerwerk .p-story:nth-child(n+2) { display: none; }
}

/* Der Verweis unter den Kacheln. Dieselbe Form wie der Aufklappknopf
   unter den Tabellen: mittig in einer eigenen Zeile, mit eigener
   [hidden]-Regel, weil display:flex das Attribut sonst schlaegt.
   Der Abstand ist der Zwischenabstand der Sektion, --p-sp-oben. */
.p-news__mehr { display: flex; justify-content: center;
                margin-top: var(--p-sp-oben); }
.p-news__mehr[hidden] { display: none !important; }

/* ---- Tabelle: eigene Zeile und Formanzeige ---- */
table.t tbody tr.p-own { background: var(--accent-tint); }
table.t tbody tr.p-own td { color: var(--fg-1); }
table.t tbody tr.p-own td:first-child { box-shadow: inset 3px 0 0 var(--accent-500); }
.p-form { display: inline-flex; gap: 3px; }
.p-form i { width: 16px; height: 16px; border-radius: var(--r-sm); display: inline-block;
            font-style: normal; font-size: 10px; line-height: 16px; text-align: center;
            font-weight: 700; color: #fff; }
.p-form i.s { background: var(--success); }
.p-form i.u { background: var(--p-draw); }
.p-form i.n { background: var(--danger); }
.p-note { margin-top: var(--s5); }

/* ---- Mannschaften ---- */
.p-teams { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: var(--s6); }
@media (max-width: 900px) { .p-teams { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 480px) { .p-teams { grid-template-columns: minmax(0,1fr); } }
/* Keine einzelne Kachel allein in der letzten Reihe (Kapitel 7): in den
   zwei Spalten von 481-900px nimmt die letzte Kachel einer ungeraden
   Gruppe beide Spalten - auf /mannschaften "Herren Ue35" (3 = 2 + 1) und
   "F-Junioren II" (7 = 2 + 2 + 2 + 1). Muster wie die fuenf Wahlen im
   Mitgliedsantrag (antrag.css). Die Startseite hat ihr eigenes Raster
   (p-teams--start, startseite.css Abschnitt 6). Auftrag 160, 01.10.2026. */
@media (min-width: 481px) and (max-width: 900px) {
  .p-teams:not(.p-teams--start) > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
.p-team-card { gap: var(--s3); padding: var(--s7); }
.p-name { font-family: var(--p-font-display); font-stretch: 82%; font-weight: 700;
          font-size: 19px; text-transform: uppercase; color: var(--fg-1); }
/* Zentrale Mannschaftsseite (web/mannschaften.php): Gruppen "Herren" und
   "Junioren" mit zweiter Ueberschrift in h3-Groesse, je Karte darunter
   das naechste Spiel. Dieselben Karten wie auf der Startseite. */
.p-teams__block + .p-teams__block { margin-top: var(--p-sp-sektion); }
.p-teams__kopf.p-display { font-size: var(--p-t-h3); line-height: 1.05;
                           margin: 0 0 var(--s6); }
.p-team-card__spiel { display: grid; gap: var(--s1); margin-top: var(--s3);
                      font-size: var(--t-sm); color: var(--fg-2); }
.p-team-card__spiel .label { color: var(--fg-3); }

/* ---- Mitgliedsband ---- */
/* Die Sektionen folgen einem fortlaufenden Muster: weiss, grau, gruen,
   und wieder von vorn. Das Gruen hing bisher am Aufnahmeband; es steht
   jetzt als eigene Sektionsklasse daneben. */
.p-sec--gruen, .p-join { background: var(--accent-500); color: var(--accent-fg); }
/* Was auf der gruenen Flaeche steht, muss hell sein. */
.p-sec--gruen .p-display, .p-sec--gruen .label { color: var(--accent-fg); }
.p-sec--gruen .p-kicker::before { background: var(--accent-fg); }
/* Der zurueckgenommene Knopf UND die Reiter stehen auf jeder Flaeche im
   Gegenzug zum Untergrund, sonst verschwinden sie. Beide tragen als
   Standardfuellung --surface-2, und die liegt in beiden Modi dicht an
   einer der beiden Sektionsflaechen.

                 hell             dunkel
     p-sec--alt  Flaeche weiss    Flaeche grau      Knopf --bg-body
                 Knopf grau       Knopf schwarz
     ohne        Flaeche grau     Flaeche schwarz   Knopf --surface-1
                 Knopf weiss      Knopf grau

   "Ohne" heisst: ohne Flaechenklasse - diese Sektionen zeigen den
   Seitenhintergrund. */
/* .chip.on bleibt aussen vor - der angewaehlte Reiter hat seine eigene
   gruene Fuellung. */
.p-sec--alt .btn--secondary,
.p-sec--alt .chip:not(.on) { background: var(--bg-body); }
.p-sec--alt .btn--secondary:hover { background: var(--surface-2); }
.p-sec:not(.p-sec--alt):not(.p-sec--gruen):not(.p-join) .btn--secondary,
.p-sec:not(.p-sec--alt):not(.p-sec--gruen):not(.p-join) .chip:not(.on) {
  background: var(--surface-1); }
.p-sec:not(.p-sec--alt):not(.p-sec--gruen):not(.p-join) .btn--secondary:hover {
  background: var(--surface-2); }
/* Ausnahme: Im Klappmenue tragen die Reiter keine eigene Flaeche -
   darunter liegt schon die durchscheinende Flaeche des Menues.

   Diese Regel MUSS hinter der Umkehr stehen und deren Spezifitaet
   erreichen. Eine Regel mit .p-tabs__liste .chip (0,2,0) weiter oben
   verliert gegen die Umkehr (0,5,0) - und die Eintraege blieben
   weiss, obwohl das Menue durchscheinend war. */
@media (max-width: 640px) {
  .p-sec--alt .p-tabs__liste .chip,
  .p-sec:not(.p-sec--alt):not(.p-sec--gruen):not(.p-join) .p-tabs__liste .chip {
    background: none; }
}
.p-join .p-wrap { display: grid; grid-template-columns: minmax(0,1.4fr) minmax(0,1fr);
                  gap: clamp(var(--s8), 4vw, var(--s11)); align-items: center; }
@media (max-width: 900px) { .p-join .p-wrap { grid-template-columns: minmax(0,1fr); } }
.p-join h2 { color: var(--accent-fg); font-size: clamp(2rem, 4.2vw, 3.2rem); margin-top: var(--s5); }
.p-join p { color: var(--accent-fg); opacity: .92; margin-top: var(--s6); max-width: 52ch; }
.p-join .label { color: var(--accent-fg); opacity: .85; }
.p-join .p-kicker::before { background: var(--accent-fg); }
.p-join .btn--primary { background: var(--accent-fg); color: var(--accent-500); border-color: var(--accent-fg); }
.p-join .btn--primary:hover { background: #fff; border-color: #fff; box-shadow: none; }
.p-join .btn--secondary { background: transparent; color: var(--accent-fg); border-color: rgba(255,255,255,.45); }
.p-join .btn--secondary:hover { background: rgba(255,255,255,.12); border-color: #fff; }
.p-beitraege { list-style: none; margin: var(--s8) 0 0; padding: 0;
               display: grid; gap: var(--s4); }
.p-beitraege li { display: flex; align-items: baseline; gap: var(--s5);
                  color: var(--accent-fg); }
.p-beitraege b { font-family: var(--p-font-display); font-stretch: 82%;
                 font-weight: 700; font-size: 24px; min-width: 4.5ch;
                 font-variant-numeric: tabular-nums; }
.p-beitraege span { font-size: var(--t-sm); opacity: .88; }
/* Die Knoepfe im Mitgliedsband (Startseite #mitglied, Kopf von
   /mitglied-werden) stehen untereinander und sind gleich breit (Auftrag
   160, 01.10.2026; Befund 1 der Nachpruefung, Auftraggeber: "Ja" -
   "gleich breit und sauber gereiht"). Ab 901px, wo das Band zweispaltig
   ist, eine Spalte rechts, so breit wie der laengste Knopf; bis 900px,
   wo es einspaltig ist, ueber die volle Breite. Vorher brachen sie frei
   um: 481-900px stand "Zum Schnuppertraining" allein in der zweiten
   Reihe, die Breiten waren 263, 207 und 249px. */
.p-join .p-acts { display: grid; grid-template-columns: minmax(0, max-content);
                  justify-content: end; }
@media (max-width: 900px) { .p-join .p-acts { grid-template-columns: minmax(0, 1fr); } }

/* ---- Termine ---- */
.p-dates { display: grid; border-top: 1px solid var(--border-subtle); }
.p-dates a { display: grid; grid-template-columns: 84px minmax(0,1fr) auto; gap: var(--s7);
             align-items: center; padding: var(--s6) 0; color: inherit;
             border-bottom: 1px solid var(--border-subtle);
             transition: padding-left var(--normal) var(--ease); }
.p-dates a:hover { padding-left: var(--s3); text-decoration: none; }
.p-day { font-family: var(--p-font-display); font-stretch: 82%; font-weight: 700;
         line-height: .95; font-variant-numeric: tabular-nums; color: var(--fg-1); }
.p-day b { display: block; font-size: 30px; }
.p-what { display: grid; gap: var(--s1); }
.p-what strong { font-family: var(--p-font-display); font-stretch: 87%; font-weight: 700;
                 font-size: 18px; text-transform: uppercase; color: var(--fg-1); }
.p-where { font-size: var(--t-sm); color: var(--fg-3); text-align: right; }
@media (max-width: 640px) {
  .p-dates a { grid-template-columns: 68px minmax(0,1fr); gap: var(--s6); }
  .p-where { grid-column: 2; text-align: left; }
}

/* ---- Sponsoren ---- */
.p-sponsors { display: grid; gap: var(--s5); align-items: stretch;
              /* min(200px,100%) statt 200px: sonst bleibt die Spalte auch dann
                 200px breit, wenn der Kasten schmaler ist - und genau daraus
                 entsteht in schmalen Fenstern ein Rollbalken. */
              grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); }

.p-partner {
  display: flex; flex-direction: column; align-items: center; gap: var(--s4);
  padding: var(--s6) var(--s5) var(--s5); min-width: 0;
  background: var(--surface-1); border: 1px solid var(--border-subtle);
  border-radius: var(--r-md); color: inherit; text-align: center;
  transition: border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.p-partner:hover { border-color: var(--accent-border); background: var(--surface-2);
                   text-decoration: none; }
.p-partner:hover .p-partner__name { color: var(--accent-text); }
.p-partner--ohne { cursor: default; }

/* Logoschild: FESTE Hoehe. Mit aspect-ratio loesen prozentuale Bildhoehen
   nicht auf, dann rendern die Logos in Originalgroesse und sprengen alles.
   Fremde Logos sind meist dunkle Schrift auf transparentem Grund und
   verschwinden im dunklen Thema — deshalb steht das Schild auf Weiß. */
.p-partner__logo {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 88px; flex: none; overflow: hidden;
  padding: var(--s5); border-radius: var(--r-sm);
  background: #ffffff; border: 1px solid var(--border-subtle);
  font-family: var(--p-font-display); font-stretch: 82%; font-weight: 700;
  font-size: 20px; letter-spacing: .06em; color: #b0b0b0;
}
.p-partner__logo img {
  display: block; max-width: 100%; max-height: 100%;
  width: auto; height: auto; object-fit: contain;
}
/* Nur fuer transparente Logos mit heller Tinte. */
.p-partner__logo--dunkel { background: #1a1a1a; border-color: #333333; }
.p-partner__logo--leer { color: #b0b0b0; }

.p-partner__name { font-size: var(--t-sm); font-weight: 600; color: var(--fg-1);
                   line-height: 1.3; overflow-wrap: anywhere; margin-top: auto;
                   transition: color var(--fast) var(--ease); }

/* ---- Fuß ---- */
.p-foot { background: var(--p-band); color: var(--p-band-fg-2);
          padding-block: var(--p-sp-m) var(--p-sp-s); }
.p-foot a { color: inherit; }
.p-foot a:hover { color: #fff; }
.p-foot .p-brandname { color: var(--p-band-fg); }
.p-cols { display: grid; grid-template-columns: minmax(0,1.4fr) repeat(3, minmax(0,1fr));
          gap: clamp(var(--s8), 3vw, var(--s10)); }
@media (max-width: 900px) { .p-cols { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 480px) { .p-cols { grid-template-columns: minmax(0,1fr); } }
.p-foot h4 { color: var(--p-band-fg); margin-bottom: var(--s6);
             font-size: var(--t-label); font-weight: 700;
             letter-spacing: var(--tr-wide); text-transform: uppercase; }
.p-foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s4);
             font-size: var(--t-sm); }
.p-legal { margin-top: var(--p-sp-s); padding-top: var(--s7);
           border-top: 1px solid rgba(255,255,255,.1);
           display: flex; flex-wrap: wrap; gap: var(--s4) var(--s9);
           justify-content: space-between; font-size: var(--t-xs); }
.p-legal nav { display: flex; flex-wrap: wrap; gap: var(--s7); }

/* Anklickbares hebt sich beim Ueberfahren um zwei Pixel an. Die Liste im
   Uebergang ist vollstaendig, weil ein zweites transition das erste
   ersetzt und die Farbwechsel sonst hart umschlagen. */
.btn, .chip, .card--link, .p-partner, .p-story,
.p-dates a, .p-strip a, .p-team-card {
  transition: transform .15s var(--ease),
              background var(--fast) var(--ease),
              border-color var(--fast) var(--ease),
              color var(--fast) var(--ease),
              box-shadow var(--fast) var(--ease);
}
/* Zusatzzeile in einer Tabellenzelle: leiser als der Haupteintrag,
   eigene Zeile. Genutzt in den Terminen und den Trainingszeiten. */
.p-zusatz { display: block; font-size: var(--t-xs); color: var(--fg-3);
            font-weight: 400; margin-top: 2px; }
/* Die Jahreszahl faellt auf dem Telefon weg - dieselbe Regel wie in der
   Gesamtuebersicht. Das Datum bleibt.
   Und die Zeitspalte gibt auf, statt die Tabelle scrollen zu lassen -
   der Standard des Projekts fuer breite Tabellen. Die Zeit steht dann
   in der Zusatzzeile; beide Formen stehen im Markup, umgeschaltet
   wird per CSS. */
.p-nurschmal { display: none; }
@media (max-width: 480px) {
  .p-jahr { display: none; }
  .p-termin__zeit { display: none; }
  .p-nurschmal { display: inline; }
}
.btn:hover, .chip:hover, .card--link:hover, .p-partner:hover,
.p-story:hover, .p-dates a:hover, .p-strip a:hover,
.p-team-card:hover { transform: translateY(-2px); }

/* ---- Einblenden beim Scrollen ----
   Verborgen wird nur, wenn Skript laeuft: seite.php setzt die Klasse
   p-js an <html>, bevor gezeichnet wird, und bbc08.js blendet ein.
   Ohne Skript stuenden die Abschnitte sonst fuer immer unsichtbar da. */
.p-js .p-reveal { opacity: 0; transform: translateY(14px); }
.p-js .p-reveal.in { opacity: 1; transform: none;
                     transition: opacity .6s var(--ease), transform .6s var(--ease); }
@media (prefers-reduced-motion: reduce) {
  .p-js .p-reveal { opacity: 1; transform: none; }
  .btn:hover, .chip:hover, .card--link:hover, .p-partner:hover,
  .p-story:hover, .p-dates a:hover, .p-strip a:hover,
  .p-team-card:hover { transform: none; }
  .p-stage::after { display: none; }
}

/* ---- Trainingsplan als Stundenplan --------------------------------
   Vorher stand hier eine Liste mit 24 Zeilen: 1606px hoch, hoeher als
   ein Bildschirm. Jetzt ein Raster.

   Breit (ab 1301px): eine Spalte fuer die Zeit, dann vier Tage zu je
   vier Bahnen - die Platzsegmente A, B, C, D. Ein Eintrag steht in
   seinen Segmenten (A+B belegt zwei Bahnen, Grossfeld alle vier) und
   ist so hoch wie er dauert. Weil ein Segment nie doppelt belegt ist,
   stossen zwei Eintraege nie zusammen - auch nicht die vier, die
   montags um 16:30 gleichzeitig laufen.

   Schmal (bis 1300px): dieselben Kaesten, dieselbe Auszeichnung. Die
   vier Tage stehen untereinander, jeder mit eigener Zeitspalte. Die
   Lage steckt in Eigenschaften am Element (--z/--c breit, --zs/--cs
   schmal); die Umschaltung tauscht nur, welche gelesen wird. Das
   Raster kommt ohne Skript aus. Auf der Startseite klappt startseite.js
   es auf den heutigen Wochentag ein (startseite.css, Abschnitt 7).

   Die Tage sind display: contents. Der Kasten selbst zeichnet nichts,
   seine Kinder haengen unmittelbar im Raster; --z und --zs erben
   trotzdem. */
/* Ein Tagesblock: Kopfzeile, neun Halbstundenzeilen, Schlusszeile.
   Er steht in einer Eigenschaft, weil der schmale Aufbau ihn viermal
   hintereinander braucht - repeat() darf nicht in repeat() stehen,
   die Ersetzung einer Eigenschaft aber schon. */
.p-plan { --p-plan-block: auto repeat(9, minmax(32px, auto)) auto;
          display: grid; padding: var(--s6);
          grid-template-columns: auto repeat(16, minmax(0, 1fr));
          grid-template-rows: var(--p-plan-block); }
.p-plan__tag { display: contents; }
/* Trennstrich zwischen den Tagen. Liegt hinter den Eintraegen, weil er
   im Markup vor ihnen steht. */
.p-plan__saeule { grid-column: var(--c) / span var(--breite); grid-row: 1 / -1;
                  border-left: 1px solid var(--border-subtle); }
.p-plan__linie { grid-column: 1 / -1; grid-row: var(--z);
                 border-top: 1px solid var(--border-subtle); }
/* Im breiten Aufbau teilen sich alle vier Tage eine Zeitspalte und ein
   Liniennetz. Die drei weiteren Saetze stehen im Markup, weil der
   schmale Aufbau sie braucht. */
.p-plan__tag:not(:first-child) .p-plan__zeit { display: none; }
.p-plan__tag:not(:first-child) .p-plan__linie { display: none; }
.p-plan__tagname { grid-column: var(--c) / span var(--breite); grid-row: var(--z);
                   font-size: var(--t-label); font-weight: 600;
                   letter-spacing: var(--tr-label); text-transform: uppercase;
                   color: var(--fg-3); padding: 0 var(--s4) var(--s5); }
.p-plan__zeit { grid-column: 1; grid-row: var(--z); align-self: start;
                font-family: var(--font-mono); font-size: var(--t-label);
                line-height: 1; color: var(--fg-3); white-space: nowrap;
                padding: 3px var(--s5) 0 0; }
.p-plan__eintrag { grid-column: var(--c) / span var(--breite);
                   grid-row: var(--z) / span var(--d);
                   display: flex; flex-direction: column; justify-content: center;
                   gap: 2px; min-width: 0; margin: 1px; padding: var(--s3);
                   background: var(--surface-2);
                   border: 1px solid var(--border-subtle);
                   border-radius: var(--r-md); }
/* Trennung nach deutschen Regeln - die Seite ist lang="de". Sie greift
   nur, wo ein Wort nicht in seine Bahn passt: im breiten Aufbau bleibt
   "Junioren" ungetrennt, auf dem Telefon wird es getrennt. Kennt der
   Browser keine Trennregeln, faengt overflow-wrap den Rest ab - dann
   bricht es haesslich, aber nichts laeuft aus dem Kasten. */
.p-plan__wer { font-size: var(--t-xs); font-weight: 600; color: var(--fg-1);
               line-height: 1.15; overflow-wrap: break-word;
               -webkit-hyphens: auto; hyphens: auto; }
.p-plan__platz { font-size: var(--t-label); font-weight: 600; color: var(--fg-3);
                 letter-spacing: var(--tr-label); line-height: 1; }
@media (max-width: 1300px) {
  /* Vier Tagesbloecke untereinander. Die Halbstundenzeile ist hier
     niedriger als im breiten Aufbau: die Bahnen sind vielfach breiter,
     ein Name passt in eine Zeile, und vier Bloecke uebereinander
     summieren sich. */
  .p-plan { --p-plan-block: auto repeat(9, minmax(22px, auto)) auto;
            grid-template-columns: auto repeat(4, minmax(0, 1fr));
            grid-template-rows: var(--p-plan-block) var(--p-plan-block)
                                var(--p-plan-block) var(--p-plan-block); }
  .p-plan__saeule { display: none; }
  .p-plan__tag:not(:first-child) .p-plan__zeit { display: block; }
  .p-plan__tag:not(:first-child) .p-plan__linie { display: block; }
  .p-plan__linie { grid-row: var(--zs); }
  .p-plan__zeit { grid-row: var(--zs); }
  .p-plan__eintrag { grid-column: var(--cs) / span var(--breite);
                     grid-row: var(--zs) / span var(--d); }
  .p-plan__tagname { grid-column: 1 / -1; grid-row: var(--zs);
                     font-size: var(--t-sm); color: var(--fg-1);
                     text-transform: none; letter-spacing: var(--tr-tight);
                     padding: var(--s8) 0 var(--s5); }
  .p-plan__tag:first-child .p-plan__tagname { padding-top: 0; }
}
/* Telefon, gemessen bei 320px: die Bahn ist 51,4px breit, davon bleiben
   41,4px fuer den Namen. "Junioren" braucht bei 11px 42,9px - anderthalb
   Pixel zu viel, und der Umbruch faellt mitten ins Wort. Knapperer Rand
   am Raster, knappere Zeitspalte, kein Aussenrand am Kasten: zusammen
   4,5px mehr. Danach stehen 45,9px zur Verfuegung und die Namen bleiben
   ganz. */
@media (max-width: 480px) {
  .p-plan { padding: var(--s4); }
  .p-plan__eintrag { padding: var(--s2); margin: 0; }
  .p-plan__wer { font-size: var(--t-label); }
  .p-plan__zeit { padding-right: var(--s3); }
}
/* Der zweite Kopf in der Sektion braucht Luft nach oben - der erste
   bekommt sie von der Sektion selbst. */
.p-plan__kopf { margin-top: var(--p-sp-m); }

/* ---- Facebook und Instagram ---------------------------------------
   Aus dem System uebernommen: ein Knopf ohne Beschriftung ist so breit
   wie hoch. Damit sind die beiden Zeichen im Kopf genauso hoch wie
   "Mitglied werden" - beide --h-btn. */
.btn--icon { width: var(--h-btn); padding: 0; }
/* Kein automatischer Rand an dieser Gruppe: der sitzt an .p-nav und
   teilte den freien Platz sonst zwischen beiden auf - Navigation und
   Zeichen wuerden auseinandergezogen. */
.p-kopfsocial { display: none; gap: var(--s4); flex: none; }
.p-kopfsocial svg, .p-fab svg { fill: currentColor; display: block; }
.p-kopfsocial svg { width: 17px; height: 17px; }
/* Erst da, wo die volle Hauptnavigation steht - die breite Ansicht.
   Darunter traegt die Kopfzeile schon die drei Striche. */
@media (min-width: 1501px) { .p-kopfsocial { display: flex; } }
/* In der knappen Fassung weicht die Hauptnavigation - die Zeichen
   weichen mit ihr, und die schwebenden unten rechts uebernehmen. */
.p-masthead.p-knapp .p-kopfsocial { display: none; }

/* Schwebend unten rechts. Eigene [hidden]-Regel, sonst schlaegt das
   display aus der Klasse das hidden-Attribut. */
.p-fab { position: fixed; z-index: 45;
         right: clamp(12px, 2vw, 24px); bottom: clamp(12px, 2vw, 24px);
         display: flex; flex-direction: column; gap: var(--s4); }
.p-fab[hidden] { display: none; }
.p-fab svg { width: 20px; height: 20px; }
/* Kein eigenes transition: die vollstaendige Liste steht schon an .btn.
   Ein zweites wuerde sie ersetzen und die Farben hart umschlagen lassen.
   Die Rundung steht dagegen eigens hier: .btn traegt seit 01.10.2026 die
   der Kaestchen (--r-lg), die schwebenden Knoepfe bleiben Kreise. */
.p-fab__knopf { width: 44px; height: 44px; min-height: 0; padding: 0; flex: none;
                border-radius: var(--r-full);
                box-shadow: 0 6px 20px rgba(0,0,0,.28); }
.p-fab__knopf:hover { box-shadow: 0 0 16px var(--accent-glow),
                                  0 6px 20px rgba(0,0,0,.28); }
.p-fab:not([hidden]) { animation: p-fab-auf .18s var(--ease) both; }
@keyframes p-fab-auf { from { opacity: 0; transform: translateY(10px); }
                       to   { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .p-fab:not([hidden]) { animation: none; }
}

.vh { position: absolute; width: 1px; height: 1px; overflow: hidden;
      clip-path: inset(50%); white-space: nowrap; }


/* ██ C · RAHMEN ██████████████████████████████████████████████████████████ */
/* Nachtraege fuer die echte Seite. Alles oberhalb steht woertlich wie im
   Stilblock der Arbeitskopie des Templates; hier steht nur, was dort
   fehlt:
     C1  Kopf- und Fusskorrekturen der live abgenommenen 30_Design/index.html
         vom 31.08.2026 - woertlich, wo nicht anders vermerkt
     C2  Menueknopf im Telefonkopf - neu gebaut, Abnahme noetig
     C3  Platzhalter fuer echte Datenluecken
     C4  eigene Korrekturen am Fuss - Abnahme noetig
     C5  gemeinsame Bausteine des Grundkonstrukts (29.09.2026)
   Die Reihenfolge ist Absicht: diese Regeln stehen HINTER dem Template
   und gewinnen bei gleicher Spezifitaet.                                   */

/* ─── C1 · KORREKTUREN DER LIVE-SEITE ────────────────────────────────────── */

/* ==== Milchglas fuer Facebook und Instagram ==========================
   Fast durchsichtige Flaeche, die verwischt, was dahinterliegt; sichtbar
   bleiben nur der Rand und das Symbol. Unschaerfe und Saettigung sind
   dieselben Werte, die das Ueberlagerungsmenue des Kopfes schon traegt
   (blur(26px) saturate(180%)) - eine Handschrift, nicht zwei.

   Der Rand bleibt 1px wie an jedem .btn, sonst wuerde er die Hoehe um
   2px verschieben und die vier Knoepfe im Kopf liefen auseinander.

   Auf Ansage noch einmal 20 Prozent durchsichtiger: die Alphawerte mit
   0,8 multipliziert - Fuellung .10 -> .08, Rand .35 -> .28. Gesenkt wird
   allein das Alpha in background und border-color. KEIN opacity am
   Element: das naehme das Symbol mit, und das soll voll deckend bleiben. */
.p-btn-glas { background: rgba(255,255,255,.08);
              border-color: rgba(255,255,255,.28);
              -webkit-backdrop-filter: blur(26px) saturate(180%);
              backdrop-filter: blur(26px) saturate(180%); }
.p-btn-glas:hover { background: rgba(255,255,255,.16);
                    border-color: rgba(255,255,255,.44); }
/* Das Symbol ist das Einzige, was klar zu sehen sein soll. Der zarte
   Schatten haelt es ueber hellem Rasen wie ueber dunklen Baeumen
   lesbar - die schwebenden Knoepfe liegen ueber dem Luftbild. */
.p-btn-glas svg { filter: drop-shadow(0 1px 2px rgba(0,0,0,.55)); }
/* Ohne Unschaerfe bliebe nur die 10-Prozent-Fuellung - auf hellem
   Untergrund waere der Knopf dann unsichtbar. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .p-btn-glas { background: rgba(18,18,18,.62);
                border-color: rgba(255,255,255,.45); }
}

/* ==== Vier Knoepfe im Kopf ===========================================
   Facebook, Instagram, fussball.de, "Mitglied werden". Alle vier
   dieselbe Hoehe - und die steht als EINE Zahl am Behaelter, nicht
   viermal am Einzelteil, sonst laufen sie beim naechsten Eingriff
   auseinander.

   Warum hier eine feste Hoehe stehen darf: unter 481px macht die
   Projektregel aus der Hoehe des Knopfes eine Mindesthoehe, damit eine
   umbrechende Beschriftung nicht abgeschnitten wird. Diese vier
   brechen nicht um (white-space: nowrap) - statt der Schrift bricht
   die Reihe selbst um. Damit kann die feste Hoehe nichts abschneiden.  */
.p-kopfknoepfe { --p-kopf-knopf-h: var(--h-btn);
                 display: flex; flex-wrap: wrap; align-items: center;
                 justify-content: flex-end; gap: var(--s4);
                 min-width: 0; }
.p-kopfknoepfe > .btn { height: var(--p-kopf-knopf-h);
                        min-height: var(--p-kopf-knopf-h);
                        padding-block: 0; white-space: nowrap;
                        text-align: center; flex: none; }
/* Symbolknopf: so breit wie hoch. Die Beschriftung
   traegt er als aria-label, genau wie in der Servicezeile. */
.p-btn-symbol { width: var(--p-kopf-knopf-h, var(--h-btn));
                padding-inline: 0; }
.p-btn-symbol svg { width: 17px; height: 17px;
                    fill: currentColor; display: block; }

/* Beim Scrollen: sobald der Kopf knapp wird, weichen Facebook und
   Instagram im Kopf, und die schwebenden unten rechts uebernehmen.
   Dieselbe Regel wie '.p-masthead.p-knapp .p-kopfsocial' im Template,
   uebertragen auf die Knopfgruppe der Live-Seite. fussball.de und
   "Mitglied werden" bleiben stehen. */
.p-masthead.p-knapp .p-kopfknoepfe > .p-kopf-sozial { display: none; }

/* ==== Schmale Ansicht: eine Zeile im Kopf ============================
   Auf dem Telefon stapelte sich der Kopf auf drei Zeilen. Unter 481px
   wandern Facebook und Instagram nach unten rechts (schwebend), oben
   bleiben Wappen, Fussball und "Mitglied werden" - und der Menueknopf,
   siehe C2. Das Wappen BLEIBT: in der mobilen Ansicht soll immer ein
   Logo zu sehen sein.

   Abweichung von der Live-Seite: dort stand in diesem Block zusaetzlich
   '.p-masthead .p-menufeld { display: none; }', weil hinter den drei
   Strichen auf der Baustellenseite nichts steckte. Hier traegt der Knopf
   die Hauptnavigation - die Zeile ist deshalb NICHT uebernommen. */
@media (max-width: 480px) {
  .p-kopfknoepfe > .p-kopf-sozial { display: none; }
  .p-kopfknoepfe { flex: 1; justify-content: flex-end; }
  /* Schmaler, damit Wappen, Fussball und Knopf in eine Zeile
     passen. NUR der seitliche Innenabstand - die Schriftgroesse
     bleibt, das war ausdruecklich verlangt. Grundwert ist 18px. */
  .p-kopfknoepfe > .btn:not(.p-btn-symbol) { padding-inline: 11px; }
}

/* ==== Schwebende Knoepfe: Abstand zur Home-Anzeige ===================
   Lage und Aussehen bleiben die des Templates (.p-fab). Von der
   Live-Seite (.p-schweber) kommt nur der Abstand zur Systemleiste: auf
   dem iPhone liegt unter dem Fenster die Home-Anzeige, und
   env(safe-area-inset-*) rechnet sie ein. Das wirkt nur mit
   viewport-fit=cover im viewport-Zeichen - das setzt seite_kopf().
   Ohne Aussparung ist env() 0, und die Lage ist genau die des
   Templates. */
.p-fab { right: calc(clamp(12px, 2vw, 24px) + env(safe-area-inset-right, 0px));
         bottom: calc(clamp(12px, 2vw, 24px) + env(safe-area-inset-bottom, 0px)); }
/* Auf Seiten mit Formularfeldern weichen sie in jeder Breite - am
   Telefon lagen sie ueber den Eingabefeldern. Diese Seiten tragen am
   body die Klasse antrag-seite (seite_kopf, body_klasse):
   /mitgliedsantrag, /bankverbindung, /spielberechtigung und /sponsoren
   (Anfrageformular). Auf allen anderen Seiten stehen sie in allen
   Breiten (Auftraggeber 01.10.2026: "aber nur auf den Seiten mit
   Formularfeldern, richtig?"). Die Regel steht hier und nicht nur in
   antrag.css, weil /sponsoren antrag.css nicht laedt. */
.antrag-seite .p-fab { display: none !important; }

/* ==== Fuss: schmal linksbuendig untereinander ========================
   Die Korrektur der Live-Seite stand dort an .fusszeile, dem Fuss der
   Rechtstexte. Hier traegt die Fusszeile des Templates dieselbe Zeile:
   .p-legal mit Vermerk und Rechtlichem. Schmal stehen beide
   linksbuendig untereinander und die Verweise einer unter dem anderen.
   Dieselbe Stufe der Leiter wie auf der Live-Seite: 641. Die Abstaende
   sind die der Live-Seite, 12px und 6px - hier als --s5 und --s3. */
@media (max-width: 640px) {
  .p-legal { flex-direction: column; align-items: flex-start;
             justify-content: flex-start; gap: var(--s5); }
  .p-legal nav { flex-direction: column; align-items: flex-start;
                 gap: var(--s3); }
}

/* ─── C2 · MENUEKNOPF IM TELEFONKOPF ─────────────────────────────────────
   NEU GEBAUT, ABNAHME NOETIG.

   Bis 480px blendete die Live-Seite die drei Striche aus - und die
   Hauptnavigation steht schon ab 1500px abwaerts nicht mehr in der
   Zeile. Auf dem Telefon gaebe es damit keinen Weg zu den Seiten. Der
   Knopf bleibt deshalb stehen, mit denselben Bausteinen wie darueber:
   .p-menuknopf, .p-menu, die durchscheinende Flaeche mit Weichzeichner,
   die Menueschrift. Nichts davon ist neu gezeichnet.

   Neu ist nur die Lage der Liste. Unter dem Knopf aufgeklappt waere sie
   so schmal wie ihr laengster Eintrag und klebte am linken Rand. Auf dem
   Telefon steht sie als Liste ueber die volle Innenbreite, direkt unter
   dem Kopf, mit dem Seitenabstand der Seite links und rechts. Dafuer
   wird der Kasten um Knopf und Menue zum gewoehnlichen Element; das
   Menue haengt dann am Kopf selbst, der als sticky-Element ohnehin der
   Bezugspunkt ist. 100vw ist bewusst NICHT genommen - mit Rollbalken
   liefe die Liste sonst rechts aus dem Bild.

   Die Flaeche ist hier dichter: 88 statt 30 Prozent Seitenhintergrund.
   Die Liste deckt auf dem Telefon fast die ganze Buehne; ueber dem
   dunklen Luftbild war die graue Menueschrift bei 30 Prozent im hellen
   Thema kaum zu lesen (angesehen bei 320px). Weichzeichner, Rand,
   Rundung und Schatten bleiben die des Menues.

   Damit Knopf, Wappen, Fussball und "Mitglied werden" bei 320px in eine
   Zeile passen, ruecken die vier bis 480px enger zusammen: Spalt --s4
   statt --s7. Die Knopfgruppe selbst traegt schon --s4. Gemessen bei
   320px: Knopf 20-54, Wappen 62-93, Fussball und "Mitglied werden"
   109-300 - eine Zeile, 8px Luft, kein Ueberlauf.

   Das Skript (bbc08.js, hauptmenue) schaltet hidden und aria-expanded,
   schliesst mit Escape, beim Klick daneben und wenn der Fokus das Feld
   verlaesst. */
@media (max-width: 480px) {
  .p-masthead > .p-wrap { gap: var(--s4); }
  .p-masthead .p-menufeld { position: static; }
  .p-masthead .p-menu { top: calc(100% + var(--s2));
                        left: var(--p-gut); right: var(--p-gut);
                        width: auto; max-width: none;
                        background: color-mix(in srgb, var(--bg-body) 88%, transparent); }
}

/* ─── C4 · EIGENE KORREKTUREN AM FUSS (Abnahme noetig) ──────────────────
   Die Anschrift im Fuss ist ein <p>, und die Grundregel
   'p { color: var(--fg-2) }' gibt ihr im hellen Thema #555 - auf dem
   fast schwarzen Fussband kaum lesbar (angesehen bei 1366px). Im
   Template ist es genauso. Hier nimmt sie die Schrift des Bandes an,
   wie die Verweise daneben. Im dunklen Thema aendert sich fast nichts. */
.p-foot p { color: inherit; }

/* Kurze Seiten (die Fehlerseite, im breiten Fenster auch andere) enden
   sonst mitten im Fenster, und unter dem schwarzen Fuss steht ein
   heller Streifen Seitenhintergrund. Der Inhalt waechst deshalb, bis
   der Fuss unten ansteht. Der Kopf bleibt sticky - das geht in einer
   Flexspalte genauso. 100vh zuerst als Ruecklage fuer Browser ohne dvh. */
body { display: flex; flex-direction: column;
       min-height: 100vh; min-height: 100dvh; }
body > main { flex: 1 0 auto; }
/* Waechst nur <main>, bleibt unter der letzten Sektion ein grauer
   Streifen Seitenhintergrund (gemessen: /bekanntmachungen bei 1366 und
   1080px Fensterhoehe 126px). Deshalb ist <main> selbst eine Flexspalte,
   und die letzte Sektion nimmt den Rest - ihre Flaeche reicht bis an den
   Fuss. section:last-of-type und nicht :last-child: auf der Startseite
   steht hinter der letzten Sektion noch ein <script>. Die Sektionen
   tragen keine Aussenraender, die in der Flexspalte anders stuenden. */
body > main { display: flex; flex-direction: column; }
body > main > section:last-of-type { flex-grow: 1; }

/* ─── C3 · PLATZHALTER ───────────────────────────────────────────────────
   platzhalter('...') in app/seite.php schreibt fuer jede echte
   Datenluecke '<span class="platzhalter">... - Angabe folgt</span>'.
   Gut erkennbar, aber ruhig: gestrichelter Rahmen, zurueckgenommene
   Schrift, keine Warnfarbe. Er sagt "hier fehlt eine Angabe", nicht
   "hier ist ein Fehler". Keine Versalien und keine Anzeigeschrift, auch
   wenn er in einer Ueberschrift steht - er soll als Luecke lesbar sein,
   nicht als Teil des Titels.

   Er bleibt in seiner Spalte. Als Inline-Kasten mit box-decoration-break:
   clone ragte er beim Umbruch mit Rand und Innenabstand bis 8px ueber die
   Inhaltskante - der Browser bricht die Zeile, ohne den geklonten
   Abschluss mitzurechnen (gemessen auf /mitglied-werden, /kontakt).
   Jetzt ist er ein Kasten in der Zeile, hoechstens so breit wie sein
   Absatz; bricht er um, dann innerhalb seines Rahmens. baseline-source:
   first stellt ihn mit seiner ERSTEN Zeile auf die Grundlinie des Textes
   davor ("Abgabe: ..."), nicht mit der letzten. Aussehen wie bisher:
   gestrichelt, kursiv, --fg-3. */
.platzhalter { display: inline-block; max-width: 100%;
               baseline-source: first; padding: 0 .4em;
               font-family: var(--font-sans); font-stretch: normal;
               font-style: italic; font-weight: 400;
               text-transform: none; letter-spacing: normal;
               color: var(--fg-3); background: var(--surface-2);
               border: 1px dashed var(--border-strong);
               border-radius: var(--r-sm); }
/* Auf den dunklen Baendern - Servicezeile, Buehne, Kurzmeldungen, Fuss -
   waere die helle Flaeche ein Fleck. Dort dieselbe Handschrift wie der
   zurueckgenommene Knopf auf dem Band. */
.p-onband .platzhalter,
.p-utility .platzhalter,
.p-foot .platzhalter { color: var(--p-band-fg-2);
                       background: rgba(255,255,255,.06);
                       border-color: rgba(255,255,255,.28); }
/* Auf Gruen: weiss, wie alles auf der gruenen Flaeche. */
.p-sec--gruen .platzhalter,
.p-join .platzhalter { color: var(--accent-fg);
                       background: rgba(255,255,255,.12);
                       border-color: rgba(255,255,255,.5); }
/* Platzhalter an Stelle eines Knopfs: die Huelle ist so hoch wie der
   grosse Knopf, den sie ersetzt (--h-btn-lg - Handlungsknoepfe im Inhalt
   sind btn--lg), und setzt ihn mittig. Als Flexkind wuerde der
   Platzhalter sonst auf die Hoehe des Nachbarknopfs gestreckt, und der
   Text klebte oben. Eine Form fuer alle Seiten - sie ersetzt
   .start-fehlt (38px) und .verein-fehlt (32px).
     <span class="p-fehlt"><?= platzhalter('Aufnahmeantrag als PDF') ?></span> */
.p-fehlt { display: inline-flex; align-items: center;
           min-height: var(--h-btn-lg); max-width: 100%; }

/* Im Klappmenue der Servicezeile (bis 1000px) liegt der Platzhalter
   nicht mehr auf dem Band, sondern auf der durchscheinenden Flaeche -
   dort gelten wieder die Farben der Seite. Abstand wie die Verweise. */
@media (max-width: 1000px) {
  .p-utility .p-servicemenu .platzhalter { margin-block: var(--s5);
                                           justify-self: start;
                                           white-space: nowrap;
                                           color: var(--fg-3);
                                           background: var(--surface-2);
                                           border-color: var(--border-strong); }
}

/* Partner werden auf Gruen: .btn--ghost traegt var(--fg-2) - auf der
   gruenen Flaeche im hellen Thema etwa 1,2:1 und damit unlesbar (so
   schon im Template, Zeile 2516). Nur die Farbe, sonst nichts. */
.p-sec--gruen .btn--ghost { color: var(--accent-fg); border-color: rgba(255, 255, 255, .55); }
.p-sec--gruen .btn--ghost:hover { background: rgba(255, 255, 255, .14); color: var(--accent-fg); }

/* ─── C5 · GEMEINSAME BAUSTEINE (Grundkonstrukt, 29.09.2026) ─────────────
   Auftrag des Auftraggebers: "sorge erstmal dafuer, dass dieses
   Grundkonstrukt steht, damit es Design ueberall gleich ist". Hier steht
   jede Form, die mehrere Seiten brauchen, genau einmal. Die Seiten nehmen
   diese Klassen, statt eine eigene zu bauen. Umschaltgrenzen nur auf der
   Leiter (480/640/900/1000/1300/1500 bzw. 481/641/901/1001/1301/1501).

     C5.1  Trennpunkte der Infozeile, Kicker mit mehreren Zeilen
     C5.2  Buehne ohne harte Bildkante
     C5.3  Kurzmeldungsband im dunklen Thema abgesetzt
     C5.4  Nachrichtenraster: Kopfzeile auf einer Linie, gleiche Reihen
     C5.5  Klappmenue als allgemeiner Baustein (.p-klapp)
     C5.6  Ligatabelle in einer Nebenspalte (.p-tabelle--neben)
     C5.7  Knoepfe: Umbruch, Verweis im Sektionskopf (die Platzhalter-
           Huelle .p-fehlt steht bei den Platzhaltern in C3)
     C5.8  Kachelraster mit fester Spaltenzahl je Stufe (.p-kachelraster)
     C5.9  Quellenzeile (.p-quelle)
     C5.10 Angabenliste (.p-angaben)                                       */

/* ---- C5.1 · Trennpunkte ------------------------------------------------
   .p-meta ist eine Flexzeile. Das fuehrende Leerzeichen aus
   content: " · " faellt dort am Anfang jedes Eintrags weg - zu sehen war
   "HERREN· FREITAG" neben "NORD · HERREN", und nach einem Umbruch begann
   die Zeile mit "·". Jetzt haengt der Punkt am VORIGEN Eintrag, mit einem
   geschuetzten Leerzeichen davor und dahinter: derselbe Abstand links und
   rechts, derselbe wie bei den Punkten im Text (" · "), und keine Zeile
   beginnt mit "·".
   Leere Eintraege (startseite.css blendet sie aus) zaehlen nicht: der
   Punkt steht nur, wenn noch ein nicht leerer Eintrag folgt.
   .status ist ein inline-flex-Kasten mit Spalt - dort ist der Punkt ein
   eigenes Flexkind, und der Spalt davor wird zurueckgenommen.
   Im Text geschriebene Punkte ("Landesklasse Nord · Herren", Kicker mit
   mehreren Kategorien) setzt trennpunkte() in seite.php bzw.
   BBC08.trennpunkte() in bbc08.js - mit derselben Regel. */
.p-meta > span + span::before { content: none; }
.p-meta > span:not(:empty):has(~ span:not(:empty))::after {
  content: "\a0\b7\a0"; color: var(--p-band-fg-3); }
.p-meta > .status:has(~ span:not(:empty))::after { margin-left: calc(-1 * var(--s3)); }

/* Der Kicker mit mehreren Kategorien ("Jugend · F-Junioren ·
   Veranstaltungen") bricht um - mit der Zeilenhoehe 1 aus .label lagen
   die beiden Zeilen aufeinander. Zeilenhoehe 1,4 trennt sie. Der
   negative Rand nimmt das Mehr an Hoehe oben und unten wieder heraus:
   ein einzeiliger Kicker steht genau da, wo er vorher stand. */
.p-kicker { line-height: 1.4; margin-block: -.2em; }

/* ---- C5.2 · Buehne ohne harte Bildkante ---------------------------------
   Die Bildebene hat eine feste Hoehe (clamp(420px, 62vw, 940px)). Ist die
   Buehne hoeher, endete das Luftbild als waagerechte Kante ueber flachem
   Schwarz - auf / bei 320 bis ~700px auf Hoehe der Knoepfe, auf den
   Mannschaftsseiten bis ~1230px mitten durch Countdown und Knoepfe.
   Die Blende laeuft jetzt unten DECKEND in die Buehnenfarbe aus
   (--p-band, #050505 = rgb(5,5,5)): am unteren Bildrand ist vom Foto
   nichts mehr zu sehen, es gibt keinen Schnitt. Oben und in der Mitte
   bleiben .72 und .30 (Design-Erkenntnisse 7b, gemessene Kontraste);
   darunter wird es nur dunkler, der Kontrast der hellen Schrift nur
   besser. Die Bildhoehe waechst weiter stufenlos - keine neue Grenze. */
.p-stage__bild { background-image:
                   linear-gradient(180deg, rgba(5,5,5,.72) 0%,
                     rgba(5,5,5,.30) 45%, rgb(5,5,5) 100%),
                   var(--p-stage-bild, none); }

/* ---- Menuepunkt Live: roter Punkt, solange ein Stream laeuft ----------- */
.p-nav-live::before { content: ""; display: inline-block; width: 8px; height: 8px;
                      margin-right: 6px; border-radius: 50%; background: #e0301e;
                      vertical-align: .1em; animation: p-live-puls 1.6s ease-in-out infinite; }
@keyframes p-live-puls { 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) { .p-nav-live::before { animation: none; } }

/* ---- C5.2a · Luftbild mit Vereinsheim: Ausschnitt und Blende -------------
   Gewaehlt am 30.09.2026 aus fuenf Proben (V4). Das Bild ist eine
   Schraegansicht: oben Himmel und Funkmast, darunter Wald, unten der
   Platz, links das Vereinsheim mit Solardach. Der Ausschnitt zeigt
   Vereinsheim und Platz, der Himmel faellt oben weg: das Bild ist 135 %
   der Bildebene hoch und mindestens so breit wie die Buehne.
   2.406 = 1,35 x 2000/1122. Die Hoehe der Bildebene steht einmal in
   --p-stage-bild-h (oben an .p-stage__bild); aendert sich das
   Seitenverhaeltnis des Bildes, ist der Faktor neu zu rechnen, sonst
   verrutscht der Ausschnitt. Die erste Angabe gilt dem Verlauf, die
   zweite dem Foto. */
.p-stage__bild { background-size: 100% 100%,
                                  max(100%, calc(var(--p-stage-bild-h) * 2.406)) auto;
                 background-position: 0 0, 12% 85%; }
/* Blende am Buehnenende. Je nach Inhalt ist die Bildebene hoeher als die
   Buehne - auf der Startseite ab etwa 770px, auf den Mannschaftsseiten
   ab etwa 1220px (1366: 847 zu 737px); das Foto endete dort mit
   waagerechter Kante am Kurzmeldungsband. Die Blende sitzt am Ende der Buehne, wie
   hoch sie auch ist, und laeuft deckend in die Buehnenfarbe aus. Sie
   liegt ueber dem Bild und unter dem Inhalt (.p-wrap, z-index 2); mobil
   liegt sie ueber Schwarz und aendert nichts. */
.p-stage::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0;
                   height: min(22%, 160px); z-index: 1; pointer-events: none;
                   background: linear-gradient(180deg, rgba(5,5,5,0), rgb(5,5,5)); }
/* WebP (186 statt 230 KB), wo der Browser image-set mit type() kennt;
   sonst bleibt das JPEG von oben. */
/* Schrift vor hellen Bildstellen. Das Luftbild hat helle Flaechen, wo
   Schrift steht: das Pflaster vor dem Vereinsheim hinter HEIM (Startseite
   1300-1501, dort nur 1,7:1), die Hauswand hinter dem Mannschaftsnamen
   (Mannschaftsseiten 1366, 1920). Ein weicher dunkler Schatten hebt die
   Schrift dort ab; auf dunklem Grund ist er nicht zu sehen. Knoepfe
   tragen ihre eigene Flaeche und bleiben ohne. */
.p-stage .p-wrap { text-shadow: 0 1px 2px rgba(5,5,5,.6), 0 0 16px rgba(5,5,5,.65); }
.p-stage .btn { text-shadow: none; }
@supports (background-image: image-set(url("x.webp") type("image/webp"))) {
  .p-stage { --p-stage-bild: image-set(url("../img/buehne-sportplatz.webp") type("image/webp"),
                                       url("../img/buehne-sportplatz.jpg") type("image/jpeg")); }
}

/* ---- C5.3 · Kurzmeldungsband im dunklen Thema ---------------------------
   Dunkel haben das Band (--p-band-2, #121212) und die weisse erste
   Sektion darunter (--surface-1, dunkel #121212) dieselbe Farbe - die
   Schlagzeilen gingen nahtlos in "Nachrichten" ueber. Das Band bekommt
   unten dieselbe Linie, die es oben schon traegt. Nur dunkel; hell
   bleibt es unveraendert (Band #121212 gegen Weiss).
   01.10.2026: Die Linie allein (8 % Weiss) war kaum zu sehen. Das Band
   steht dunkel jetzt eine Stufe tiefer, auf --p-band (#050505) wie
   Buehne und Fuss, und hebt sich so von der Sektion darunter (#121212)
   ab. Zur Buehne darueber trennt die Linie oben. */
@media (prefers-color-scheme: dark) {
  :root:not([data-thema="hell"]) .p-strip { background: var(--p-band);
                                            border-bottom: 1px solid rgba(255,255,255,.08); }
}
:root[data-thema="dunkel"] .p-strip { background: var(--p-band);
                                      border-bottom: 1px solid rgba(255,255,255,.08); }

/* ---- C5.4 · Nachrichtenraster (/ und /news) -----------------------------
   (a) Kopfzeile: Topmeldung und Nachbarkachel sind gleich hoch, ihre
   Bildunterkanten und Titel stehen auf einer Linie. Vorher fuellte das
   Bild der Nachbarkachel, was ihr kuerzerer Text uebrig liess - 65px
   Versatz bei 641-900, 7-12px ab 901.
   Beide Kacheln teilen sich jetzt zwei Rasterzeilen (subgrid): Zeile 1
   das Bild, Zeile 2 der Text. Die Hoehe von Zeile 1 gibt das Bild der
   Topmeldung vor (2:1, bis 900px 16:9); das Bild der Nachbarkachel
   bringt keine eigene Hoehe mit (contain: size) und fuellt die Zeile.
   Ohne subgrid bleibt es, wie es war. */
@supports (grid-template-rows: subgrid) {
  .p-kopfzeile > .p-story { grid-row: span 2; grid-template-rows: subgrid; }
  .p-kopfzeile .p-story--neben .p-shot { min-height: 0; contain: size; }
}
/* (b) Zwei Spalten (641-900): der Textblock hatte eine feste Hoehe von
   116px, gedacht fuer das Mauerwerk ab 901. Darunter stand deshalb nach
   kurzem Text viel, nach langem wenig Luft (/news bei 780: 67/46/46/67).
   Bis 900 ist er so hoch wie sein Text, und zwischen allen Kachelreihen
   steht derselbe Abstand: der Rasterspalt --s6, auch unter der
   Kopfzeile. Dort stand das Datum als Inline-Element in einer Zeile mit
   der Zeilenhoehe des 17px-Fliesstexts und brachte 3-4px mehr Luft mit
   als im Mauerwerk, wo es ein eigener Kasten ist - jetzt auch in der
   Kopfzeile ein Kasten. */
@media (max-width: 900px) {
  .p-mauerwerk .p-kachel__text { height: auto; }
  .p-kopfzeile { margin-bottom: var(--s6); }
  .p-kopfzeile .p-date { display: block; }
}

/* ---- C5.5 · Klappmenue als allgemeiner Baustein -------------------------
   Das Klappmenue der Startseite (#spieltag, bis 640px), jetzt fuer jede
   Seite und in jeder Breite. Form, Pfeil, Flaeche, Rand, Schatten,
   Eintraege und Flaechenumkehr sind woertlich die der Startseite
   (Abschnitt B, "Spieltag", max-width: 640px). Die Startseite selbst
   bleibt, wie sie ist: ueber 640 Reiter, darunter das Klappmenue.

   Markup (die Klasse p-klapp am Behaelter schaltet es ein):

     <div class="p-klapp">
       <div class="p-tabs__gruppe" role="tablist" aria-label="Mannschaft waehlen">
         <div class="p-tabs__liste" role="presentation" id="x-liste">
           <button type="button" class="chip on" role="tab"
                   aria-selected="true">Herren</button>
           <button type="button" class="chip" role="tab"
                   aria-selected="false">Herren II</button>
         </div>
       </div>
       <button type="button" class="chip p-tabs__auswahl" data-klapp
               aria-haspopup="true" aria-expanded="false"
               aria-controls="x-liste"><span class="p-klapp__wort">Herren</span><span
               class="p-tabs__pfeil" aria-hidden="true">&#9662;</span></button>
     </div>

   Statt Reitern gehen auch Verweise: <a class="chip on" aria-current=...>.
   Die Liste haengt linksbuendig unter dem Behaelter - der Knopf ist sein
   erstes sichtbares Kind. Das Skript steht in bbc08.js ("Klappmenues")
   und bedient jedes [data-klapp].

   OHNE Skript (keine Klasse p-js an <html>) stehen die Eintraege als
   Reiterreihe da, der Knopf fehlt - so geht die Auswahl auch ohne
   Skript, und ein <select> ist dafuer nicht noetig. */
.p-klapp { display: flex; flex-wrap: wrap; gap: var(--s4); }
.p-klapp[hidden] { display: none; }
.p-klapp a.chip:hover { text-decoration: none; }
.p-js .p-klapp { position: relative; }
.p-js .p-klapp .chip.p-tabs__auswahl { display: inline-flex; gap: .35em; }
.p-js .p-klapp .p-tabs__pfeil { font-size: .6em; line-height: 1; }
.p-js .p-klapp .p-tabs__liste {
                 position: absolute; top: calc(100% + var(--s4));
                 left: 0; z-index: 60; display: none;
                 width: max-content;
                 max-width: calc(100vw - 2 * var(--p-gut));
                 padding: var(--s4) var(--s8);
                 background: var(--bg-body);
                 background: color-mix(in srgb, var(--bg-body) 30%, transparent);
                 -webkit-backdrop-filter: blur(26px) saturate(180%);
                 backdrop-filter: blur(26px) saturate(180%);
                 border: 1px solid color-mix(in srgb, var(--fg-1) 12%, transparent);
                 border-radius: var(--r-lg);
                 box-shadow: 0 24px 60px rgba(0,0,0,.28); }
.p-js .p-klapp .p-tabs__liste.p-offen { display: grid; }
/* Die Eintraege haben keine eigene Flaeche - darunter liegt schon die
   durchscheinende des Menues. Die Flaechenumkehr (Abschnitt B) wird
   dafuer mit ihrer eigenen Spezifitaet ueberstimmt. */
.p-js .p-klapp .p-tabs__liste .chip { border: 0; border-radius: 0;
                                      height: auto; padding: var(--s5) 0;
                                      justify-content: flex-start;
                                      border-bottom: 1px solid var(--border-subtle);
                                      background: none; }
.p-js .p-klapp .p-tabs__liste .chip:last-child { border-bottom: 0; }
.p-js .p-sec--alt .p-klapp .p-tabs__liste .chip,
.p-js .p-sec:not(.p-sec--alt):not(.p-sec--gruen):not(.p-join) .p-klapp .p-tabs__liste .chip {
  background: none; }
/* Ohne Skript bis 640px: die Regeln der Startseite in Abschnitt B gelten
   fuer JEDE .p-tabs__liste und machen daraus das (dann nicht bedienbare)
   Menue. Im Baustein bleibt es ohne Skript die Reiterreihe: Liste als
   display: contents, Reiter mit Rand, Rundung und Flaechenumkehr wie
   ueberall, der Knopf weg. */
@media (max-width: 640px) {
  html:not(.p-js) .p-klapp .chip.p-tabs__auswahl { display: none; }
  html:not(.p-js) .p-klapp .p-tabs__liste { display: contents; }
  html:not(.p-js) .p-klapp .p-tabs__liste .chip {
    height: var(--h-chip); padding: 0 var(--s5);
    border: 1px solid var(--border-default); border-radius: var(--r-lg); }
  html:not(.p-js) .p-klapp .p-tabs__liste .chip:hover { border-color: var(--border-strong); }
  html:not(.p-js) .p-klapp .p-tabs__liste .chip.on { border-color: var(--accent-border); }
  html:not(.p-js) .p-sec--alt .p-klapp .p-tabs__liste .chip:not(.on) {
    background: var(--bg-body); }
  html:not(.p-js) .p-sec:not(.p-sec--alt):not(.p-sec--gruen):not(.p-join) .p-klapp .p-tabs__liste .chip:not(.on) {
    background: var(--surface-1); }
  html:not(.p-js) .p-sec--alt .p-klapp .p-tabs__liste .chip.on,
  html:not(.p-js) .p-sec:not(.p-sec--alt):not(.p-sec--gruen):not(.p-join) .p-klapp .p-tabs__liste .chip.on {
    background: var(--accent-tint); }
}

/* ---- C5.6 · Ligatabelle in einer Nebenspalte ----------------------------
   Die Spaltenregeln der Ligatabelle schalten nach der Fensterbreite. In
   .p-two steht die Tabelle ab 1001px aber neben einer zweiten Spalte -
   mit allen neun Spalten war die Vereinsspalte dort 144px schmal, die
   Namen brachen zwei- bis dreizeilig um. In einer Nebenspalte gibt die
   Tabelle deshalb Spalten auf, wie 30_Design/mannschaft-herren.html:
   #, Verein, Sp, Tore, Pkt - G, U, V und Diff fallen weg.
   Unter 1001px steht .p-two einspaltig, dann gelten die normalen Regeln.
   Innerhalb von .p-two greift das von selbst; anderswo nimmt man die
   Klasse p-tabelle--neben am .p-tabelle-Kasten. */
@media (min-width: 1001px) {
  .p-two .p-tabelle .p-tab__guv,
  .p-two .p-tabelle .p-tab__diff,
  .p-tabelle--neben .p-tab__guv,
  .p-tabelle--neben .p-tab__diff { display: none; }
}

/* ---- C5.7 · Knoepfe -------------------------------------------------------
   Die Groessenordnung (Handlungsknoepfe im Inhalt btn--lg, Verweise im
   Sektionskopf btn--ghost btn--sm, Normalgroesse nur "Mitglied werden" im
   Kopf) ist eine Regel fuer das Markup der Seiten - hier stehen die drei
   Teile, die der Stil dafuer braucht.

   (b) Bis 480px darf eine Beschriftung umbrechen (Abschnitt A). Mit der
   Zeilenhoehe 1 beruehrten die Umlautpunkte die Zeile darueber
   ("IN OPENSTREETMAP OEFFNEN" bei 320px). 1,3 trennt die Zeilen; ein
   einzeiliger Knopf bleibt so hoch wie vorher (Mindesthoehe). */
@media (max-width: 480px) {
  .btn { line-height: 1.3; }
}
/* (d) Bricht der Verweis im Sektionskopf unter die Ueberschrift, fluchtet
   seine Schrift mit Kicker und Ueberschrift - vorher war er um seinen
   Innenabstand plus Rand eingerueckt (13px). Steht er rechts daneben,
   aendert der Rand nichts: justify-content: space-between haelt seine
   rechte Kante am Rand. */
.p-head > .btn--ghost.btn--sm,
.p-head > .p-head__links > .btn--ghost.btn--sm:first-child {
  margin-left: calc(-1 * (var(--s5) + 1px)); }

/* ---- C5.8 · Kachelraster mit fester Spaltenzahl je Stufe ---------------
   auto-fill wechselte die Spaltenzahl irgendwo zwischen den Stufen (die
   Sponsoren bei 450/460, 690/700, 920/930, 1160/1170). Der Baustein
   haelt die Zahl je Stufe fest; sie wechselt nur bei 481, 641, 901, 1001
   und 1301. Die Zahlen setzt die Seite als Eigenschaften, eine je Stufe;
   fehlt eine, gilt die der Stufe davor:

     --p-spalten-320   bis 480       --p-spalten-901    901-1000
     --p-spalten-481   481-640       --p-spalten-1001   1001-1300
     --p-spalten-641   641-900       --p-spalten-1301   ab 1301
     --p-kachel-min    Mindestbreite einer Kachel (Standard 0)

   min(--p-kachel-min, 100%) bleibt: auch eine Kachel mit Mindestbreite
   laeuft in einem schmalen Kasten nicht hinaus.
   Die Seite setzt dafuer KEIN eigenes grid-template-columns - ihre
   Datei steht hinter bbc08.css und wuerde den Baustein ueberstimmen.

     <ul class="verein-karten p-kachelraster"> ...
     .verein-karten { --p-spalten-641: 2; --p-spalten-901: 3; }

   Vorlaeufig gilt die Zahl, die das Raster am Anfang der Stufe zeigte.
   Die Spaltenzahl auf dem Telefon ist eine offene Frage an den
   Auftraggeber. */
.p-kachelraster, .p-sponsors {
  display: grid;
  --p-spalten: var(--p-spalten-320, 1);
  grid-template-columns: repeat(var(--p-spalten),
                                minmax(min(var(--p-kachel-min, 0px), 100%), 1fr)); }
@media (min-width: 481px) {
  .p-kachelraster, .p-sponsors {
    --p-spalten: var(--p-spalten-481, var(--p-spalten-320, 1)); }
}
@media (min-width: 641px) {
  .p-kachelraster, .p-sponsors {
    --p-spalten: var(--p-spalten-641, var(--p-spalten-481, var(--p-spalten-320, 1))); }
}
@media (min-width: 901px) {
  .p-kachelraster, .p-sponsors {
    --p-spalten: var(--p-spalten-901, var(--p-spalten-641,
                 var(--p-spalten-481, var(--p-spalten-320, 1)))); }
}
@media (min-width: 1001px) {
  .p-kachelraster, .p-sponsors {
    --p-spalten: var(--p-spalten-1001, var(--p-spalten-901, var(--p-spalten-641,
                 var(--p-spalten-481, var(--p-spalten-320, 1))))); }
}
@media (min-width: 1301px) {
  .p-kachelraster, .p-sponsors {
    --p-spalten: var(--p-spalten-1301, var(--p-spalten-1001, var(--p-spalten-901,
                 var(--p-spalten-641, var(--p-spalten-481, var(--p-spalten-320, 1)))))); }
}
/* Die Sponsorentafel (Startseite und /sponsoren): die Zahlen, die
   auto-fill mit 200px am Anfang jeder Stufe zeigte. */
.p-sponsors { --p-spalten-320: 1; --p-spalten-481: 2; --p-spalten-641: 2;
              --p-spalten-901: 3; --p-spalten-1001: 4; --p-spalten-1301: 5;
              --p-kachel-min: 200px; }

/* ---- C5.9 · Quellenzeile --------------------------------------------------
   Stand und Quelle unter Daten, EINE Form fuer alle Seiten, im Mass der
   leiseren Fassung (spielbetrieb.css .sb-quelle): klein, --fg-3, knapper
   Abstand. Ein gewoehnlicher Absatz, kein Strich, kein Kasten.
     <p class="p-quelle">Stand 29.09.2026 · Quelle: fussball.de</p> */
.p-quelle { margin-top: var(--s5); font-size: var(--t-xs); color: var(--fg-3); }
.p-head .p-quelle { margin-top: 0; }

/* ---- C5.10 · Angabenliste (Beschriftung | Wert) --------------------------
   EINE Form fuer Steckbrief, Platzangaben und Ansprechpartner. Mass der
   Mannschaftsseite (Beschriftungsspalte 9rem, Wert --fg-2 wie in den
   Tabellen); die Beschriftung steht auf der ersten Zeile des Werts
   (Grundlinie), auch wenn er umbricht; keine Linie unter dem letzten
   Eintrag, wie in table.t. Kein Wort wird mitten getrennt.
   Bis 480px und - mit p-angaben--neben - in einer schmalen Nebenspalte
   (901-1300, etwa rechts in .verein-spalten) steht die Beschriftung ueber
   dem Wert.
     <dl class="p-angaben">
       <div><dt>Gruendungsjahr</dt><dd>1908</dd></div>
     </dl> */
.p-angaben { margin: 0; display: grid; }
.p-angaben > div { display: grid; align-items: baseline;
                   grid-template-columns: minmax(0, 9rem) minmax(0, 1fr);
                   gap: var(--s5); padding-block: var(--s5);
                   border-bottom: 1px solid var(--border-subtle); }
.p-angaben > div:last-child { border-bottom: 0; }
.p-angaben dt { font-size: var(--t-label); font-weight: 600;
                letter-spacing: var(--tr-label); text-transform: uppercase;
                color: var(--fg-3); }
.p-angaben dd { margin: 0; color: var(--fg-2);
                overflow-wrap: normal; -webkit-hyphens: manual; hyphens: manual; }
@media (max-width: 480px) {
  .p-angaben > div { grid-template-columns: minmax(0, 1fr); gap: var(--s2); }
}
@media (min-width: 901px) and (max-width: 1300px) {
  .p-angaben--neben > div { grid-template-columns: minmax(0, 1fr); gap: var(--s2); }
}

/* ---- C5.11 · Kaesten im dunklen Thema ------------------------------------
   Dunkel trugen .panel und .card (--surface-1, #121212) dieselbe Farbe
   wie die weisse Sektion p-sec--alt (--surface-1, #121212); nur der Rand
   #1b1b1b trennte - die Ergebnistabelle der Startseite lag fast
   unsichtbar auf der Flaeche. Dort steht der Kasten jetzt eine Stufe
   heller (--surface-2, #191919), so wie er auf der grauen Sektion eine
   Stufe ueber dem Seitenhintergrund steht (#121212 auf #0a0a0a).
   Was im Kasten liegt, zieht eine Stufe mit, sonst verschwaende es auf
   der neuen Fuellung: Rand und Linien (--border-subtle wird
   --border-default, #2a2a2a), Fuellungen darin (--surface-2 wird
   --surface-3, #222222, etwa .sp-auswahl), das Ueberfahren einer
   Tabellenzeile und einer Kachel (--surface-3). Grau und Gruen bleiben
   wie sie sind, hell aendert sich nichts. */
@media (prefers-color-scheme: dark) {
  :root:not([data-thema="hell"]) .p-sec--alt :is(.panel, .card) {
    --border-subtle: var(--border-default);
    background: var(--surface-2); }
  :root:not([data-thema="hell"]) .p-sec--alt :is(.panel, .card) > * {
    --surface-2: var(--surface-3); --surface-hover: var(--surface-3); }
  :root:not([data-thema="hell"]) .p-sec--alt .card--link:hover {
    background: var(--surface-3); }
}
:root[data-thema="dunkel"] .p-sec--alt :is(.panel, .card) {
  --border-subtle: var(--border-default);
  background: var(--surface-2); }
:root[data-thema="dunkel"] .p-sec--alt :is(.panel, .card) > * {
  --surface-2: var(--surface-3); --surface-hover: var(--surface-3); }
:root[data-thema="dunkel"] .p-sec--alt .card--link:hover {
  background: var(--surface-3); }
/* Die Shop-Kacheln der Startseite (.p-shop__kachel, startseite.css)
   trugen dunkel --surface-1 wie die Sektion (#121212); nur der Rand
   #2c2c2c trennte. Sie stehen jetzt wie die Kaesten eine Stufe heller
   (--surface-2, #191919). Die Vitrine bleibt hell, hell aendert sich
   nichts. Die Spezifitaet (0,4,0) schlaegt startseite.css (0,2,0), das
   hinter bbc08.css laedt. Auftrag 160, 01.10.2026. */
@media (prefers-color-scheme: dark) {
  :root:not([data-thema="hell"]) .p-shop .p-shop__kachel { background: var(--surface-2); }
}
:root[data-thema="dunkel"] .p-shop .p-shop__kachel { background: var(--surface-2); }

/* ---- C5.12 · Kapitelueberschriften in den kleinen Breiten ---------------
   --p-t-hero haengt ohne Untergrenze an der Fensterbreite (4,9vw). Unter
   rund 360px war die Ueberschrift im Sektionskopf damit kleiner als die
   Kartentitel (320: 15,7 gegen 17,6px). Bis 480px ist sie deshalb
   mindestens so gross wie ein Kartentitel (--p-t-h3). Die Umschalttitel
   Ergebnisse/Tabelle/Spielplan tragen dieselbe Groesse wie die h2 und
   ziehen mit - aber nur der sichtbare Knopf (.p-titelwahl__auswahl). Die
   Eintraege im aufgeklappten Menue (.p-titelwahl__liste) behalten ihre
   Menueschrift (--t-xs, Regel im Block bis 640px); bis 480 standen sie
   vorher in Anzeigegroesse (Nachbesserung 01.10.2026). :where() haelt
   die Spezifitaet bei der von ".p-head .p-titel". Die Mannschaftsnamen
   der Buehne bleiben ohne Untergrenze (Laengenrechnung bei --p-t-hero in
   :root). */
@media (max-width: 480px) {
  .p-head h2.p-display,
  .p-head .p-titel:not(:where(.p-titelwahl__liste .p-titel)) {
    font-size: max(var(--p-t-hero), var(--p-t-h3)); }
}

/* ---- C5.13 · Textseiten: eine Lesespalte, mittig -------------------------
   Impressum, Datenschutz, Satzung (.p-recht, verein.css). Kopf und Text
   stehen in einer Spalte von --p-lesemass, mittig im Raster wie der
   Artikel (news.css) - in der breitesten Ansicht bleibt links und rechts
   gleich viel Raum. Vorher stand die Spalte links, bei 1366px blieben
   rechts 544px und links 107px frei. Unter rund 800px fuellt der Text
   die Spalte wie bisher. */
.p-wrap:has(> .p-recht) > .p-head,
.p-wrap:has(> .p-recht) > .p-recht { max-width: var(--p-lesemass); margin-inline: auto; }

/* ---- C5.14 · Merkmarke in der Spielliste ---------------------------------
   "verlegt auf ..." und "spielfrei" (.sb-merk, spielbetrieb.css) standen
   eckig. Marken tragen die Rundung der Kaestchen, sehr kleine --r-md
   (Kapitel 7, "Knoepfe tragen die Rundung der Kaestchen"; die Marke ist
   19px hoch, wie .badge). Der Streifen links bleibt. Die Spezifitaet
   (0,2,0) schlaegt spielbetrieb.css (0,1,0), das hinter bbc08.css laedt.
   Gilt ueberall, wo die Spielliste steht (Mannschaftsseiten, /spielplan,
   /aktuelles). Auftrag 160, 01.10.2026. */
.sb-liste .sb-merk { border-radius: var(--r-md); }
