/* ===========================================================================
   DAS DESIGNSYSTEM — Fundament und Bausteine
   ---------------------------------------------------------------------------
   Grundlage: Material Design 3, als SYSTEM übernommen, nicht als Haut.
   Regelwerk und Begründung: docs/designsystem.md
   Befunde, aus denen die Abweichungen kommen: docs/befunde-kontaktbogen-2026-09-09.md

   Die Farbrollen (--md-*) stehen NICHT hier, sondern kommen aus
   src/Core/Material.php in den Seitenkopf — sie hängen am Akzent der Instanz.
   Hier stehen nur die festen Skalen und die Bausteine.

   DIESE DATEI WIRD NACH app.css GELADEN. Sie gewinnt damit bei gleicher
   Spezifität. Sie greift nichts aus app.css an: alle Bausteine tragen das
   Präfix .ds-, damit der Altbestand unberührt weiterläuft, solange die
   Migration in Wellen läuft.

   DREI REGELN, DIE HIER NICHT GEBROCHEN WERDEN
   1. Keine Farbe, die keine Rolle ist. Kein #hex, kein rgba() unterhalb
      dieser Zeile — außer in --ds-schatten, wo Schwarz die Rolle IST.
   2. Kein Abstand außerhalb der Skala (4 8 12 16 24 32 48).
   3. Keine Schriftgröße außerhalb der 15 Rollen.
   =========================================================================== */

:root {
  /* --- Schrift: die 15 Rollen aus M3 (md.sys.typescale, v0_192) ---------- */
  --ds-display-l:  3.5625rem/4rem;      --ds-display-l-track: -0.0156rem;
  --ds-display-m:  2.8125rem/3.25rem;   --ds-display-m-track: 0;
  --ds-display-s:  2.25rem/2.75rem;     --ds-display-s-track: 0;
  --ds-headline-l: 2rem/2.5rem;         --ds-headline-l-track: 0;
  --ds-headline-m: 1.75rem/2.25rem;     --ds-headline-m-track: 0;
  --ds-headline-s: 1.5rem/2rem;         --ds-headline-s-track: 0;
  --ds-title-l:    1.375rem/1.75rem;    --ds-title-l-track: 0;
  --ds-title-m:    1rem/1.5rem;         --ds-title-m-track: 0.0094rem;
  --ds-title-s:    0.875rem/1.25rem;    --ds-title-s-track: 0.0063rem;
  --ds-body-l:     1rem/1.5rem;         --ds-body-l-track: 0.0313rem;
  --ds-body-m:     0.875rem/1.25rem;    --ds-body-m-track: 0.0156rem;
  --ds-body-s:     0.75rem/1rem;        --ds-body-s-track: 0.025rem;
  --ds-label-l:    0.875rem/1.25rem;    --ds-label-l-track: 0.0063rem;
  --ds-label-m:    0.75rem/1rem;        --ds-label-m-track: 0.0313rem;
  --ds-label-s:    0.6875rem/1rem;      --ds-label-s-track: 0.0313rem;

  /* --- Form: 6 Stufen, mehr gibt es nicht ------------------------------- */
  --ds-eck-xs: 4px;   /* Felder, Zellen, Marken            */
  --ds-eck-s:  8px;   /* kleine Flächen                    */
  --ds-eck-m:  12px;  /* Karten und Panels                 */
  --ds-eck-l:  16px;  /* große Flächen                     */
  --ds-eck-xl: 28px;  /* Dialoge                           */
  --ds-eck-voll: 9999px;

  /* --- Erhebung: Flächenfarbe trägt sie, Schatten erst ab Stufe 2 -------- */
  --ds-schatten-2: 0 1px 2px 0 rgb(0 0 0 / .18), 0 2px 6px 2px rgb(0 0 0 / .10);
  --ds-schatten-3: 0 4px 8px 3px rgb(0 0 0 / .10), 0 1px 3px 0 rgb(0 0 0 / .18);

  /* --- Abstand: 4er-Raster. Nur diese sieben Werte ----------------------- */
  --ds-1: 4px;  --ds-2: 8px;  --ds-3: 12px; --ds-4: 16px;
  --ds-6: 24px; --ds-8: 32px; --ds-12: 48px;

  /* --- Dichte: kompakt. Der häufigste Befund war "Platz nicht genutzt". -- */
  --ds-zeile: 34px;      /* Höhe einer Listen-/Tabellenzeile */
  --ds-feld: 34px;       /* Höhe eines Eingabefelds          */
  --ds-pad: 14px;        /* Innenabstand einer Karte         */
  --ds-luecke: 12px;     /* Abstand innerhalb einer Karte    */
  --ds-abstand: 16px;    /* Abstand zwischen Karten          */
  --ds-abschnitt: 24px;  /* Abstand zwischen Abschnitten     */

  /* --- Bewegung --------------------------------------------------------- */
  /* Bewegung (M3): Standardkurve für Zustandswechsel, betonte Kurve für
     Flächen, die erscheinen. Drei Dauern — mehr braucht keine Oberfläche. */
  --ds-kurve-standard: cubic-bezier(.2,0,0,1);
  --ds-kurve-betont: cubic-bezier(.05,.7,.1,1);
  --ds-schnell: 120ms var(--ds-kurve-standard);
  --ds-normal: 200ms var(--ds-kurve-standard);
  --ds-langsam: 300ms var(--ds-kurve-betont);
}

/* ===========================================================================
   SCHRIFT-ROLLEN als Klassen. Wer eine Größe braucht, nimmt eine Rolle.
   =========================================================================== */
.ds-display-s{font:400 var(--ds-display-s) var(--font-head);letter-spacing:var(--ds-display-s-track)}
.ds-headline-l{font:400 var(--ds-headline-l) var(--font-head);letter-spacing:var(--ds-headline-l-track)}
.ds-headline-s{font:400 var(--ds-headline-s) var(--font-head);letter-spacing:var(--ds-headline-s-track)}
.ds-title-l{font:400 var(--ds-title-l) var(--font-head);letter-spacing:var(--ds-title-l-track)}
.ds-title-m{font:500 var(--ds-title-m) var(--font-head);letter-spacing:var(--ds-title-m-track)}
.ds-title-s{font:500 var(--ds-title-s) var(--font-ui);letter-spacing:var(--ds-title-s-track)}
.ds-body-l{font:400 var(--ds-body-l) var(--font-ui);letter-spacing:var(--ds-body-l-track)}
.ds-body-m{font:400 var(--ds-body-m) var(--font-ui);letter-spacing:var(--ds-body-m-track)}
.ds-body-s{font:400 var(--ds-body-s) var(--font-ui);letter-spacing:var(--ds-body-s-track)}
.ds-label-l{font:500 var(--ds-label-l) var(--font-ui);letter-spacing:var(--ds-label-l-track)}
.ds-label-m{font:500 var(--ds-label-m) var(--font-ui);letter-spacing:var(--ds-label-m-track)}
.ds-label-s{font:500 var(--ds-label-s) var(--font-ui);letter-spacing:var(--ds-label-s-track);
  text-transform:uppercase}

/* Zahlen stehen in Spalten untereinander. Immer. */
.ds-zahl{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

/* ===========================================================================
   FLÄCHE — die Erhebung, ohne Schatten
   =========================================================================== */
.ds-flaeche{background:var(--md-surface);color:var(--md-on-surface)}
.ds-f0{background:var(--md-surface-container-lowest)}
.ds-f1{background:var(--md-surface-container-low)}
.ds-f2{background:var(--md-surface-container)}
.ds-f3{background:var(--md-surface-container-high)}
.ds-f4{background:var(--md-surface-container-highest)}

/* ===========================================================================
   KARTE — der eine Baustein für "abgegrenzter Inhalt"
   =========================================================================== */
.ds-karte{
  background:var(--md-surface-container-low);
  color:var(--md-on-surface);
  border:1px solid var(--md-outline-variant);
  border-radius:var(--ds-eck-m);
  overflow:hidden;
}
/* flex-wrap: Reicht die Breite nicht (Handy), rutscht der rechte Teil in
   eine zweite Zeile, statt den Titel auf vier Zeilen zu quetschen. */
.ds-karte-kopf{
  display:flex;align-items:center;flex-wrap:wrap;gap:var(--ds-1) var(--ds-2);
  min-height:var(--ds-zeile);
  padding:var(--ds-1) var(--ds-pad);
  background:var(--md-surface-container);
  border-bottom:1px solid var(--md-outline-variant);
}
.ds-karte-kopf > h2,.ds-karte-kopf > h3{
  margin:0;font:500 var(--ds-title-s) var(--font-head);
  letter-spacing:var(--ds-title-s-track);color:var(--md-on-surface);
}
.ds-karte-kopf .ds-rechts{margin-left:auto;display:flex;align-items:center;gap:var(--ds-2)}
.ds-karte-leib{padding:var(--ds-pad)}
.ds-karte-leib.ds-eng{padding:0}
/* Auch allein nutzbar — z. B. an einem alten .panel-b, in dem eine Tabelle
   randlos liegen soll. Bis heute stand dort dreimal style="padding:0". */
.ds-eng{padding:0}
/* Trennt Abschnitte innerhalb einer Karte, ohne eine zweite Karte zu bauen. */
.ds-karte-leib + .ds-karte-leib{border-top:1px solid var(--md-outline-variant)}

/* ===========================================================================
   RASTER — Inhalt füllt die Breite, statt in einer Spalte zu versickern
   =========================================================================== */
.ds-spalten{display:grid;gap:var(--ds-abstand);grid-template-columns:minmax(0,1fr) 340px;align-items:start}
.ds-stapel{display:flex;flex-direction:column;gap:var(--ds-abstand)}
/* Ein Knopf im Stapel bleibt so breit wie sein Wort — sonst zieht ihn die
   Spalte auf volle Breite und der Text steht zentriert im Nichts. */
.ds-stapel > .ds-knopf{align-self:flex-start}
.ds-reihe{display:flex;align-items:center;gap:var(--ds-2);flex-wrap:wrap}
.ds-raster{display:grid;gap:var(--ds-abstand);grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
@media (max-width:1080px){.ds-spalten{grid-template-columns:minmax(0,1fr)}}

/* ===========================================================================
   KENNZAHL — die Antwort auf "keine Stats, nichts besonderes"
   =========================================================================== */
.ds-kennzahlen{
  display:grid;gap:0;margin:0 -1px -1px 0;
  grid-template-columns:repeat(auto-fit,minmax(112px,1fr));
}
/* Trennlinien je Kachel statt eines Lücken-Rasters: Bei drei Kacheln in zwei
   Spalten blieb sonst ein grauer Block, wo die vierte gestanden hätte. Die
   Außenkanten liegen einen Pixel unter der Kartenkante (die Karte schneidet ab). */
.ds-kennzahl{border-right:1px solid var(--md-outline-variant);border-bottom:1px solid var(--md-outline-variant)}
.ds-kennzahl{
  background:var(--md-surface-container-low);
  padding:var(--ds-2) var(--ds-3);
  display:flex;flex-direction:column;gap:2px;min-width:0;
}
.ds-kennzahl dt,.ds-kennzahl .ds-kz-l{
  font:500 var(--ds-label-m) var(--font-ui);letter-spacing:var(--ds-label-m-track);
  text-transform:uppercase;color:var(--md-on-surface-variant);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.ds-kennzahl dd,.ds-kennzahl .ds-kz-w{
  margin:0;font:500 var(--ds-title-l) var(--font-head);
  color:var(--md-on-surface);font-variant-numeric:tabular-nums;
}
.ds-kennzahl dd small,.ds-kennzahl .ds-kz-w small{display:block;font:400 var(--ds-body-s) var(--font-ui);
  color:var(--md-on-surface-variant);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Im schmalen Seitenstreifen fuellt eine ungerade Zahl von Kacheln das
   auto-fit-Raster nicht auf und laesst ein Loch. Zwei feste Spalten. */
.ds-kennzahlen.ds-zwei{grid-template-columns:repeat(2,minmax(0,1fr))}
.ds-kennzahlen.ds-drei{grid-template-columns:repeat(3,minmax(0,1fr))}
.ds-kennzahlen.ds-vier{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:560px){.ds-kennzahlen.ds-vier{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Auf dem Handy: drei Kacheln untereinander, und Marke und Unterzeile brechen
   um statt „BEGINN 10.05.202…" abzuschneiden — gekürzt ist die Zahl falsch. */
@media (max-width:560px){
  .ds-kennzahlen.ds-drei{grid-template-columns:minmax(0,1fr)}
  .ds-kennzahl dt,.ds-kennzahl .ds-kz-l,
  .ds-kennzahl dd small,.ds-kennzahl .ds-kz-w small{white-space:normal;overflow:visible}
}
.ds-kennzahl.ds-gut dd,.ds-kennzahl.ds-gut .ds-kz-w{color:var(--md-erfolg)}
.ds-kennzahl.ds-schlecht dd,.ds-kennzahl.ds-schlecht .ds-kz-w{color:var(--md-error)}

/* ===========================================================================
   TABELLE — dicht, mit Zahlenspalten, mit Wertbalken in der Zelle
   =========================================================================== */
.ds-tabelle{width:100%;border-collapse:collapse;font:400 var(--ds-body-m) var(--font-ui)}
.ds-tabelle th{
  position:sticky;top:0;z-index:1;
  background:var(--md-surface-container);
  font:500 var(--ds-label-m) var(--font-ui);letter-spacing:var(--ds-label-m-track);
  text-transform:uppercase;color:var(--md-on-surface-variant);
  text-align:left;padding:0 var(--ds-2);height:28px;white-space:nowrap;
  border-bottom:1px solid var(--md-outline-variant);
}
.ds-tabelle td{
  padding:0 var(--ds-2);height:var(--ds-zeile);
  border-bottom:1px solid var(--md-outline-variant);
  color:var(--md-on-surface);vertical-align:middle;
}
.ds-tabelle tbody tr:last-child td{border-bottom:0}
.ds-tabelle tbody tr:hover td{background:var(--md-surface-container)}
.ds-tabelle .ds-num{text-align:right;font-variant-numeric:tabular-nums}
.ds-tabelle th.ds-num{text-align:right}
.ds-tabelle tfoot td{
  font:500 var(--ds-label-l) var(--font-ui);
  background:var(--md-surface-container);color:var(--md-on-surface);
  border-top:1px solid var(--md-outline);
}
/* Der Wert steckt im Hintergrund der Zelle: --v ist 0..1. So braucht eine
   Tabelle kein zweites Diagramm daneben, um Verhältnisse zu zeigen. */
.ds-zellbalken{position:relative;isolation:isolate}
.ds-zellbalken::before{
  content:"";position:absolute;inset:4px auto 4px 0;z-index:-1;
  width:calc(var(--v,0) * 100%);
  background:var(--md-surface-container-highest);border-radius:var(--ds-eck-xs);
}
/* Der Bestwert darf NICHT die Akzentfarbe tragen: der Akzent ist hier rot,
   und Rot steht in derselben Tabelle schon fuer „verloren". Der beste Wert
   wird darum ueber Gewicht und Textfarbe hervorgehoben, nicht ueber eine
   Signalflaeche. */
.ds-zellbalken.ds-spitze{font-weight:600;color:var(--md-on-surface)}
.ds-zellbalken.ds-spitze::before{background:var(--md-secondary-container)}
.ds-umbruch{overflow-x:auto}

/* ===========================================================================
   PILLE — ein Baustein statt 48 Klassennamen
   =========================================================================== */
.ds-pille{
  display:inline-flex;align-items:center;gap:var(--ds-1);
  height:22px;padding:0 var(--ds-2);border-radius:var(--ds-eck-voll);
  font:500 var(--ds-label-m) var(--font-ui);letter-spacing:var(--ds-label-m-track);
  background:var(--md-surface-container-high);color:var(--md-on-surface-variant);
  border:1px solid transparent;white-space:nowrap;
}
.ds-pille.ds-gut{background:var(--md-erfolg-container);color:var(--md-on-erfolg-container)}
.ds-pille.ds-schlecht{background:var(--md-error-container);color:var(--md-on-error-container)}
/* Akzent-Pille = Hinweis, nicht Alarm: sie steht auf der Tertiärrolle (blau).
   Die Primärrolle folgt der Vereinsfarbe — bei Rot sahen „extern", „geplant"
   oder der aktive Filter aus wie eine Niederlage (12.09.2026). */
.ds-pille.ds-akzent{background:var(--md-tertiary-container);color:var(--md-on-tertiary-container)}
/* Ein Bild in der Pille (Spiel, Rolle, Team) — rund, so hoch wie die Schrift. */
.ds-pille img{width:16px;height:16px;border-radius:var(--ds-eck-voll);object-fit:cover;margin-left:-3px}
.ds-pille.ds-offen{background:transparent;border-color:var(--md-outline);color:var(--md-on-surface-variant)}

/* ===========================================================================
   KNOPF — vier Sorten, wie in M3. Mehr gibt es nicht.
   =========================================================================== */
.ds-knopf{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--ds-2);
  height:var(--ds-feld);padding:0 var(--ds-4);
  border-radius:var(--ds-eck-voll);border:1px solid transparent;
  font:500 var(--ds-label-l) var(--font-ui);letter-spacing:var(--ds-label-l-track);
  cursor:pointer;text-decoration:none;white-space:nowrap;
  transition:background var(--ds-schnell),border-color var(--ds-schnell);
}
.ds-knopf-gefuellt{background:var(--md-primary);color:var(--md-on-primary)}
.ds-knopf-getont{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}
.ds-knopf-umrandet{background:transparent;color:var(--md-primary);border-color:var(--md-outline)}
.ds-knopf-text{background:transparent;color:var(--md-primary);padding:0 var(--ds-2)}
.ds-knopf-gefuellt:hover{background:var(--md-primary);filter:brightness(1.08)}
.ds-knopf-getont:hover,.ds-knopf-umrandet:hover,.ds-knopf-text:hover{background:var(--md-surface-container-high)}
.ds-knopf.ds-klein{height:26px;padding:0 var(--ds-3);font:500 var(--ds-label-m) var(--font-ui)}
/* Gesperrt nach M3: Fläche und Schrift aus der Textfarbe gemischt, nicht
   durchsichtig — mit opacity wurde ein roter Knopf auf dunklem Grund braun
   und die Schrift unlesbar. */
.ds-knopf[disabled],.ds-knopf[aria-disabled="true"]{
  background:color-mix(in oklab,var(--md-on-surface) 12%,transparent);
  color:color-mix(in oklab,var(--md-on-surface) 50%,transparent);
  border-color:transparent;filter:none;pointer-events:none;cursor:default;
}
.ds-knopf-text[disabled],.ds-knopf-text[aria-disabled="true"]{background:transparent}
.ds-knopf-umrandet[disabled],.ds-knopf-umrandet[aria-disabled="true"]{
  background:transparent;border-color:color-mix(in oklab,var(--md-on-surface) 12%,transparent)}

/* Sichtbarer Fokus, immer. Auch auf den eigenen Bausteinen. */
.ds-knopf:focus-visible,.ds-reiter a:focus-visible,.ds-reiter > button:focus-visible,.ds-zeile:focus-visible,
.ds-feld:focus-visible,.ds-tabelle a:focus-visible{
  outline:2px solid var(--md-primary);outline-offset:2px;
}

/* ===========================================================================
   FELD
   =========================================================================== */
/* Feldgrund = die hellste (hell) bzw. tiefste (dunkel) Fläche, Rand = Outline:
   Auf dem grauen Grund (surface-container-highest) sahen Eingabefelder im
   hellen Schema aus wie gesperrt (12.09.2026). */
.ds-feld{
  height:var(--ds-feld);padding:0 var(--ds-3);
  background:var(--md-surface-container-lowest);color:var(--md-on-surface);
  border:1px solid var(--md-outline);border-radius:var(--ds-eck-xs);
  font:400 var(--ds-body-m) var(--font-ui);width:100%;
}
/* Die Elementregeln aus app.css (input[type=text] …, input:hover, input:focus)
   tragen Spezifität 0,1,1 und schlugen .ds-feld (0,1,0): Text-, Datums-,
   Zahl- und Mailfelder bekamen die alte Mulde (Grund --panel-2, Rand
   rgba(…,.1) = 1,9:1 statt 3:1), Auswahllisten daneben schon die neue Form.
   Die Elementform hier zieht gleich und gewinnt über die Ladereihenfolge. */
input.ds-feld,select.ds-feld,textarea.ds-feld{
  padding:0 var(--ds-3);background:var(--md-surface-container-lowest);color:var(--md-on-surface);
  border:1px solid var(--md-outline);border-radius:var(--ds-eck-xs);
  font:400 var(--ds-body-m) var(--font-ui);box-shadow:none;
}
.ds-feld:hover{background:color-mix(in oklab,var(--md-on-surface) 4%,var(--md-surface-container-lowest))}
.ds-feld:focus{outline:2px solid var(--md-primary);outline-offset:-1px;border-color:var(--md-primary);
  background:var(--md-surface-container-lowest);box-shadow:none}
.ds-feldmarke{
  display:block;font:500 var(--ds-label-m) var(--font-ui);
  letter-spacing:var(--ds-label-m-track);text-transform:uppercase;
  color:var(--md-on-surface-variant);margin-bottom:var(--ds-1);
}

/* ===========================================================================
   REITER
   =========================================================================== */
.ds-reiter{
  display:flex;gap:0;border-bottom:1px solid var(--md-outline-variant);
  overflow-x:auto;scrollbar-width:thin;
}
.ds-reiter a{
  display:inline-flex;align-items:center;gap:var(--ds-2);
  height:40px;padding:0 var(--ds-4);
  font:500 var(--ds-title-s) var(--font-ui);letter-spacing:var(--ds-title-s-track);
  color:var(--md-on-surface-variant);text-decoration:none;white-space:nowrap;
  border-bottom:2px solid transparent;
}
.ds-reiter a:hover{color:var(--md-on-surface);background:var(--md-surface-container)}
.ds-reiter a[aria-current="page"]{color:var(--md-primary);border-bottom-color:var(--md-primary)}
.ds-reiter .ds-pille{margin-left:var(--ds-1)}
/* Zweite Reiterzeile — die Seiten eines Unterbereichs: leiser, ohne eigene Grundlinie. */
.ds-reiter.ds-reiter-leise{border-bottom:0;gap:var(--ds-1)}
.ds-reiter.ds-reiter-leise a{height:32px;padding:0 var(--ds-3);font:500 var(--ds-label-l) var(--font-ui);letter-spacing:var(--ds-label-l-track);border-bottom:0;border-radius:var(--ds-eck-voll)}
.ds-reiter.ds-reiter-leise a[aria-current="page"]{background:var(--md-secondary-container);color:var(--md-on-secondary-container)}
/* Umbrechende Reiterzeile, wenn jeder Eintrag sichtbar bleiben muss (Schritte des Assistenten). */
.ds-reiter.ds-reiter-umbruch{flex-wrap:wrap;overflow:visible;row-gap:var(--ds-1)}

/* ===========================================================================
   BALKEN — Verhältnisse ohne Diagramm
   =========================================================================== */
.ds-balken{
  display:flex;height:6px;border-radius:var(--ds-eck-voll);overflow:hidden;
  background:var(--md-surface-container-highest);
}
.ds-balken i{display:block;height:100%}
/* Der Anteil kommt als Custom Property (Prozentzahl ohne Einheit): style="--anteil:62.5". */
.ds-balken i[style*="--anteil"]{width:calc(var(--anteil) * 1%)}
.ds-balken i.ds-gut{background:var(--md-erfolg)}
.ds-balken i.ds-schlecht{background:var(--md-error)}
.ds-balken i.ds-neutral{background:var(--md-outline)}

/* ===========================================================================
   ZEILE — Liste ohne Tabelle
   =========================================================================== */
.ds-liste{display:flex;flex-direction:column}
.ds-zeile{
  display:flex;align-items:center;gap:var(--ds-3);
  min-height:var(--ds-zeile);padding:var(--ds-1) 0;
  border-bottom:1px solid var(--md-outline-variant);
  color:var(--md-on-surface);text-decoration:none;
}
.ds-liste > .ds-zeile:last-child{border-bottom:0}
a.ds-zeile:hover{background:var(--md-surface-container)}
.ds-zeile .ds-fuellt{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis}
.ds-zeile .ds-neben{margin-left:auto;color:var(--md-on-surface-variant);
  font:400 var(--ds-body-s) var(--font-ui)}

/* Rundes Zeichen für Personen und Gegner. */
.ds-zeichen{
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:26px;height:26px;border-radius:var(--ds-eck-voll);
  background:var(--md-secondary-container);color:var(--md-on-secondary-container);
  font:500 var(--ds-label-m) var(--font-ui);text-transform:uppercase;overflow:hidden;
}
.ds-zeichen img{width:100%;height:100%;object-fit:cover}
/* Eine Farbe aus den Daten (Katalogeintrag, Rang, Stufe) kommt als --farbe,
   nicht als style="background:…". */
.ds-zeichen[style*="--farbe"],.ds-abzeichenbild[style*="--farbe"],.ds-punkt[style*="--farbe"]{background:var(--farbe)}
.ds-zeichen.ds-gross{width:44px;height:44px;font:500 var(--ds-title-m) var(--font-head)}
.ds-zeichen.ds-riesig{width:96px;height:96px;font:400 var(--ds-headline-s) var(--font-head)}
/* Kopfbild einer Karte (Profil, Team): liegt oben, die Kanten übernimmt die Karte. */
.ds-karte > .ds-banner{display:block;width:100%;height:150px;object-fit:cover;border-bottom:1px solid var(--md-outline-variant)}

/* ===========================================================================
   NÄCHSTER SCHRITT — der rote Faden, als Baustein
   Er steht am Fuß eines Objekt-Bildschirms und sagt, was jetzt dran ist.
   =========================================================================== */
/* Auf der Tertiärrolle (blau), der Knopf trägt die Vereinsfarbe: Auf dem
   Primär-Container sah der nächste Schritt im Dunkeln bei rotem Akzent aus
   wie eine Fehlermeldung, und die Unterzeile (opacity .85) verlor Kontrast. */
.ds-weiter{
  display:flex;align-items:center;flex-wrap:wrap;gap:var(--ds-3);
  padding:var(--ds-3) var(--ds-pad);
  background:var(--md-tertiary-container);color:var(--md-on-tertiary-container);
  border-radius:var(--ds-eck-m);
}
.ds-weiter .ds-fuellt{flex:1 1 16rem;min-width:0}
.ds-weiter b{font:500 var(--ds-title-s) var(--font-head);display:block}
.ds-weiter span{font:400 var(--ds-body-s) var(--font-ui)}
.ds-weiter .ds-knopf-gefuellt{background:var(--md-primary);color:var(--md-on-primary)}

/* ===========================================================================
   LEER — ein Zustand, nicht sechs
   =========================================================================== */
.ds-leer{
  display:flex;flex-direction:column;align-items:flex-start;gap:var(--ds-2);
  padding:var(--ds-6) var(--ds-pad);color:var(--md-on-surface-variant);
  font:400 var(--ds-body-m) var(--font-ui);
}
.ds-leer b{font:500 var(--ds-title-s) var(--font-head);color:var(--md-on-surface)}

/* ===========================================================================
   ERGEBNISZEILE — der Kopf eines Matches.
   Eine Zeile, keine 200px hohe Bühne: das Ergebnis ist EINE Angabe, sie darf
   nicht den halben Bildschirm kosten. („langweilig, platz nicht gut genutzt")
   =========================================================================== */
.ds-erg{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:var(--ds-4)}
.ds-erg-seite{display:flex;align-items:center;gap:var(--ds-3);min-width:0}
.ds-erg-seite.ds-rechts{justify-content:flex-end;text-align:right}
.ds-erg-seite .ds-fuellt{min-width:0;display:flex;flex-direction:column}
.ds-erg-seite b{margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ds-erg-seite .ds-label-s{color:var(--md-on-surface-variant)}
.ds-erg-stand{display:flex;align-items:baseline;gap:var(--ds-2)}
.ds-erg-stand > span{color:var(--md-on-surface-variant)}
.ds-erg-stand .ds-vorn{color:var(--md-on-surface)}
.ds-erg-doppel{font:400 var(--ds-headline-s) var(--font-head);color:var(--md-outline)}
@media (max-width:720px){
  .ds-erg{grid-template-columns:1fr auto;row-gap:var(--ds-3)}
  .ds-erg-stand{grid-row:1;grid-column:2}
  .ds-erg-seite.ds-rechts{grid-column:1/-1;justify-content:flex-start;text-align:left;flex-direction:row-reverse}
  .ds-erg-seite.ds-rechts .ds-fuellt{align-items:flex-start}
}

/* ===========================================================================
   FORM — die letzten Ergebnisse als Kette. Antwort auf „mehr Statistiken".
   =========================================================================== */
.ds-form{display:flex;gap:var(--ds-1)}
.ds-form-punkt{
  display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:var(--ds-eck-xs);
  font:500 var(--ds-label-m) var(--font-ui);
  background:var(--md-surface-container-highest);color:var(--md-on-surface-variant);
}
.ds-form-punkt.ds-gut{background:var(--md-erfolg-container);color:var(--md-on-erfolg-container)}
.ds-form-punkt.ds-schlecht{background:var(--md-error-container);color:var(--md-on-error-container)}

/* BEWEGUNG AUS: Wer sie abgeschaltet hat, bekommt jeden Zustand sofort —
   keine Übergänge, kein Schimmern, kein Drehen. */
@media (prefers-reduced-motion:reduce){
  .ds-knopf,.ds-reiter a,.ds-zeile,.ds-pille,.ds-mitglied,.ds-ablage,.ds-feld,
  details.ds-auf > summary::after,.ds-fortschritt,.ds-laden,.ds-laden::after,
  .ds-knopf[aria-busy="true"]::after{transition:none;animation:none}
}

/* ===========================================================================
   SEITENLEISTE EINKLAPPEN
   ---------------------------------------------------------------------------
   Wunsch vom 09.09.2026: „Menü sollte klappbar sein, damit Nutzer mehr Platz
   auf dem Canvas haben." Eingeklappt bleiben die Symbole; die Beschriftung
   fährt beim Überfahren als Fähnchen aus, ein Bereich klappt als Tafel auf.

   Diese Regeln fassen Klassen aus app.css an (.rail, .nav, .brand …). Das ist
   der einzige Ort, an dem system.css das tut, und es ist Absicht: die Leiste
   ist Rahmen, kein Baustein — sie bekommt hier eine ZUSTANDSSCHICHT, keine
   zweite Fassung. Unterhalb von 820px ist die Leiste eine Schublade; dort
   gilt nichts davon.
   =========================================================================== */

.ds-rail-leiste{display:flex;justify-content:flex-end;padding:0 12px 4px}
.ds-rail-schalter{
  width:28px;height:28px;display:grid;place-items:center;
  border:0;background:transparent;border-radius:var(--ds-eck-s);
  color:var(--md-on-surface-variant);cursor:pointer;
  transition:background var(--ds-schnell),color var(--ds-schnell);
}
.ds-rail-schalter:hover{background:var(--md-surface-container-high);color:var(--md-on-surface)}
.ds-rail-schalter:focus-visible{outline:2px solid var(--md-primary);outline-offset:2px}
.ds-rail-schalter svg{width:16px;height:16px;transition:transform var(--ds-normal)}
.ds-schmal-titel{display:none}

@media (max-width:820px){ .ds-rail-leiste{display:none} }

@media (min-width:821px){
  :root[data-rail="schmal"] .app{grid-template-columns:64px 1fr}

  /* Der Pfeil zeigt in die Richtung, in die es geht. */
  :root[data-rail="schmal"] .ds-rail-schalter svg{transform:rotate(180deg)}
  :root[data-rail="schmal"] .ds-rail-leiste{justify-content:center;padding:0 0 4px}

  /* Marke: nur noch die Plakette, mittig. */
  :root[data-rail="schmal"] .brand{justify-content:center;padding:14px 0 10px}
  :root[data-rail="schmal"] .brand-txt,
  :root[data-rail="schmal"] .brand-credit,
  :root[data-rail="schmal"] .rail-foot .legal-links,
  :root[data-rail="schmal"] .rail-foot form,
  :root[data-rail="schmal"] .rail-knoepfe,
  :root[data-rail="schmal"] .me-txt,
  :root[data-rail="schmal"] .nav-sep,
  :root[data-rail="schmal"] .nav-sub,
  :root[data-rail="schmal"] .nav-area-toggle,
  :root[data-rail="schmal"] .nav-pin{display:none}
  :root[data-rail="schmal"] .brand--full{padding:12px 8px 8px}
  :root[data-rail="schmal"] .brand-logo-full{max-height:44px}

  /* Zeilen werden zu Tasten: Symbol mittig, Beschriftung als Fähnchen. */
  :root[data-rail="schmal"] .nav{padding:8px 10px;overflow:visible}
  :root[data-rail="schmal"] .nav a,
  :root[data-rail="schmal"] .rail-meta,
  :root[data-rail="schmal"] .me{justify-content:center;padding:9px 0;gap:0}
  :root[data-rail="schmal"] .rail-foot{padding:8px 10px}
  :root[data-rail="schmal"] .nav-area{position:relative}
  :root[data-rail="schmal"] .nav-area-head{gap:0}

  /* Das Fähnchen. Es ist der ohnehin vorhandene <span> der Zeile — kein
     zweiter Text, der auseinanderlaufen könnte. */
  :root[data-rail="schmal"] .nav a > span,
  :root[data-rail="schmal"] .nav-area-link > span,
  :root[data-rail="schmal"] .rail-meta > span{
    position:absolute;left:calc(100% + 10px);top:50%;transform:translateY(-50%);
    z-index:70;pointer-events:none;opacity:0;
    background:var(--md-inverse-surface);color:var(--md-inverse-on-surface);
    font:500 var(--ds-label-l) var(--font-ui);
    padding:5px 10px;border-radius:var(--ds-eck-xs);white-space:nowrap;
    box-shadow:var(--ds-schatten-2);transition:opacity var(--ds-schnell);
  }
  :root[data-rail="schmal"] .rail-meta,
  :root[data-rail="schmal"] .me{position:relative}
  :root[data-rail="schmal"] .nav a:hover > span,
  :root[data-rail="schmal"] .nav a:focus-visible > span,
  :root[data-rail="schmal"] .nav-area-link:hover > span,
  :root[data-rail="schmal"] .nav-area-link:focus-visible > span,
  :root[data-rail="schmal"] .rail-meta:hover > span,
  :root[data-rail="schmal"] .rail-meta:focus-visible > span{opacity:1}

  /* Ein Bereich klappt als Tafel neben der Leiste auf, damit die
     Unterpunkte erreichbar bleiben, ohne die Leiste aufzuziehen.
     Der Bereichsname steht in der Tafel — am Symbol wäre er nicht lesbar. */
  :root[data-rail="schmal"] .nav-area-body{display:none}
  :root[data-rail="schmal"] .nav-area:hover > .nav-area-body,
  :root[data-rail="schmal"] .nav-area:focus-within > .nav-area-body{
    display:flex;position:absolute;left:calc(100% + 8px);top:-6px;z-index:70;
    min-width:210px;margin:0;padding:6px;
    background:var(--md-surface-container-low);color:var(--md-on-surface);
    border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-m);
    box-shadow:var(--ds-schatten-3);
  }
  /* Beim Aufklappen als Tafel darf das Fähnchen des Bereichs nicht zusätzlich
     erscheinen — sonst stehen Name und Tafel übereinander. */
  :root[data-rail="schmal"] .nav-area:hover .nav-area-link > span,
  :root[data-rail="schmal"] .nav-area:focus-within .nav-area-link > span{opacity:0}
  :root[data-rail="schmal"] .nav-area-body a{justify-content:flex-start;padding:6px 9px;gap:9px}
  :root[data-rail="schmal"] .nav-area-body a > span{
    position:static;transform:none;opacity:1;background:transparent;color:inherit;
    padding:0;box-shadow:none;font:inherit;
  }
  :root[data-rail="schmal"] .ds-schmal-titel{
    display:block;font:500 var(--ds-label-m) var(--font-ui);
    letter-spacing:var(--ds-label-m-track);text-transform:uppercase;
    color:var(--md-on-surface-variant);padding:2px 9px 6px;
  }
}

@media (prefers-reduced-motion:reduce){
  .ds-rail-schalter svg,
  :root[data-rail="schmal"] .nav a > span{transition:none}
}

/* ===========================================================================
   PERSON — ein Name verhält sich überall gleich
   ---------------------------------------------------------------------------
   Baustein: src/Core/Person.php. Bild, Miniprofil, Profil-Link kommen aus
   EINER Stelle. Gemessen am 09.09.2026 gab es sieben Stellen mit Miniprofil
   und achtzehn mit Profil-Link — alle von Hand zusammengesetzt.

   Ohne Profil (Gegnerspieler aus einer Aufzeichnung) bleibt der Name Text:
   .ds-ohne bekommt keinen Zeiger und keine Hover-Fläche, damit niemand
   klickt, wo nichts ist.
   =========================================================================== */
.ds-person{
  display:inline-flex;align-items:center;gap:var(--ds-2);min-width:0;
  color:var(--md-on-surface);text-decoration:none;border-radius:var(--ds-eck-xs);
}
a.ds-person:hover .ds-person-n{text-decoration:underline}
.ds-person:focus-visible{outline:2px solid var(--md-primary);outline-offset:2px}
.ds-person-n{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;
}
.ds-person.ds-gross .ds-person-n{font:500 var(--ds-title-s) var(--font-head)}
.ds-person-du{
  flex:0 0 auto;font:500 var(--ds-label-s) var(--font-ui);
  letter-spacing:var(--ds-label-s-track);text-transform:uppercase;
  color:var(--md-on-surface-variant);
  border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-voll);
  padding:0 6px;
}
.ds-person-z{
  flex:0 0 auto;font:400 var(--ds-body-s) var(--font-ui);
  color:var(--md-on-surface-variant);
}
.ds-person.ds-ohne{color:var(--md-on-surface-variant);cursor:default}
.ds-person.ds-ohne .ds-zeichen{background:var(--md-surface-container-high);color:var(--md-on-surface-variant)}

/* ── Dialog — eine schwebende Karte: Kopf mit Titel und Schließen, Leib
   mit dem Formular, Fuß mit Abbrechen und der einen Handlung. Öffnen und
   Schließen macht app.js ([data-dialog-open], [data-dialog-close], Backdrop);
   ein serverseitig offener Dialog ([open]) ist ohne JavaScript ein
   gewöhnlicher Kasten im Fluss. Breite Fassung für Formulare mit mehreren
   Gruppen (Match anlegen, Termin): Kopf bleibt stehen, der Leib rollt —
   Flex-Spalte NUR im offenen Zustand, display:flex am zugeklappten <dialog>
   zeigte ihn an. */
.ds-dialog{border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-l);padding:0;
  background:var(--md-surface-container-low);color:var(--md-on-surface);
  width:min(560px,94vw);max-width:94vw;max-height:88vh;box-shadow:var(--ds-schatten-3)}
.ds-dialog::backdrop{background:color-mix(in srgb,var(--md-on-surface) 55%,transparent)}
.ds-dialog-kopf{display:flex;align-items:center;justify-content:space-between;gap:var(--ds-2);
  padding:var(--ds-3) var(--ds-pad);border-bottom:1px solid var(--md-outline-variant)}
.ds-dialog-kopf h2{margin:0;font:500 var(--ds-title-m) var(--font-head);color:var(--md-on-surface)}
.ds-dialog-breit[open]{display:flex;flex-direction:column;width:min(920px,94vw)}
/* Rückfrage mit einem Satz und zwei Knöpfen — 560 px machten daraus eine
   einzige lange Zeile. */
.ds-dialog.ds-dialog-schmal{width:min(420px,94vw)}

/* ── Gruppe — ein Feldsatz mit Überschrift (fieldset/legend): Wer · Gegen wen ·
   Worum · Wo. Die Abstufung zwischen „muss“ und „kann“ steht als Pille in der
   Legende, nicht als Rätsel. Schmal, wo ein Feld über die volle Breite eine
   Bedeutung behauptete, die es nicht hat. */
.ds-gruppe{border:0;margin:0;padding:0;min-width:0;display:flex;flex-direction:column;gap:var(--ds-3)}
.ds-gruppe > legend{float:left;width:100%;padding:0;margin:0 0 var(--ds-2);display:flex;align-items:center;gap:var(--ds-2);
  font:500 var(--ds-label-l) var(--font-ui);letter-spacing:var(--ds-label-l-track);text-transform:uppercase;color:var(--md-on-surface-variant)}
.ds-gruppe > label:not(.ds-check){display:flex;flex-direction:column;gap:var(--ds-1);min-width:0}
.ds-gruppe-schmal{max-width:440px}
/* Woher ein vorbelegter Wert stammt. Kein Schloss, nur eine Auskunft. */
.ds-herkunft{color:var(--md-primary)}
.ds-herkunft::before{content:"↳ ";opacity:.6}
/* Kasten — ein abgesetzter Bereich in einem Formular (z. B. das, was ein Weg braucht). */
.ds-kasten{padding:var(--ds-3) var(--ds-pad);border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-s);background:var(--md-surface-container)}

/* ── Wege — gleich gebaute Karten zur Wahl (Reiter mit Inhalt): Zeichen, Titel,
   ein Satz, und als Liefer-Zeile das, wonach man tatsächlich wählt. */
.ds-wege{display:grid;gap:var(--ds-2);grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:860px){.ds-wege{grid-template-columns:1fr}}
.ds-weg{display:grid;grid-template-columns:auto 1fr auto;gap:var(--ds-1) var(--ds-2);align-items:start;text-align:left;
  padding:var(--ds-3);border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-m);background:var(--md-surface-container-lowest);
  cursor:pointer;font:inherit;color:inherit;transition:border-color var(--ds-schnell),background var(--ds-schnell)}
.ds-weg:hover{border-color:var(--md-primary)}
.ds-weg.ist-da,.ds-weg[aria-selected="true"]{border-color:var(--md-primary);background:var(--md-primary-container);box-shadow:inset 0 0 0 1px var(--md-primary)}
.ds-weg.ist-blass .ds-weg-zeichen,.ds-weg.ist-blass .ds-weg-liefert{opacity:.55}
.ds-weg-zeichen{grid-row:1;width:28px;height:28px;display:grid;place-items:center;border-radius:var(--ds-eck-s);
  background:var(--md-surface-container-high);color:var(--md-on-surface-variant)}
.ds-weg-zeichen svg{width:15px;height:15px}
.ds-weg.ist-da .ds-weg-zeichen,.ds-weg[aria-selected="true"] .ds-weg-zeichen{background:var(--md-primary);color:var(--md-on-primary)}
.ds-weg-text{grid-row:1;display:flex;flex-direction:column;gap:1px;min-width:0}
.ds-weg-text b{font:500 var(--ds-title-s) var(--font-ui)}
.ds-weg-text > span{font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant)}
.ds-weg-liefert{grid-column:1/-1;margin-top:var(--ds-1);padding-top:var(--ds-2);border-top:1px dashed var(--md-outline-variant);
  font:400 var(--ds-label-m) var(--font-ui);color:var(--md-on-surface-variant)}
.ds-weg > .ds-pille{grid-row:1;grid-column:3;align-self:start}
/* ds-weg als Auswahlkarte: <label class="ds-weg"><input type="radio"> … — die Wahl
   liegt im (unsichtbaren) Radio, die Karte zeigt sie; Tastatur bleibt bedienbar. */
.ds-weg{position:relative}
.ds-weg > input[type=radio]{position:absolute;inset:0;margin:0;opacity:0;pointer-events:none}
.ds-weg:has(> input:checked){border-color:var(--md-primary);background:var(--md-primary-container);box-shadow:inset 0 0 0 1px var(--md-primary)}
.ds-weg:has(> input:checked) .ds-weg-zeichen{background:var(--md-primary);color:var(--md-on-primary)}
.ds-weg:has(> input:focus-visible){outline:2px solid var(--md-primary);outline-offset:2px}
.ds-wege.ds-zwei{grid-template-columns:repeat(2,minmax(0,1fr))}
@media (max-width:860px){.ds-wege.ds-zwei{grid-template-columns:1fr}}
.ds-dialog-leib{padding:var(--ds-4);overflow:auto;min-height:0}
.ds-dialog-fuss{display:flex;justify-content:flex-end;gap:var(--ds-2);
  padding-top:var(--ds-3);border-top:1px solid var(--md-outline-variant)}

/* ── Wer kann — der Kader als Kacheln, je Mensch ein Zustand ───────────
   Ein Baustein für drei Orte: Terminvorschlag am Match, Abstimmung am
   Kader, Kalendertermin (views/_wer_liste.php). Zustand als Farbe UND
   Wort — Farbe allein liest nicht jeder; „abwesend" gestrichelt, weil es
   eine Ableitung aus dem Abwesenheitskalender ist und kein Klick. */
.ds-wer-liste{display:flex;flex-wrap:wrap;gap:var(--ds-1) var(--ds-2);margin-top:var(--ds-2)}
.ds-wer{display:inline-flex;align-items:center;gap:var(--ds-2);padding:2px var(--ds-2) 2px 2px;
  max-width:100%;border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-voll);
  background:var(--md-surface-container);color:var(--md-on-surface-variant);
  font:400 var(--ds-label-l) var(--font-ui)}
.ds-wer .ds-person{color:inherit;gap:var(--ds-1)}
.ds-wer .ds-zeichen{width:22px;height:22px;font:500 var(--ds-label-s) var(--font-ui)}
/* Die Liste beantwortet „wer kann" — der Name darf nicht nach 14 Zeichen enden,
   und das Zustandswort ist die Information: volle Deckkraft. */
.ds-wer .ds-person-n{max-width:22ch}
.ds-wer-st{font:500 var(--ds-label-s) var(--font-ui);letter-spacing:var(--ds-label-s-track);
  text-transform:uppercase}
.ds-wer.ist-zusage{border-color:var(--md-erfolg);background:var(--md-erfolg-container);color:var(--md-on-erfolg-container)}
.ds-wer.ist-absage{border-color:var(--md-error);background:var(--md-error-container);color:var(--md-on-error-container)}
/* „Vielleicht" blau statt auf der Vereinsfarbe: bei rotem Akzent stand es
   in derselben Farbe wie „Absage". */
.ds-wer.ist-vielleicht{border-color:var(--md-tertiary);background:var(--md-tertiary-container);color:var(--md-on-tertiary-container)}
.ds-wer.ist-abwesend{border-style:dashed}
/* Offen: ohne Fläche statt halb durchsichtig — Name und „Offen" blieben
   sonst bei 3,0:1 bzw. 2,4:1 stehen. */
.ds-wer.ist-offen{background:transparent}

/* ── Reihe — Knöpfe und Marken nebeneinander, mit Umbruch ───────────── */
.ds-reihe{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ds-2)}

/* ── Ablage — eine Fläche, auf die man eine Datei zieht ───────────────
   Groß, weil sie die ganze Aufgabe ist (Demo Report): ein Feld, ein Satz.
   Ohne Skript bleibt sie ein Datei-Feld — das <label> öffnet die Auswahl. */
.ds-ablage{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--ds-1);
  min-height:240px;padding:var(--ds-6);text-align:center;cursor:pointer;
  border:2px dashed var(--md-outline);border-radius:var(--ds-eck-l);
  background:var(--md-surface-container-low);color:var(--md-on-surface-variant);
  transition:border-color var(--ds-schnell),background-color var(--ds-schnell)}
.ds-ablage b{font:500 var(--ds-title-m) var(--font-head);color:var(--md-on-surface)}
.ds-ablage:hover,.ds-ablage.ist-drueber{border-color:var(--md-primary);background:var(--md-primary-container)}
.ds-ablage:focus-within{outline:2px solid var(--md-primary);outline-offset:2px}

/* ===========================================================================
   WELLE 1 — die Bausteine, die die Startseite gebraucht hat (09.09.2026)
   =========================================================================== */
/* Kennzahl als Verweis: die ganze Kachel ist der Klick. */
a.ds-kennzahl{text-decoration:none;color:inherit}
a.ds-kennzahl:hover{background:var(--md-surface-container)}
.ds-kennzahl .ds-kz-w{display:block}

/* Fortschritt — der Balken aus dem Browser, ohne Inline-Stil. */
.ds-fortschritt{-webkit-appearance:none;appearance:none;flex:1 1 auto;min-width:80px;max-width:260px;
  height:6px;border:0;border-radius:var(--ds-eck-voll);overflow:hidden;
  background:var(--md-surface-container-highest)}
.ds-fortschritt::-webkit-progress-bar{background:var(--md-surface-container-highest)}
.ds-fortschritt::-webkit-progress-value{background:var(--md-erfolg)}
.ds-fortschritt::-moz-progress-bar{background:var(--md-erfolg)}

/* Datum als Marke — Tag groß, Monat klein. */
.ds-datum{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:0 0 auto;
  width:44px;min-height:44px;border-radius:var(--ds-eck-s);
  background:var(--md-surface-container-high);color:var(--md-on-surface)}
.ds-datum b{font:500 var(--ds-title-m) var(--font-head);line-height:1}
.ds-datum small{font:500 var(--ds-label-s) var(--font-ui);letter-spacing:var(--ds-label-s-track);
  text-transform:uppercase;color:var(--md-on-surface-variant)}

/* Zeile: Titel und Nebensatz untereinander; ein Verweis im Titel ohne Zierde. */
.ds-zeile .ds-fuellt b{display:block;font:500 var(--ds-body-m) var(--font-ui)}
.ds-zeile .ds-fuellt small{display:block;font:400 var(--ds-body-s) var(--font-ui);
  color:var(--md-on-surface-variant)}
/* Ein Handgriff UNTER dem Satz (statt daneben, wo er den Satz zerquetscht) —
   bündig mit dem Text, der Knopf-Innenabstand wird nach links ausgeglichen. */
.ds-zeile .ds-fuellt > .ds-knopf-text{margin:2px 0 0 calc(-1 * var(--ds-2))}
/* Verweis ohne Zierde — in Zeilen, Zellen und Nebensätzen; der Titel unterstreicht beim Überfahren. */
.ds-verweis{color:inherit;text-decoration:none}
.ds-verweis:hover,.ds-verweis:hover b{text-decoration:underline}
/* Pille als Verweis (Filter): kein Unterstrich, beim Überfahren dunkler. */
a.ds-pille{text-decoration:none}
a.ds-pille:hover{background:var(--md-surface-container-highest)}
a.ds-pille.ds-akzent:hover{background:var(--md-tertiary-container);filter:brightness(1.06)}
/* Nebensatz unter einem Zellentitel. */
.ds-tabelle td small{display:block;color:var(--md-on-surface-variant)}
.ds-zeile .ds-zeichen.ds-gut{background:var(--md-erfolg-container);color:var(--md-on-erfolg-container)}
/* Zeilen direkt im randlosen Karten-Leib bekommen ihr Polster selbst. */
.ds-karte-leib.ds-eng .ds-zeile{padding:var(--ds-1) var(--ds-pad)}
/* Randlose Tabelle in der Karte: erste und letzte Spalte rücken auf die
   Kante des Kartenkopfs ein, sonst klebt der Text am Kartenrand. */
:is(.ds-karte-leib.ds-eng,.ds-karte) > .ds-tabelle :is(th,td):first-child{padding-left:var(--ds-pad)}
:is(.ds-karte-leib.ds-eng,.ds-karte) > .ds-tabelle :is(th,td):last-child{padding-right:var(--ds-pad)}
.ds-karte-leib.ds-eng .ds-leer{padding:var(--ds-4) var(--ds-pad)}
/* Zwischenüberschrift innerhalb einer Karte (Gruppen einer Liste). */
.ds-abschnitt{margin:0;padding:var(--ds-2) var(--ds-pad) var(--ds-1);
  font:500 var(--ds-label-m) var(--font-ui);letter-spacing:var(--ds-label-m-track);
  text-transform:uppercase;color:var(--md-on-surface-variant);
  background:var(--md-surface-container-low);border-bottom:1px solid var(--md-outline-variant)}

/* Aufklappbarer Kartenkopf (<details>). */
summary.ds-karte-kopf{cursor:pointer;list-style:none}
summary.ds-karte-kopf::-webkit-details-marker{display:none}

/* Zwei Spalten INNERHALB einer Karte: Liste links, schmale Beigabe rechts. */
.ds-spalten.ds-spalten-schmal{grid-template-columns:minmax(0,1fr) 260px;gap:0}
.ds-spalten-schmal > .ds-mini-kalender{border-left:1px solid var(--md-outline-variant)}
@media (max-width:760px){
  .ds-spalten.ds-spalten-schmal{grid-template-columns:minmax(0,1fr)}
  .ds-spalten-schmal > .ds-mini-kalender{border-left:0;border-top:1px solid var(--md-outline-variant)}
}

/* ── Spielkarte (Stufe 1 der Match-Liste): Bild leise im Hintergrund ───── */
.ds-spiel{position:relative;display:block;text-decoration:none;color:inherit;min-height:120px}
.ds-spiel:hover{border-color:var(--md-primary)}
.ds-spiel-bild{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.16}
.ds-spiel > .ds-karte-leib{position:relative;display:flex}
.ds-spiel .ds-fuellt{display:flex;flex-direction:column;min-width:0}

/* Felder in einer Reihe (Filter): so breit wie ihr Inhalt, nicht die Zeile. */
.ds-reihe > label > .ds-feld{width:auto;min-width:140px}
/* Der gefährliche Knopf: rot umrandet, nie gefüllt. */
.ds-knopf.ds-schlecht{color:var(--md-error);border-color:var(--md-error)}
/* Der Text-Knopf bleibt randlos, auch in Rot: mit Rand sah "Endgueltig loeschen"
   aus wie der umrandete Knopf daneben. */
.ds-knopf-text.ds-schlecht{border-color:transparent}
/* Zellen, die nicht umbrechen sollen (Namen in einer scrollenden Tabelle). */
.ds-tabelle .ds-nowrap{white-space:nowrap}
/* Eingerückte Zelle: die zweite Ebene einer Gliederung. */
/* --ds-5 gibt es nicht (Skala 4 8 12 16 24 …): calc() mit ihr war ungültig,
   die Zelle fiel auf padding-left 0 — weniger eingerückt als die Elternzeile. */
.ds-tabelle td.ds-einzug{padding-left:calc(var(--ds-pad) + var(--ds-4))}
/* Kopfzeile einer Seite: Zeichen, Name mit Nebensatz, Pillen — in einer Reihe. */
.ds-reihe > .ds-fuellt{flex:1;min-width:0;display:flex;flex-direction:column}
.ds-reihe > .ds-fuellt .ds-label-s{color:var(--md-on-surface-variant)}

/* ===========================================================================
   AUFKLAPPBARE ZEILE — zugeklappt eine Zeile der Liste, aufgeklappt ein
   Formular darunter (Aufstellung, Zugehörigkeit: „wer war wann dabei").
   Der Pfeil zeigt den Zustand, nicht eine Farbe.
   =========================================================================== */
details.ds-auf > summary{list-style:none;cursor:pointer}
details.ds-auf > summary::-webkit-details-marker{display:none}
details.ds-auf > summary::after{content:"";width:7px;height:7px;flex:none;margin-left:var(--ds-1);
  border-right:1.5px solid var(--md-outline);border-bottom:1.5px solid var(--md-outline);
  transform:rotate(-45deg);transition:transform var(--ds-schnell)}
details.ds-auf[open] > summary::after{transform:rotate(45deg)}
.ds-liste > details.ds-auf > .ds-zeile{border-bottom:1px solid var(--md-outline-variant)}
.ds-liste > details.ds-auf:last-child:not([open]) > .ds-zeile{border-bottom:0}
.ds-auf-leib{padding:var(--ds-3) var(--ds-pad);border-bottom:1px solid var(--md-outline-variant);
  background:var(--md-surface-container)}
.ds-liste > details.ds-auf:last-child > .ds-auf-leib{border-bottom:0}

/* ===========================================================================
   FELDER — ein Formular als Stapel von Feldern; die Marke steht über dem
   Feld, der Hinweis darunter. Zwei Spalten, wo zwei Angaben zusammengehören.
   =========================================================================== */
.ds-felder{display:grid;gap:var(--ds-3);align-items:start}
.ds-felder.ds-zwei{grid-template-columns:repeat(2,minmax(0,1fr))}
.ds-felder > label:not(.ds-check){display:flex;flex-direction:column;gap:var(--ds-1);min-width:0}
.ds-felder > label > .ds-feldmarke{margin:0}
.ds-hinweis{font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant)}
/* Ein Verweis mitten im Satz (Hinweis, Meldung, Leerzustand) ist sonst nicht
   vom Text zu unterscheiden: app.css setzt a{color:inherit;text-decoration:none}. */
:is(.ds-hinweis,.ds-meldung,.ds-leer,.ds-fehler) a:not([class]){text-decoration:underline;text-underline-offset:2px}
:is(.ds-hinweis,.ds-meldung,.ds-leer,.ds-fehler) a:not([class]):hover{text-decoration-thickness:2px}
.ds-check{display:flex;align-items:center;gap:var(--ds-2);font:400 var(--ds-body-m) var(--font-ui);cursor:pointer}
.ds-check input{width:18px;height:18px;margin:0;accent-color:var(--md-primary)}
@media (max-width:560px){.ds-felder.ds-zwei{grid-template-columns:1fr}}
.ds-felder.ds-drei{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:760px){.ds-felder.ds-drei{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.ds-felder.ds-drei{grid-template-columns:1fr}}
/* Feldgrößen, wo ein Feld nicht die ganze Breite braucht: eine Zahl in einer
   Tabellenzelle, eine Reihenfolge, ein Zeitpunkt in einer Zeile. */
.ds-feld-zahl,.ds-feld.ds-feld-zahl{width:5.5em;min-width:4.5em;text-align:right;font-variant-numeric:tabular-nums}
.ds-feld-kurz,.ds-feld.ds-feld-kurz{width:5em;min-width:4em;text-align:right;font-variant-numeric:tabular-nums}
/* Doppelt, weil app.css input[type=datetime-local]{width:100%} (0,1,1) die
   einfache Klasse schlug — das Zeitfeld lief trotz Klasse über die volle Breite. */
.ds-feld-zeit,.ds-feld.ds-feld-zeit{width:auto;min-width:11.5em}
.ds-reihe > .ds-fuellt > .ds-feld{width:100%;min-width:0}
textarea.ds-feld,.ds-feld-text{height:auto;min-height:calc(var(--ds-feld) * 2.5);padding:var(--ds-2) var(--ds-3);resize:vertical;line-height:1.45}
/* Gerechnete Felder sind sichtbar gesperrt statt heimlich ignoriert — über
   Fläche und gestrichelten Rand, nicht über Deckkraft: opacity .6 drückte
   den Wert, den man hier lesen soll, auf 4,0:1. Abgeschaltete Felder
   (disabled, z. B. die Meta-Description im dynamischen Zustand der
   SEO-Werkbank) sehen genauso aus: .ds-feld setzt Grund und Schrift selbst
   und überstimmt damit die graue Browser-Darstellung — ohne diese Regel
   sah ein gesperrtes Feld aus wie ein freies. */
.ds-feld[readonly],.ds-feld[readonly]:hover,.ds-feld[readonly]:focus,
.ds-feld:disabled,.ds-feld:disabled:hover{background:var(--md-surface-container);
  color:var(--md-on-surface-variant);border-style:dashed;cursor:not-allowed}
.ds-tabelle td > .ds-feld-zahl + small{display:block;color:var(--md-on-surface-variant)}
.ds-tabelle .ds-zelle-breit{min-width:170px}
/* Fließtext in einer dichten Tabelle (Kommentare): Mindestbreite, Umbruch erlaubt. */
.ds-tabelle td.ds-zelle-text{min-width:24ch;white-space:normal}
/* Kopfzellen im Tabellenkörper (Gruppenzeilen) kleben NICHT mit — sonst schöben
   sie sich beim Scrollen oben übereinander. */
.ds-tabelle tbody th{position:static}
.ds-tabelle .ds-mitte{text-align:center}
.ds-tabelle th small{display:block;font:400 var(--ds-label-s) var(--font-ui);letter-spacing:0;text-transform:none}
/* Rechte-Matrix: Kopf mit Rollenname und Kontenzahl, Häkchen in Fingergröße. */
.ds-matrix thead th{height:auto;padding:var(--ds-1) var(--ds-2)}
.ds-matrix input[type="checkbox"]{width:18px;height:18px;accent-color:var(--md-primary);cursor:pointer}
.ds-matrix input[type="checkbox"]:disabled{cursor:not-allowed}
.ds-tabelle .ds-trenner{background:var(--md-surface-container);color:var(--md-on-surface-variant);
  font:500 var(--ds-label-m) var(--font-ui);text-transform:uppercase;letter-spacing:.04em}
.ds-block{display:block}
/* Der Standard-Absender für die Enter-Taste in Formularen mit mehreren Knöpfen:
   nicht display:none und nicht hidden — ein so versteckter Knopf zählt in manchen
   Browsern nicht mehr als Default-Button, und dann griffe der nächste in der Reihe. */
.ds-enter{position:absolute;width:1px;height:1px;padding:0;margin:-1px;border:0;opacity:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%)}
/* Der Kartenleib ist ein Container: Feldraster in einer schmalen Seitenspalte
   brechen auf eine Spalte, ohne dass die Seite es wissen muss. */
.ds-karte-leib{container-type:inline-size}
@container (max-width:560px){.ds-felder.ds-zwei,.ds-felder.ds-drei{grid-template-columns:1fr}}

/* ===========================================================================
   VORSCHLAG — ein Terminvorschlag: wann, Stand, wer kann, die eigene Antwort.
   Links der Sachverhalt, rechts die Handlung; schmal untereinander.
   =========================================================================== */
.ds-vorschlag{display:flex;gap:var(--ds-4);align-items:flex-start;padding:var(--ds-3) var(--ds-pad);border-bottom:1px solid var(--md-outline-variant)}
.ds-liste > .ds-vorschlag:last-child{border-bottom:0}
.ds-vorschlag.ist-fest{box-shadow:inset 3px 0 0 var(--md-erfolg)}
.ds-vorschlag-leib{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--ds-1)}
.ds-vorschlag-leib .ds-balken{margin-top:var(--ds-1)}
.ds-vorschlag-leib .ds-wer-liste{margin-top:var(--ds-1)}
.ds-vorschlag-wahl{flex:0 1 auto;max-width:min(44%,320px);display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:var(--ds-2)}
.ds-vorschlag-handgriffe{width:100%;justify-content:flex-end}
.ds-frist{color:var(--md-on-surface-variant);font-weight:500}
/* Antwort als Pille mit Radio: Zusagen grün, Absagen rot — erst, wenn gewählt. */
.ds-radio{display:inline-flex;align-items:center;gap:var(--ds-1);height:var(--ds-feld);padding:0 var(--ds-3);border-radius:var(--ds-eck-voll);
  border:1px solid var(--md-outline);color:var(--md-on-surface);font:500 var(--ds-label-l) var(--font-ui);cursor:pointer;user-select:none}
.ds-radio input{margin:0;accent-color:var(--md-primary)}
/* Gewählt ohne Ton: die Akzentfläche — auch als Mehrfachauswahl (Checkbox) brauchbar. */
.ds-radio:has(input:checked){border-color:var(--md-primary);background:var(--md-primary-container);color:var(--md-on-primary-container)}
.ds-radio.ds-gut:has(input:checked){border-color:var(--md-erfolg);background:var(--md-erfolg-container);color:var(--md-on-erfolg-container)}
.ds-radio.ds-schlecht:has(input:checked){border-color:var(--md-error);background:var(--md-error-container);color:var(--md-on-error-container)}
.ds-umbruch-wort{overflow-wrap:anywhere}
@media (max-width:640px){.ds-vorschlag{flex-direction:column}.ds-vorschlag-wahl{max-width:none;justify-content:flex-start}}

/* ===========================================================================
   SEITENKOPF — eine schlanke Zeile über dem Inhalt: Zurück, Pillen, rechts
   die Handgriffe. Das h1 steht in der Topbar; hier höchstens ein Untertitel.
   =========================================================================== */
.ds-seitenkopf{display:flex;align-items:center;gap:var(--ds-2);flex-wrap:wrap;margin-bottom:var(--ds-abstand)}
.ds-seitenkopf > h2{margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:500 var(--ds-title-m) var(--font-head);color:var(--md-on-surface)}
.ds-seitenkopf > .ds-rechts{margin-left:auto;display:flex;align-items:center;gap:var(--ds-2);flex-wrap:wrap}
.ds-seitenkopf + .ds-reiter{margin-top:calc(-1 * var(--ds-3))}

/* ===========================================================================
   BLÄTTERN — steht unter der Liste, nicht darüber: Wer blättert, hat gelesen.
   Links der Stand, rechts die Seiten als Knöpfe; die aktuelle ist gefüllt.
   =========================================================================== */
.ds-blaettern{display:flex;align-items:center;justify-content:space-between;gap:var(--ds-3);flex-wrap:wrap;
  margin-top:var(--ds-3);padding-top:var(--ds-3);border-top:1px solid var(--md-outline-variant)}
.ds-blaettern .ds-body-s{color:var(--md-on-surface-variant)}
.ds-blaettern .ds-knopf.ds-zahl{min-width:34px;justify-content:center;padding-left:var(--ds-2);padding-right:var(--ds-2)}
@media print{.ds-blaettern{display:none}}
/* Schmal bleiben nur Zurück/Weiter und die aktuelle Seite — zwölf Zahlenknöpfe
   nebeneinander sind auf einem Telefon nicht treffbar. */
@media (max-width:560px){
  .ds-blaettern{justify-content:center}
  .ds-blaettern > .ds-body-s{width:100%;text-align:center;order:2}
  .ds-blaettern .ds-knopf.ds-zahl:not([aria-current]){display:none}
}

/* ===========================================================================
   GUIDE — eine Karte für Inhalte mit Bild: Guides, Stratbook-Karten, News.
   Bild oben (oder eine beschriftete Fläche), darüber die Pillen, darunter
   Kicker, Titel, Kurztext, Tags und ein Fuß mit Reaktionen und Autor.
   =========================================================================== */
.ds-guide{display:flex;flex-direction:column;min-width:0;border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-m);
  overflow:hidden;background:var(--md-surface-container-lowest);color:inherit;text-decoration:none;transition:border-color var(--ds-schnell)}
.ds-guide:hover{border-color:var(--md-primary)}
.ds-guide-bild{position:relative;aspect-ratio:16/7;background:var(--md-surface-container);display:block}
.ds-guide-bild img{width:100%;height:100%;object-fit:cover;display:block}
.ds-guide-bild > .ds-reihe{position:absolute;top:var(--ds-2);left:var(--ds-2);right:var(--ds-2)}
.ds-guide-ph{position:absolute;inset:0;display:grid;place-items:center;font:500 var(--ds-label-l) var(--font-ui);letter-spacing:var(--ds-label-l-track);
  text-transform:uppercase;color:var(--md-on-surface-variant)}
.ds-guide-bild-gross{aspect-ratio:21/9;max-height:360px}
.ds-guide-leib{display:flex;flex-direction:column;gap:var(--ds-1);padding:var(--ds-3) var(--ds-pad);flex:1}
.ds-guide-kick{font:500 var(--ds-label-m) var(--font-ui);letter-spacing:var(--ds-label-m-track);text-transform:uppercase;color:var(--md-on-surface-variant)}
.ds-guide-titel{font:500 var(--ds-title-m) var(--font-head);color:var(--md-on-surface)}
.ds-guide-text{font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.ds-guide-fuss{margin-top:auto;padding-top:var(--ds-2);display:flex;gap:var(--ds-3);align-items:center;flex-wrap:wrap;
  font:400 var(--ds-label-m) var(--font-ui);color:var(--md-on-surface-variant)}
.ds-guide-fuss .ist-da{color:var(--md-primary)}
.ds-guide-fuss .ds-fuellt{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right}
/* Anhang — ein Bild mit Beschriftung, in einem engen Raster. */
.ds-anhang{display:flex;flex-direction:column;gap:var(--ds-1);min-width:0;color:inherit;text-decoration:none;
  border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-s);overflow:hidden;background:var(--md-surface-container-lowest)}
.ds-anhang img{width:100%;aspect-ratio:4/3;object-fit:cover;display:block}
.ds-anhang > span{padding:var(--ds-1) var(--ds-2);font:400 var(--ds-label-m) var(--font-ui);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ds-anhang form{padding:0 var(--ds-2) var(--ds-1)}
.ds-anhang.ist-da{border-color:var(--md-primary);box-shadow:inset 0 0 0 1px var(--md-primary)}
/* Eingerückte Zeile — eine Antwort unter ihrem Strang. */
.ds-zeile.ds-einzug{padding-left:calc(var(--ds-pad) + var(--ds-8))}
.ds-radio img{width:18px;height:18px;object-fit:cover;border-radius:var(--ds-eck-xs)}
.ds-feld-lang{min-height:260px}
.ds-tabelle .ds-nowrap .ds-reihe{flex-wrap:nowrap}

/* ===========================================================================
   MITGLIEDERKARTE — die ganze Karte führt zum Profil: die Marke trägt den
   Verweis und das Miniprofil, ihr Pseudoelement deckt die Karte ab. Kästchen
   und Werkzeuge liegen darüber, damit sie klickbar bleiben.
   =========================================================================== */
.ds-mitglied{position:relative}
.ds-mitglied > .ds-banner{height:72px}
.ds-mitglied .ds-person::after{content:"";position:absolute;inset:0}
.ds-mitglied:hover{border-color:var(--md-primary)}
/* Auf der Karte hat der Name Platz — kein Abschneiden wie in einer Zeile. */
.ds-mitglied .ds-person-n{max-width:none;white-space:normal}
.ds-mitglied .ds-wahl{position:absolute;top:var(--ds-2);left:var(--ds-2);z-index:1;display:flex}
.ds-mitglied .ds-wahl input{width:18px;height:18px;margin:0;accent-color:var(--md-primary)}
.ds-mitglied-werkzeuge{position:absolute;top:var(--ds-2);right:var(--ds-2);z-index:1;display:flex;gap:var(--ds-1)}
/* Enger Stapel: Zeilen einer Karte, die zusammengehören. */
.ds-eng-stapel{gap:var(--ds-2)}
.ds-filter-marke{min-width:52px}

/* ===========================================================================
   AUS DER AUFZEICHNUNG — Scoreboard gegenüber, Werte je Spieler
   =========================================================================== */
/* Zwei Hälften: links wir (vollständig), rechts der Gegner (Basics). */
.ds-gegenueber{display:grid;grid-template-columns:minmax(0,3fr) minmax(0,2fr)}
.ds-gegenueber > div + div{border-left:1px solid var(--md-outline-variant)}
@media (max-width:900px){.ds-gegenueber{grid-template-columns:1fr}.ds-gegenueber > div + div{border-left:0;border-top:1px solid var(--md-outline-variant)}}
.ds-tabelle tr.ist-gegner td{color:var(--md-on-surface-variant)}
.ds-tabelle tr.ist-ich td{background:var(--md-surface-container)}
.ds-tabelle tr.ist-vorbei td{color:var(--md-on-surface-variant)}
/* Die gewählte Pille (Partie der Wiedergabe) — app.js schaltet ist-da um. */
.ds-pille.ist-da{background:var(--md-primary-container);color:var(--md-on-primary-container)}
/* Aufklappbarer Abschnitt in einer Karte (eine Partie des Scoreboards). */
details.ds-auf > summary.ds-abschnitt{display:flex;align-items:center;gap:var(--ds-1)}
/* Vierzig Werte je Spieler: ein Raster aus Beschriftung und Zahl. */
.ds-werte{display:grid;gap:var(--ds-1) var(--ds-4);grid-template-columns:repeat(auto-fill,minmax(170px,1fr))}
.ds-wert{display:flex;align-items:baseline;justify-content:space-between;gap:var(--ds-2);min-width:0;
  padding:2px 0;border-bottom:1px dashed var(--md-outline-variant)}
.ds-wert-l{font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ===========================================================================
   ZUSTÄNDE — Fehler, Meldung, Laden (Phase 3, 09.09.2026)
   =========================================================================== */
/* FEHLER: Das Feld sagt es selbst — Rand UND Satz darunter, nie nur Farbe.
   aria-invalid setzt der Server (oder :user-invalid der Browser nach der
   ersten Eingabe); aria-describedby zeigt auf den Satz. */
.ds-feld[aria-invalid="true"],.ds-feld:user-invalid{border-color:var(--md-error)}
.ds-feld[aria-invalid="true"]:focus,.ds-feld:user-invalid:focus{outline-color:var(--md-error)}
.ds-fehler{font:400 var(--ds-body-s) var(--font-ui);color:var(--md-error)}
.ds-felder > label.ist-fehler > .ds-feldmarke{color:var(--md-error)}
/* MELDUNG: ein Satz im Fluss der Seite — Fehler, Erfolg, Hinweis. Fett ist
   das Ergebnis, danach der Grund oder der nächste Handgriff. */
.ds-meldung{display:block;padding:var(--ds-2) var(--ds-3);border-radius:var(--ds-eck-s);
  font:400 var(--ds-body-m) var(--font-ui);background:var(--md-surface-container-high);color:var(--md-on-surface)}
.ds-meldung.ds-schlecht{background:var(--md-error-container);color:var(--md-on-error-container)}
.ds-meldung.ds-gut{background:var(--md-erfolg-container);color:var(--md-on-erfolg-container)}
.ds-meldung b{font-weight:600}
.ds-meldung-fuss{margin-top:var(--ds-2)}
/* LADEN: ein Platzhalter in der Form des Inhalts, kein drehender Kreis im
   Nichts. Der Text bleibt im Markup (Screenreader lesen aria-busy), ist
   aber unsichtbar; das Schimmern läuft über die Fläche. */
.ds-laden{position:relative;overflow:hidden;color:transparent;pointer-events:none;
  background:var(--md-surface-container-high);border-radius:var(--ds-eck-xs)}
.ds-laden::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,var(--md-surface-container-highest),transparent);
  animation:ds-schimmer 1.4s var(--ds-kurve-standard) infinite}
.ds-laden-text{display:block;height:.9em;width:60%;margin:.2em 0}
small.ds-laden-text{width:40%}
@keyframes ds-schimmer{to{transform:translateX(100%)}}
/* Ein Knopf, der arbeitet: bleibt stehen, nimmt keine zweite Eingabe an;
   app.js setzt aria-busy beim Absenden. */
.ds-knopf[aria-busy="true"]{pointer-events:none;color:transparent}
.ds-knopf[aria-busy="true"]::after{content:"";position:absolute;width:14px;height:14px;border-radius:50%;
  border:2px solid var(--md-on-surface-variant);border-right-color:transparent;animation:ds-dreht .8s linear infinite}
.ds-knopf{position:relative}
@keyframes ds-dreht{to{transform:rotate(360deg)}}

/* ===========================================================================
   FARBE (Welle 3) — ein Farbfeld und die Farbrollen als Muster. Die Rollen
   sind die globale Palette aus Core\Farbe::ROLLEN; eine eigene Farbe kommt
   als --ds-farbe-wert im style-Attribut.
   =========================================================================== */
.ds-feld.ds-feld-farbe{width:64px;height:40px;padding:2px;cursor:pointer}
.ds-farben{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:var(--ds-2)}
.ds-farbe-muster{display:flex;flex-direction:column;gap:var(--ds-1);min-width:0}
.ds-farbe-muster small{font:400 var(--ds-label-m) var(--font-ui);color:var(--md-on-surface-variant);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ds-farbe{display:block;height:28px;border-radius:var(--ds-eck-xs);border:1px solid var(--md-outline-variant);background:var(--ds-farbe-wert,transparent)}
.ds-farbe[data-rolle="primary"]{background:var(--md-primary)}
.ds-farbe[data-rolle="secondary"]{background:var(--md-secondary)}
.ds-farbe[data-rolle="tertiary"]{background:var(--md-tertiary)}
.ds-farbe[data-rolle="erfolg"]{background:var(--md-erfolg)}
.ds-farbe[data-rolle="error"]{background:var(--md-error)}
.ds-farbe[data-rolle="primary-container"]{background:var(--md-primary-container)}
.ds-farbe[data-rolle="secondary-container"]{background:var(--md-secondary-container)}
.ds-farbe[data-rolle="tertiary-container"]{background:var(--md-tertiary-container)}
.ds-farbe[data-rolle="erfolg-container"]{background:var(--md-erfolg-container)}
.ds-farbe[data-rolle="error-container"]{background:var(--md-error-container)}
.ds-farbe[data-rolle="on-surface"]{background:var(--md-on-surface)}
.ds-farbe[data-rolle="outline"]{background:var(--md-outline)}
/* Farbwahl — der eine Farbwähler (views/_farbwahl.php): ein Radio je Rolle,
   „ohne Farbe" und „eigene Farbe" mit Farbfeld. Das Radio ist unsichtbar, aber
   fokussierbar; die Auswahl zeigt der Rahmen um das Muster. */
.ds-farbwahl{border:0;margin:0;padding:0;min-width:0;display:flex;flex-direction:column;gap:var(--ds-1);flex:1 1 100%}
.ds-farbwahl-raster{display:flex;flex-wrap:wrap;gap:var(--ds-1)}
.ds-farbwahl-feld{position:relative;display:inline-flex;cursor:pointer;padding:2px;border:2px solid transparent;border-radius:var(--ds-eck-s)}
.ds-farbwahl-feld > input[type="radio"]{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}
.ds-farbwahl-feld .ds-farbe{width:28px;height:28px}
.ds-farbwahl-feld:has(> input[type="radio"]:checked){border-color:var(--md-on-surface)}
.ds-farbwahl-feld:has(> input[type="radio"]:focus-visible){outline:2px solid var(--md-primary);outline-offset:1px}
.ds-farbwahl-eigen input[type="color"]{width:28px;height:28px;padding:0;border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-xs);background:none;cursor:pointer}
.ds-farbe.ds-farbe-ohne{background:linear-gradient(135deg,transparent 44%,var(--md-outline) 44%,var(--md-outline) 56%,transparent 56%)}
.ds-farbwahl-name{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* ===========================================================================
   MEDIEN (Welle 3) — das Bildfeld (views/_media_field.php) und die Mediathek.
   Zustand der Auswahl: .ist-da (app.js, data-media-choose).
   =========================================================================== */
.ds-medienfeld{display:flex;flex-direction:column;gap:var(--ds-1);min-width:0}
.ds-medien-bild{width:84px;height:84px;flex:none;display:grid;place-items:center;overflow:hidden;
  border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-s);background:var(--md-surface-container-low)}
.ds-medien-bild img{width:100%;height:100%;object-fit:contain;display:block}
.ds-medien-raster{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:var(--ds-2)}
.ds-medien-raster > .ds-leer{grid-column:1/-1}
.ds-medien-zelle{padding:0;aspect-ratio:1;border:2px solid transparent;border-radius:var(--ds-eck-s);overflow:hidden;
  background:var(--md-surface-container-low);cursor:pointer}
.ds-medien-zelle img{width:100%;height:100%;object-fit:contain;display:block}
.ds-medien-zelle:hover{border-color:var(--md-outline)}
.ds-medien-zelle.ist-da{border-color:var(--md-primary)}
.ds-medien-zelle:focus-visible{outline:2px solid var(--md-primary);outline-offset:1px}

/* ===========================================================================
   MARKE (17.09.2026, E8) — das Logo der Instanz in heller und dunkler Fassung.
   Core\Theme::logoBild() setzt zwei <img> (.ds-marke-hell/.ds-marke-dunkel), wenn
   die Fassungen verschieden sind; hier fällt die Wahl am data-scheme des
   <html> — dieselbe Regel wie bei den Farbrollen (Core\Material): hell ist
   der Standard, dunkel nur per ausdrücklicher Wahl. Nur display:none, nie ein
   Anzeigewert zurück: Das sichtbare Bild behält seinen eigenen.
   =========================================================================== */
:root:not([data-scheme="dark"]) .ds-marke-dunkel,
:root[data-scheme="dark"] .ds-marke-hell{display:none}
/* Im Formular steht jede Fassung auf dem Grund, für den sie gedacht ist. Die
   Umkehrfläche ist im hellen Schema dunkel und im dunklen hell. */
:root:not([data-scheme="dark"]) .ds-marke-feld[data-fassung="dunkel"] .ds-medien-bild,
:root[data-scheme="dark"] .ds-marke-feld[data-fassung="hell"] .ds-medien-bild{
  background:var(--md-inverse-surface);color:var(--md-inverse-on-surface)}
.ds-raster.ds-raster-medien{grid-template-columns:repeat(auto-fill,minmax(180px,1fr))}
.ds-medium{position:relative;margin:0;display:flex;flex-direction:column;min-width:0;overflow:hidden;
  border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-s);background:var(--md-surface-container-lowest)}
.ds-medium > img{width:100%;aspect-ratio:1;object-fit:contain;display:block;padding:var(--ds-1);background:var(--md-surface-container-low)}
.ds-medium-wahl{position:absolute;top:var(--ds-1);left:var(--ds-1);z-index:1;display:flex;padding:var(--ds-1);
  border-radius:var(--ds-eck-xs);background:var(--md-surface-container-lowest)}
.ds-medium-wahl input{width:18px;height:18px;margin:0;accent-color:var(--md-primary);cursor:pointer}
.ds-medium:has(.ds-medium-wahl input:checked){outline:2px solid var(--md-primary);outline-offset:-2px}
.ds-medium figcaption{display:flex;flex-direction:column;gap:var(--ds-1);padding:var(--ds-2);min-width:0}
.ds-medium-name{font:500 var(--ds-label-m) var(--font-ui);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ===========================================================================
   SCHALTER (Welle 3) — an/aus, speichert meist sofort (z. B. data-mail-toggle).
   Das Häkchen ist unsichtbar, aber fokussierbar; die Bahn zeigt den Zustand.
   =========================================================================== */
.ds-schalter{position:relative;display:inline-flex;align-items:center;cursor:pointer;flex:none}
.ds-schalter input{position:absolute;opacity:0;width:1px;height:1px;margin:0}
.ds-schalter-bahn{position:relative;width:44px;height:24px;border-radius:var(--ds-eck-voll);
  border:2px solid var(--md-outline);background:var(--md-surface-container-highest);transition:background var(--ds-schnell),border-color var(--ds-schnell)}
.ds-schalter-bahn::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;
  background:var(--md-outline);transition:transform var(--ds-schnell),background var(--ds-schnell)}
.ds-schalter input:checked + .ds-schalter-bahn{background:var(--md-primary);border-color:var(--md-primary)}
.ds-schalter input:checked + .ds-schalter-bahn::after{transform:translateX(20px);background:var(--md-on-primary)}
.ds-schalter input:focus-visible + .ds-schalter-bahn{outline:2px solid var(--md-primary);outline-offset:2px}
/* Eine abgeschaltete Zeile bleibt lesbar, tritt aber zurück — über die
   Textrolle, nicht über Deckkraft (opacity .6: Nebensatz 3,0:1, Pille 2,9:1). */
.ds-zeile.ist-aus > .ds-fuellt,.ds-zeile.ist-aus > .ds-fuellt b{color:var(--md-on-surface-variant)}
.ds-zeile.ist-aus > .ds-pille{background:transparent;border-color:var(--md-outline-variant)}
/* Reiter als Knöpfe (app.js, data-ap-tab setzt .on) — dieselbe Gestalt wie die Link-Reiter. */
.ds-reiter > button{display:inline-flex;align-items:center;gap:var(--ds-2);height:40px;padding:0 var(--ds-4);
  font:500 var(--ds-title-s) var(--font-ui);letter-spacing:var(--ds-title-s-track);color:var(--md-on-surface-variant);
  background:none;border:0;border-bottom:2px solid transparent;cursor:pointer;white-space:nowrap}
.ds-reiter > button:hover{color:var(--md-on-surface);background:var(--md-surface-container)}
.ds-reiter > button.on{color:var(--md-primary);border-bottom-color:var(--md-primary)}
/* Eine Seitenspalte, die beim Scrollen stehen bleibt (Vorschau neben einem Editor). */
.ds-klebt{position:sticky;top:var(--ds-3)}

/* ===========================================================================
   MUSTERSEITE /bausteine — nur dort gebraucht
   =========================================================================== */
.ds-muster-raster{grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}
.ds-muster-farbe{display:block;height:36px;border-radius:var(--ds-eck-xs);border:1px solid var(--md-outline-variant)}
.ds-muster-farbe[data-rolle="surface"]{background:var(--md-surface)}
.ds-muster-farbe[data-rolle="surface-container-low"]{background:var(--md-surface-container-low)}
.ds-muster-farbe[data-rolle="surface-container"]{background:var(--md-surface-container)}
.ds-muster-farbe[data-rolle="surface-container-high"]{background:var(--md-surface-container-high)}
.ds-muster-farbe[data-rolle="surface-container-highest"]{background:var(--md-surface-container-highest)}
.ds-muster-farbe[data-rolle="primary"]{background:var(--md-primary)}
.ds-muster-farbe[data-rolle="primary-container"]{background:var(--md-primary-container)}
.ds-muster-farbe[data-rolle="secondary-container"]{background:var(--md-secondary-container)}
.ds-muster-farbe[data-rolle="outline-variant"]{background:var(--md-outline-variant)}
.ds-muster-farbe[data-rolle="error-container"]{background:var(--md-error-container)}
.ds-muster-farbe[data-rolle="erfolg-container"]{background:var(--md-erfolg-container)}
.ds-muster-v-hoch{--v:.85}.ds-muster-v-mittel{--v:.5}.ds-muster-v-tief{--v:.2}
.ds-muster-b-60{width:60%}.ds-muster-b-40{width:40%}

/* ===========================================================================
   PROFILBLÖCKE (Welle 2) — Fließtext, Auszeichnungen, Rechnung, Reiter-Knöpfe
   =========================================================================== */
.ds-fliesstext{line-height:1.6}
.ds-raster.ds-raster-eng{grid-template-columns:repeat(auto-fill,minmax(92px,1fr));gap:var(--ds-2)}
.ds-raster.ds-raster-guides{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
/* Auszeichnung: erreicht in Farbe, sonst grau — und beides mit Beschriftung.
   Grau wird nur das Zeichen; die Beschriftung bleibt lesbar (vorher lag die
   ganze Kachel bei opacity .45 — Beschriftung 2,2:1). */
.ds-abzeichen{display:flex;flex-direction:column;align-items:center;gap:var(--ds-1);padding:var(--ds-2);
  border:1px dashed var(--md-outline-variant);border-radius:var(--ds-eck-s);text-align:center}
.ds-abzeichen .ds-abzeichen-em{opacity:.45;filter:grayscale(1)}
.ds-abzeichen.ist-da{border-style:solid;border-color:var(--md-primary);background:var(--md-surface-container)}
.ds-abzeichen.ist-da .ds-abzeichen-em{opacity:1;filter:none}
.ds-abzeichen-em{font:400 var(--ds-headline-s) var(--font-ui);line-height:1}
.ds-abzeichen-lb{font:400 var(--ds-label-s) var(--font-ui);color:var(--md-on-surface-variant);overflow:hidden;text-overflow:ellipsis;max-width:100%}
/* Eine Rechnung liest man von oben nach unten; die Formel darf umbrechen. */
.ds-rechnung{display:grid;gap:2px;font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant);font-variant-numeric:tabular-nums}
.ds-formel{display:block;font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant);overflow-wrap:anywhere}
.ds-pille svg{width:14px;height:14px;flex:none}
/* Ein Knopf als Reiter (role=tab): gewählt ist getönt. */
.ds-knopf[aria-selected="true"]{background:var(--md-secondary-container);color:var(--md-on-secondary-container);border-color:transparent}
/* Aufklappbarer Abschnitt am Ende einer Karte. */
.ds-karte > details.ds-auf{border-top:1px solid var(--md-outline-variant)}
.ds-karte > details.ds-auf > summary.ds-zeile{padding:var(--ds-1) var(--ds-pad)}

/* ===========================================================================
   CLIP-KARTE und SCHIEBER (Welle 2)
   =========================================================================== */
.ds-clip{display:flex;flex-direction:column;min-width:0;overflow:hidden;
  background:var(--md-surface-container-low);border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-m)}
/* Das Vorschaubild ist der Abspiel-Knopf (Zwei-Klick-Einbettung). */
.ds-clip-bild{position:relative;display:block;width:100%;aspect-ratio:16/9;overflow:hidden;padding:0;border:0;
  background:var(--md-surface-container-highest);color:var(--md-on-surface);cursor:pointer;text-decoration:none}
.ds-clip-bild img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.ds-clip-bild::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 45%,var(--md-on-surface));opacity:.45}
.ds-clip-ph{position:absolute;inset:0;display:grid;place-items:center;font:500 var(--ds-title-m) var(--font-head);color:var(--md-on-surface-variant)}
.ds-clip-start{position:absolute;left:50%;top:50%;z-index:1;width:46px;height:46px;transform:translate(-50%,-50%);
  display:grid;place-items:center;border-radius:var(--ds-eck-voll);background:var(--md-on-surface);color:var(--md-surface);opacity:.85;
  transition:transform var(--ds-schnell),opacity var(--ds-schnell)}
.ds-clip-start svg{width:22px;height:22px;margin-left:2px}
.ds-clip-bild:hover .ds-clip-start{transform:translate(-50%,-50%) scale(1.08);opacity:1}
.ds-clip-spiel{position:absolute;top:var(--ds-2);left:var(--ds-2);z-index:1}
.ds-clip .clip-player{aspect-ratio:16/9}
.ds-clip-leib{padding:var(--ds-3);display:flex;flex-direction:column;gap:var(--ds-2);min-width:0}
.ds-clip-leib > b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ds-clip-handgriffe{display:flex;align-items:center;gap:var(--ds-1)}
.ds-clip-handgriffe form{margin:0}
.ds-clip-handgriffe .ds-neben{margin-left:auto}
/* Gewählter Zustand eines Knopfes (gefällt mir, Favorit, am Profil). */
.ds-knopf.ist-da{background:var(--md-secondary-container);color:var(--md-on-secondary-container);border-color:transparent}
/* Schieber: eine Bahn, die seitwärts rollt, mit zwei Pfeilen (app.js). */
.ds-schieber{position:relative}
.ds-schieber-bahn{display:flex;gap:var(--ds-3);overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:var(--ds-1);scrollbar-width:thin}
.ds-schieber-bahn > *{flex:0 0 250px;scroll-snap-align:start}
.ds-schieber-pfeil{position:absolute;top:38%;z-index:2;width:30px;height:30px;transform:translateY(-50%);
  display:grid;place-items:center;border-radius:var(--ds-eck-voll);border:1px solid var(--md-outline-variant);
  background:var(--md-surface-container-low);color:var(--md-on-surface);cursor:pointer;font:400 var(--ds-title-m) var(--font-ui)}
.ds-schieber-pfeil:hover{border-color:var(--md-primary);color:var(--md-primary)}
.ds-schieber-pfeil.ist-links{left:-6px}
.ds-schieber-pfeil.ist-rechts{right:-6px}
/* Zeichen in Zuständen (Zeitleiste: Zu- und Abgänge, Marken). */
.ds-zeichen.ds-schlecht{background:var(--md-error-container);color:var(--md-on-error-container)}
.ds-zeichen.ds-akzent{background:var(--md-primary-container);color:var(--md-on-primary-container)}

/* ===========================================================================
   CODE UND SUCHVORSCHAU (Welle 3, Anbindungen). Der Codeblock trägt, was
   jemand kopiert und woanders einsetzt — Schlüssel, Einbettung, Shortcodes;
   die Suchvorschau zeigt einen Eintrag so, wie ihn eine Trefferliste zeigt.
   =========================================================================== */
.ds-code{display:block;margin:0;padding:var(--ds-2) var(--ds-3);border:1px solid var(--md-outline-variant);
  border-radius:var(--ds-eck-s);background:var(--md-surface-container);color:var(--md-on-surface);
  font:400 var(--ds-body-s) var(--font-data);white-space:pre;overflow-x:auto}
.ds-code.ds-umbruch-wort{white-space:pre-wrap}
.ds-code i{font-style:normal;color:var(--md-on-surface-variant)}
textarea.ds-feld.ds-code-feld{min-height:90px;font:400 var(--ds-body-s) var(--font-data)}
.ds-vorschaubild{width:56px;height:56px;flex:none;object-fit:contain;border-radius:var(--ds-eck-s);background:var(--md-surface-container)}
.ds-tabelle tr.ist-offen td{background:color-mix(in srgb,var(--md-error-container) 40%,transparent)}
.ds-tag{display:inline-flex;align-items:center;gap:var(--ds-1);height:32px;padding:0 var(--ds-1) 0 var(--ds-3);border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-voll);font:500 var(--ds-label-l) var(--font-ui)}
.ds-tabelle select.ds-feld{min-width:max-content}
.ds-tabelle input.ds-feld[type=text]:not(.ds-feld-kurz){min-width:9em}
.ds-abzeichenbild{display:grid;place-items:center;width:72px;height:40px;overflow:hidden;border-radius:var(--ds-eck-xs);background:var(--md-surface-container)}
.ds-abzeichenbild img{width:100%;height:100%;object-fit:contain}
.ds-punkt{display:inline-block;width:10px;height:10px;flex:none;border-radius:var(--ds-eck-voll);background:var(--md-outline)}
.ds-serp{max-width:600px;display:flex;flex-direction:column;gap:var(--ds-1);padding:var(--ds-3) var(--ds-pad);
  border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-s);background:var(--md-surface)}
.ds-serp-t{font:400 var(--ds-title-m) var(--font-ui);color:var(--md-primary);overflow-wrap:anywhere}
.ds-serp-u{font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant)}
.ds-serp-d{font:400 var(--ds-body-m) var(--font-ui);color:var(--md-on-surface-variant);overflow-wrap:anywhere}

/* ===========================================================================
   BELOHNUNGEN (Welle 3, Auszeichnungen) — der Bestand als Galerie. Rahmen
   liegen über einem Beispielgesicht: Erst darüber sieht man, ob die Mitte
   frei bleibt. Das Seitenverhältnis kommt je Art als --seite.
   =========================================================================== */
.ds-belohnung{display:flex;flex-direction:column;gap:var(--ds-1);padding:var(--ds-2);min-width:0;
  border:1px solid var(--md-outline-variant);border-radius:var(--ds-eck-m);background:var(--md-surface-container-low);
  color:inherit;text-decoration:none}
.ds-belohnung:hover{border-color:var(--md-outline)}
.ds-belohnung.ist-da{border-color:var(--md-primary);box-shadow:inset 0 0 0 1px var(--md-primary)}
.ds-belohnung:focus-visible{outline:2px solid var(--md-primary);outline-offset:2px}
/* Als Auswahl: <label class="ds-belohnung"><input type="radio"> … — der Zustand kommt
   vom Radio (Meine Belohnungen), nicht von einer serverseitigen Klasse. */
.ds-belohnung{position:relative;cursor:pointer}
.ds-belohnung > input[type=radio]{position:absolute;inset:0;margin:0;opacity:0;pointer-events:none}
.ds-belohnung:has(> input:checked){border-color:var(--md-primary);box-shadow:inset 0 0 0 1px var(--md-primary)}
.ds-belohnung:has(> input:focus-visible){outline:2px solid var(--md-primary);outline-offset:2px}
.ds-belohnung:has(> input:disabled){cursor:not-allowed}
.ds-belohnung:has(> input:disabled) .ds-belohnung-bild{opacity:.45}
.ds-belohnung-schloss{position:absolute;top:var(--ds-1);right:var(--ds-1);display:grid;place-items:center;width:24px;height:24px;border-radius:var(--ds-eck-voll);background:var(--md-surface-container-highest);color:var(--md-on-surface-variant);opacity:1}
.ds-belohnung-schloss svg{width:13px;height:13px}
.ds-belohnung-bild{position:relative;display:block;width:100%;aspect-ratio:var(--seite,1/1);overflow:hidden;
  border-radius:var(--ds-eck-s);background:var(--md-surface-container)}
.ds-belohnung-bild img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
.ds-belohnung-gesicht{position:absolute;inset:12%;display:grid;place-items:center;border-radius:var(--ds-eck-voll);
  background:var(--md-primary-container);color:var(--md-on-primary-container);font:500 var(--ds-title-m) var(--font-head)}
.ds-belohnung-name{font:500 var(--ds-label-l) var(--font-ui);overflow-wrap:anywhere}
.ds-belohnung small{font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant)}

/* TOR: die Seiten ohne App-Rahmen (Anmeldung, Einladung, Fehler,
   Installation, Rechtstexte von aussen). Eine Karte, mittig; die Meldungen
   des Shells stehen in derselben Breite darueber. */
body.plain{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--ds-3);
  min-height:100dvh;padding:var(--ds-6) var(--ds-4);background:var(--md-surface);color:var(--md-on-surface)}
body.plain > .ds-meldung{width:100%;max-width:440px}
.ds-tor{width:100%;max-width:440px}
.ds-tor.ds-tor-breit{max-width:760px}
.ds-tor-kopf{display:flex;align-items:center;gap:var(--ds-3);padding:var(--ds-4) var(--ds-pad);
  background:var(--md-surface-container);border-bottom:1px solid var(--md-outline-variant)}
.ds-tor-kopf .brand-mark{width:40px;height:40px}
.ds-tor-kopf h1{margin:0;font:500 var(--ds-title-l) var(--font-head);letter-spacing:var(--ds-title-l-track);color:var(--md-on-surface)}
.ds-tor-kopf p{margin:2px 0 0;font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant)}
.ds-tor > .ds-karte-leib + .ds-karte-leib,.ds-tor > .ds-auf + .ds-karte-leib{border-top:1px solid var(--md-outline-variant)}
/* MITTIG: eine einzelne schmale Karte im App-Rahmen (Erstanmeldung). */
.ds-mittig{width:100%;max-width:640px;margin-inline:auto}
/* Meldungen des App-Rahmens (Session-Flash) ueber dem Seiteninhalt. */
.ds-flash{margin-bottom:var(--ds-3)}

/* BILDRASTER-AUSWAHL (_entry_picker, 10.09.2026 aus dem Baustein hierher):
   ein Katalog im Character-Select-Stil — verstecktes Radio im <label>, der
   Rahmen kommt über :checked. Lange Kataloge (67 Waffen) scrollen in sich. */
.ep-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--ep-min,88px),1fr));gap:var(--ds-2);
  max-height:min(360px,60vh);overflow-y:auto;padding:2px}
.ep-grid.ep-sm{--ep-min:64px;gap:6px;max-height:240px}
.ep-cell{display:block;position:relative;margin:0;cursor:pointer;min-width:0}
.ep-cell input{position:absolute;display:block;width:1px;height:1px;opacity:0;margin:0;pointer-events:none}
.ep-cell:has(input:focus-visible) .ep-tile{outline:2px solid var(--md-primary);outline-offset:2px}
.ep-tile{aspect-ratio:var(--ep-ratio,3/4);border:2px solid var(--md-outline-variant);border-radius:var(--ds-eck-s);
  background:color-mix(in srgb,var(--ep-c,var(--md-surface-container-high)) 30%,var(--md-surface-container-high));
  display:grid;place-items:center;overflow:hidden;
  transition:border-color var(--ds-schnell) var(--ds-kurve-standard),box-shadow var(--ds-schnell) var(--ds-kurve-standard)}
.ep-cell:hover .ep-tile{border-color:var(--md-outline)}
.ep-cell input:checked+.ep-tile{border-color:var(--md-primary);box-shadow:inset 0 0 0 2px var(--md-primary)}
.ep-cell input:checked~.ep-name{color:var(--md-on-surface);font-weight:600}
.ep-tile img{width:100%;height:100%;object-fit:var(--ep-fit,cover)}
.ep-init{font:700 var(--ds-title-m) var(--font-head);color:var(--md-on-surface);letter-spacing:.02em}
.ep-none .ep-tile{background:var(--md-surface-container-high);color:var(--md-on-surface-variant);font:400 var(--ds-title-l) var(--font-ui)}
.ep-name{display:block;margin-top:3px;font:400 var(--ds-label-m) var(--font-ui);color:var(--md-on-surface-variant);
  text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ep-grid.ep-sm .ep-name{font:400 var(--ds-label-s) var(--font-ui)}

/* FAVORIT (_favorit, 10.09.2026): ein Katalogeintrag als Bild. Charaktere
   zeigen das Gesicht, Ausrüstung wird eingepasst statt beschnitten, Karten
   und Stages bekommen ein Querformat. */
.ds-favs{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ds-1) var(--ds-3)}
.ds-fav{position:relative;display:inline-flex;align-items:center;gap:var(--ds-2);min-width:0;max-width:100%;vertical-align:middle}
.ds-fav-bild{flex:none;display:grid;place-items:center;width:36px;height:36px;overflow:hidden;
  border-radius:var(--ds-eck-s);border:1px solid var(--md-outline-variant);
  background:color-mix(in srgb,var(--ds-fav-farbe,var(--md-surface-container-highest)) 30%,var(--md-surface-container-highest))}
.ds-fav-bild img{width:100%;height:100%;object-fit:cover}
.ds-fav[data-art="character"] .ds-fav-bild img{object-position:50% 18%}
.ds-fav[data-art="item"] .ds-fav-bild img{object-fit:contain;padding:2px}
.ds-fav[data-art="map"] .ds-fav-bild{width:56px}
.ds-fav-bild b{font:600 var(--ds-label-m) var(--font-head);color:var(--md-on-surface)}
.ds-fav-name{font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ds-fav.ds-gross .ds-fav-bild{width:56px;height:56px}
.ds-fav.ds-gross[data-art="map"] .ds-fav-bild{width:88px}
.ds-fav-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ===========================================================================
   TEAMKARTE UND SPIELERKARTE (/teams, 24.09.2026) — „Cardansichten mit
   Kurzstatistik": Banner oben, das Logo in der größten Stufe, drei
   Kennzahlen, darunter die aufgestellten Spieler mit Bild. Die Teamfarbe
   kommt als --ds-akzent an die Karte und wird hier zur oberen Kante.
   =========================================================================== */
.ds-raster.ds-raster-teams{grid-template-columns:repeat(auto-fill,minmax(260px,1fr));align-items:stretch}
.ds-teamkarte,.ds-spielerkarte{display:flex;flex-direction:column;min-width:0;
  border-top:3px solid var(--ds-akzent,var(--md-outline-variant))}
.ds-teamkarte > .ds-banner,.ds-spielerkarte > .ds-banner{height:96px}
/* Kopf: das große Logo links, Name und Zeile daneben; der Name darf umbrechen. */
.ds-teamkarte-kopf{display:flex;align-items:flex-start;gap:var(--ds-3)}
.ds-teamkarte-kopf > .ds-fuellt{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--ds-1)}
.ds-teamkarte-kopf .ds-verweis{text-decoration:none;color:inherit;overflow-wrap:anywhere}
.ds-teamkarte-kopf .ds-verweis:hover{text-decoration:underline}
.ds-teamkarte-kopf .ds-label-s{color:var(--md-on-surface-variant)}
/* Kennzahlen sitzen zwischen zwei Leibern: Linie oben, die untere übernimmt der nächste Leib. */
.ds-teamkarte > .ds-kennzahlen,.ds-spielerkarte > .ds-kennzahlen{border-top:1px solid var(--md-outline-variant)}
.ds-teamkarte > .ds-kennzahlen + .ds-karte-leib,.ds-spielerkarte > .ds-kennzahlen + .ds-karte-leib{border-top:0}
/* Die Form ist eine Kette, keine Zahl — sie bekommt Luft in der Kachel. */
.ds-teamkarte .ds-kennzahl dd .ds-form,.ds-spielerkarte .ds-kennzahl dd .ds-form{margin:var(--ds-1) 0}
.ds-teamkarte .ds-kennzahl.ds-offen dd{color:var(--md-on-surface)}
.ds-teamkarte .ds-kennzahl.ds-offen dd small{color:var(--md-error)}
/* Ein Name, der in zwei Teams desselben Spiels steht: die Zeile ist markiert, nicht nur der Hinweis. */
.ds-teamkarte .ds-zeile.ds-teamkarte-konflikt{background:var(--md-error-container);color:var(--md-on-error-container)}
.ds-teamkarte .ds-zeile .ds-fuellt small{display:block}
.ds-teamkarte-leer{display:block;padding:var(--ds-2) var(--ds-pad);color:var(--md-on-surface-variant)}
/* Der Fuß bleibt unten — auch wenn die Karte daneben höher ist. */
.ds-teamkarte-fuss{margin-top:auto}
/* Spielerkarte: das Bild größer als in einer Zeile, der Name darf umbrechen. */
.ds-spielerkarte .ds-zeichen.ds-gross{width:72px;height:72px;font:500 var(--ds-title-l) var(--font-head)}
.ds-spielerkarte .ds-person{align-items:center}
.ds-spielerkarte .ds-person-n{max-width:none;white-space:normal}
.ds-spielerkarte .ds-favs{gap:var(--ds-2) var(--ds-3)}
/* Rang-Pille mit der Farbe des Rangs — als Kante, damit der Text lesbar bleibt. */
.ds-pille.ds-rang[style*="--farbe"]{box-shadow:inset 3px 0 0 var(--farbe)}

/* ===========================================================================
   VIERER-RASTER, MATCH-KARTE UND GEGNER-KARTE (/wettkampf, /wettkampf/gegner,
   24.09.2026). Der Auftraggeber wollte für Matches und Gegner ein „4er-Grid":
   wenige Informationen je Eintrag, viele Einträge. Das Raster ist FEST
   vierspaltig (kein auto-fit — das würde je nach Breite drei oder fünf
   Spalten ergeben), und wird nach unten zu drei, zwei, einer Spalte.
   =========================================================================== */
.ds-raster.ds-raster-vier{grid-template-columns:repeat(4,minmax(0,1fr));align-items:stretch}
@media (max-width:1400px){.ds-raster.ds-raster-vier{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:1080px){.ds-raster.ds-raster-vier{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.ds-raster.ds-raster-vier{grid-template-columns:minmax(0,1fr)}}

/* MATCH-KARTE: oben eine 16:9-Fläche mit zwei Schichten — der Schnipsel der
   Erweiterung (Leinwand) und darunter der HTML-Rückfall —, unten der Leib
   mit „wer gegen wen", wann und dem Knopf. Das Häkchen der Stapelauswahl
   sitzt wie bei der Mitgliederkarte oben links über allem. */
.ds-matchkarte{position:relative;display:flex;flex-direction:column;min-width:0}
.ds-matchkarte:hover{border-color:var(--md-primary)}
.ds-matchkarte .ds-wahl,.ds-gegnerkarte .ds-wahl{position:absolute;top:var(--ds-2);left:var(--ds-2);z-index:2;display:flex}
.ds-matchkarte .ds-wahl input,.ds-gegnerkarte .ds-wahl input{width:18px;height:18px;margin:0;accent-color:var(--md-primary)}
.ds-matchkarte-bild{position:relative;display:block;width:100%;aspect-ratio:16/9;overflow:hidden;
  background:var(--md-surface-container);container-type:inline-size}
/* Die Leinwand der Erweiterung füllt die Fläche; eine Anzeige-Leinwand ist
   klein, die volle Größe (1600×900) hält nur EINE Offscreen-Leinwand. */
.ds-matchkarte-bild > canvas,.ds-matchkarte-bild > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* Gezeichnet → der Rückfall verschwindet. Scheitert das Zeichnen, bleibt er. */
.ds-matchkarte-bild.ist-gezeichnet .ds-matchkarte-rueckfall{display:none}
.ds-matchkarte-rueckfall{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:space-between;
  gap:var(--ds-1);padding:var(--ds-2)}
/* Das Map-Bild aus dem eigenen Katalog als leiser Hintergrund (wie .ds-spiel-bild). */
.ds-matchkarte-hinter{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:.16}
/* Pillen rechts oben — links oben sitzt im Bearbeiten-Modus das Häkchen. */
.ds-matchkarte-oben{position:relative;display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--ds-1);min-height:22px}
/* Wir · Stand · Gegner — drei Spalten, die Seiten gleich breit, der Stand so breit wie seine Zahl. */
.ds-matchkarte-gegenueber{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  align-items:center;gap:var(--ds-2)}
.ds-matchkarte-seite{display:flex;flex-direction:column;align-items:center;gap:var(--ds-1);min-width:0;text-align:center}
.ds-matchkarte-seite > b{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--md-on-surface)}
.ds-matchkarte-seite .ds-zeichen.ds-gross{width:56px;height:56px;font:500 var(--ds-title-l) var(--font-head)}
/* Ein Mensch (Core\Person) steht wie ein Team: Bild oben, Name darunter. */
.ds-matchkarte-seite .ds-person{flex-direction:column;gap:var(--ds-1);max-width:100%}
.ds-matchkarte-seite .ds-person-n{max-width:100%;font:500 var(--ds-label-l) var(--font-ui)}
.ds-matchkarte-stand{font:500 var(--ds-display-s) var(--font-head);letter-spacing:var(--ds-display-s-track);
  color:var(--md-on-surface);white-space:nowrap;line-height:1}
.ds-matchkarte-stand.ds-gut{color:var(--md-erfolg)}
.ds-matchkarte-stand.ds-schlecht{color:var(--md-error)}
.ds-matchkarte-vs{font:400 var(--ds-title-m) var(--font-ui);color:var(--md-on-surface-variant)}
/* Die Karten der Serie, kompakt: „Inferno 13:9 · Ancient 7:13 · Nuke 13:11". */
.ds-matchkarte-serie{position:relative;display:flex;flex-wrap:wrap;justify-content:center;gap:var(--ds-1) var(--ds-3);
  min-height:18px;font:400 var(--ds-label-m) var(--font-ui);color:var(--md-on-surface-variant)}
.ds-matchkarte-partie{white-space:nowrap}
.ds-matchkarte-partie b{color:var(--md-on-surface)}
.ds-matchkarte-partie.ds-gut b{color:var(--md-erfolg)}
.ds-matchkarte-partie.ds-schlecht b{color:var(--md-error)}
/* Schmale Fläche (drei, vier Spalten auf mittlerer Breite): kleinere Zeichen,
   kleinerer Stand, die Serie weicht — sie steht auf der Match-Seite. */
@container (max-width:300px){
  .ds-matchkarte-seite .ds-zeichen.ds-gross{width:44px;height:44px;font:500 var(--ds-title-m) var(--font-head)}
  .ds-matchkarte-stand{font:500 var(--ds-headline-s) var(--font-head);letter-spacing:0}
}
@container (max-width:230px){
  .ds-matchkarte-serie{display:none}
  .ds-matchkarte-seite > b,.ds-matchkarte-seite .ds-person-n{font:500 var(--ds-label-m) var(--font-ui)}
}
/* Der Leib: Namen und Zeitpunkt links, der Knopf rechts; bleibt unten, wenn die Nachbarkarte höher ist. */
.ds-matchkarte-leib{display:flex;align-items:center;gap:var(--ds-2);margin-top:auto}
.ds-matchkarte-leib > .ds-fuellt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.ds-matchkarte-leib .ds-title-s{display:flex;align-items:center;gap:var(--ds-1);min-width:0;overflow:hidden;white-space:nowrap}
.ds-matchkarte-leib .ds-title-s > a,.ds-matchkarte-leib .ds-title-s > span{min-width:0;overflow:hidden;text-overflow:ellipsis}
.ds-matchkarte-leib .ds-title-s .ds-person{display:inline;min-width:0;overflow:hidden;text-overflow:ellipsis}
.ds-matchkarte-leib .ds-title-s .ds-person-n{font:inherit}
.ds-matchkarte-leib .ds-matchkarte-vs{flex:none;font:400 var(--ds-label-m) var(--font-ui)}
.ds-matchkarte-meta{color:var(--md-on-surface-variant);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ds-matchkarte-leib > .ds-knopf{flex:none}

/* GEGNER-KARTE: Zeichen in der größten Stufe, Name als Weg zur Scouting-Seite,
   Pillen für Art und Zahl der Matches, darunter zwei Kennzahlen (Bilanz aus
   unserer Sicht, jüngstes Match). Ändern und Häkchen liegen wie bei der
   Mitgliederkarte in den Ecken (nur im Bearbeiten-Modus). */
.ds-gegnerkarte{position:relative;display:flex;flex-direction:column;min-width:0}
.ds-gegnerkarte:hover{border-color:var(--md-primary)}
.ds-gegnerkarte-kopf{display:flex;flex-direction:column;align-items:center;gap:var(--ds-1);text-align:center;flex:1}
.ds-gegnerkarte-kopf > .ds-zeichen{margin-bottom:var(--ds-1)}
.ds-gegnerkarte-kopf > .ds-verweis{max-width:100%;overflow-wrap:anywhere}
.ds-gegnerkarte-kopf > .ds-body-s{color:var(--md-on-surface-variant);max-width:100%;overflow-wrap:anywhere}
.ds-gegnerkarte-pillen{justify-content:center;margin-top:var(--ds-1)}
.ds-gegnerkarte-pillen a.ds-pille{text-decoration:none}
.ds-gegnerkarte-pillen a.ds-pille:hover{border-color:var(--md-primary);color:var(--md-primary)}
.ds-gegnerkarte > .ds-kennzahlen{border-top:1px solid var(--md-outline-variant)}
.ds-gegnerkarte .ds-kennzahl dd .ds-gut{color:var(--md-erfolg)}
.ds-gegnerkarte .ds-kennzahl dd .ds-schlecht{color:var(--md-error)}

/* ===========================================================================
   AUFSTELLUNG — Zonen mit Plätzen, Kader als Chips (25.09.2026)
   views/_match_termin.php · js/42-aufstellung.js · views/_aufstellung_karte.php
   Ein Mensch ist EIN Element (.ds-au-person) mit zwei Gesichtern: im Kader
   der Chip (.ds-au-chip, gebaut wie .ds-wer), im Platz die Karte
   (.ds-au-karte). Welches zu sehen ist, entscheidet allein der Ort im Baum
   — deshalb wird beim Ziehen nur verschoben und nie neu gebaut, und die
   gezeichnete Leinwand der Dynamischen Grafiken bleibt.
   =========================================================================== */
.ds-au{display:flex;flex-direction:column;gap:var(--ds-4)}
.ds-au-zone{border:1px dashed var(--md-outline-variant);border-radius:var(--ds-eck-m);padding:var(--ds-3);
  background:var(--md-surface-container-low);transition:border-color .15s,background-color .15s}
.ds-au-zone.ist-drueber{border-color:var(--md-primary);background:var(--md-surface-container-high)}
.ds-au-zone.ist-zuviel{border-color:var(--md-error)}
.ds-au-zone-kopf{display:flex;align-items:center;gap:var(--ds-2);flex-wrap:wrap;margin-bottom:var(--ds-2)}
.ds-au-zone-kopf b{font:500 var(--ds-title-s) var(--font-ui);letter-spacing:var(--ds-title-s-track)}
.ds-au-zone-kopf small{flex-basis:100%;font:400 var(--ds-body-s) var(--font-ui);color:var(--md-on-surface-variant)}
.ds-au-slots{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:var(--ds-3)}
.ds-au-slot{position:relative;display:flex;flex-direction:column;min-height:240px;
  border:1px dashed var(--md-outline);border-radius:var(--ds-eck-m);background:var(--md-surface);
  transition:border-color .15s,box-shadow .15s}
.ds-au-slot:has(.ds-au-person){border-style:solid;border-color:var(--md-outline-variant)}
.ds-au-slot.ist-drueber{border-color:var(--md-primary);box-shadow:inset 0 0 0 2px var(--md-primary)}
.ds-au-slot.ist-zuviel{border-color:var(--md-error)}
.ds-au-slot-leer{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--ds-1);
  margin:auto;padding:var(--ds-3);text-align:center;color:var(--md-on-surface-variant);
  font:500 var(--ds-label-l) var(--font-ui)}
.ds-au-slot-leer small{font:400 var(--ds-label-s) var(--font-ui)}
.ds-au-slot:has(.ds-au-person) .ds-au-slot-leer{display:none}

/* Der Mensch */
.ds-au-person{min-width:0}
.ds-au-person[draggable="true"]{cursor:grab}
.ds-au-person[draggable="true"]:active{cursor:grabbing}
.ds-au-person.ist-gezogen{opacity:.45}
.ds-au-slot > .ds-au-person{flex:1;display:flex;flex-direction:column}
.ds-au-slot .ds-au-chip{display:none}
.ds-au-pool .ds-au-karte{display:none}

/* Chip im Kader: ein Knopf im Kleid von .ds-wer (Zustandsfarben ist-zusage/ist-absage/…) */
.ds-au-chips{display:flex;flex-wrap:wrap;gap:var(--ds-2);min-height:44px;align-items:flex-start}
.ds-au-chips:empty::after{content:"—";color:var(--md-on-surface-variant);font:400 var(--ds-body-s) var(--font-ui)}
button.ds-au-chip{appearance:none;-webkit-appearance:none;cursor:inherit;font-family:var(--font-ui);text-align:left}
button.ds-au-chip:hover{border-color:var(--md-primary)}
button.ds-au-chip:focus-visible{outline:2px solid var(--md-primary);outline-offset:2px}
.ds-au-chip .ds-au-chip-n{max-width:22ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Karte im Platz */
.ds-au-karte{display:flex;flex-direction:column;flex:1;animation:ds-au-auf .25s ease-out}
@keyframes ds-au-auf{from{transform:scale(.92);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){.ds-au-karte{animation:none}}
.ds-au-karte-bild{position:relative;aspect-ratio:4/5;overflow:hidden;border-radius:var(--ds-eck-m) var(--ds-eck-m) 0 0;
  background:var(--md-surface-container-high)}
.ds-au-karte-bild > canvas{position:absolute;inset:0;width:100%;height:100%}
.ds-au-karte-bild.ist-gezeichnet .ds-au-karte-rueckfall{display:none}
.ds-au-karte-fuss{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ds-1);padding:var(--ds-2);margin-top:auto}
.ds-au-karte-fuss .ds-au-karte-name{flex:1 1 100%;font:600 var(--ds-label-l) var(--font-ui);color:var(--md-on-surface);text-decoration:none;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ds-au-karte-griffe{display:flex;flex-wrap:wrap;gap:0}
.ds-au-karte-griffe .ds-knopf.ds-klein{height:28px;padding:0 var(--ds-2);font:500 var(--ds-label-m) var(--font-ui)}

/* Der HTML-Rückfall der Karte (views/_aufstellung_karte.php): Spielfarbe als --farbe */
.ds-au-kh{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--ds-2);
  padding:var(--ds-3);text-align:center;color:var(--md-on-surface);
  background:var(--md-surface-container-high);
  background:linear-gradient(165deg,color-mix(in srgb,var(--farbe,var(--md-primary)) 45%,var(--md-surface-container-highest)),var(--md-surface-container-high) 72%)}
.ds-au-kh-nr{position:absolute;top:var(--ds-2);left:var(--ds-2);display:inline-flex;align-items:center;justify-content:center;
  min-width:24px;height:24px;padding:0 var(--ds-1);border-radius:var(--ds-eck-voll);
  background:var(--md-surface);color:var(--md-on-surface);font:600 var(--ds-label-m) var(--font-ui)}
.ds-au-kh-nr:empty{display:none}
.ds-au-kh-name{font:600 var(--ds-title-s) var(--font-head);overflow-wrap:anywhere;max-width:100%}
.ds-au-kh-tag{font:400 var(--ds-label-m) var(--font-ui);color:var(--md-on-surface-variant);overflow-wrap:anywhere;max-width:100%}
.ds-au-meldung{min-height:1.25rem;color:var(--md-on-surface-variant)}
.ds-au-meldung:empty{display:none}
@media (max-width:600px){
  .ds-au-slots{grid-template-columns:repeat(auto-fill,minmax(124px,1fr))}
  .ds-au-slot{min-height:200px}
}
