/* ============================================================================
 * spieler.css — Die oeffentliche Spielerseite
 * ----------------------------------------------------------------------------
 * ERGAENZT NUR, WAS DIE LIBRARY NICHT HERGIBT.
 *
 * Umgebaut am 14.08.2026 nach Tims Hinweis "Als Style wie immer die Library".
 * Die erste Fassung hatte drei Dinge selbst gebaut, die es laengst gibt:
 *
 *   .sp-kopf   → tc-page-header   (header.css, "ersetzt 13+ Seiten-Header")
 *   .sp-block  → tc-panel         (panel.css, "ersetzt flache <section>-Bloecke")
 *   .sp-zahl   → tc-statcard      (statcard.css, samt --gold/--win/--loss)
 *
 * Besonders aergerlich war tc-statcard: Die Komponente bringt genau die
 * Datenfarben mit, die ich mir hier selbst definiert hatte.
 *
 * Was bleibt, ist die ANORDNUNG (Zweispalter, Portrait im Kopf) und die
 * Bauteile, die es sonst nirgends gibt: Bilanz-Ziffer, Systemchips,
 * Tier-Pillen und das Beitragsraster.
 *
 * Token-First (§3/§9): kein Hex ausser bei Medaillenfarben — die bedeuten
 * etwas ueber die Daten und bleiben deshalb hart (§9).
 * ========================================================================== */

/* --------------------------------------------------------------- Grundlage */

/* DER HINTERGRUND MUSS HIER STEHEN (14.08.2026, Tim: "Hintergrund ist noch
   weiss"). Auf dieser Plattform setzt KEIN globales Stylesheet den
   Body-Hintergrund — jede Seite bringt ihn selbst mit (untergrund.css,
   aos-lists.css, library.css tun das je einzeln). Fehlt er, scheint das Weiss
   des Browsers durch, und zwar nur dort, wo keine Karte darueberliegt: oben
   beim Zurueck-Link und unten unter dem letzten Panel.
   Dasselbe Muster wie die font-family-Falle aus CLAUDE.md §9 — was man auf
   dieser Plattform nicht selbst setzt, erbt man nicht.

   UND `html` MUSS MIT. Nur `body` einzufaerben reicht auf dem iPhone nicht:
   Beim Ueberscrollen (Bounce) zieht Safari die Flaeche des Wurzelelements
   nach, und die war transparent — daher der weisse Streifen unter der
   Navigation auf Tims Screenshot. Am Schreibtisch faellt das nie auf, weil
   dort nicht ueberscrollt wird. */
html, body {
  background: var(--tc-bg-base);
}

/* UND DIE GRUNDSCHRIFT (14.08.2026, Tim: "Die Schriftart ist doch falsch,
   oder nicht? Das ist doch Times.").

   Er hatte recht. Dieselbe Ursache wie beim Hintergrund, nur eine Zeile
   weiter: `body` traegt auf dieser Plattform GAR KEINE font-family — auch
   nicht auf oldworld.html oder den Systemseiten. Die Schrift kommt ueberall
   aus den Komponentenklassen. Wer eine neue Seite baut und auf Vererbung
   hofft, bekommt Times.

   Sichtbar war es nur im Fliesstext: Die Ueberschriften kamen ueber
   tc-panel__title in Cinzel, alles darunter — Titel, Systemchips, Termine,
   Ratings — stand in Times. CLAUDE.md §9 beschreibt genau diesen Fall, und
   untergrund.css loest ihn seit dem 14.08. mit denselben zwei Zeilen.

   Auf `.theme-community`, nicht auf `:root`: So trifft die Regel keine
   andere Seite (§9). Die Grundfarbe steht daneben, weil sonst jeder Text,
   dessen Klasse keine Farbe setzt, das Browser-Schwarz erbt — auf dunklem
   Grund unlesbar. */
body.theme-community {
  font-family: Lato, 'Segoe UI', system-ui, sans-serif;
  color: var(--tc-text-default, #b0b0b0);
  min-height: 100vh;
}

/* ------------------------------------------------------------------- Kopf */

/* Das Portrait ist der einzige Zusatz am tc-page-header: Die Komponente kennt
   ein Icon, aber kein Bild in Avatargroesse. */
.sp-kopf__portrait {
  margin-bottom: var(--tc-space-3);
}
/* Groesse kommt seit dem 14.08.2026 aus .tc-avatar--xl (atoms-extra.css) —
   die Klasse stand hier schon im Markup, war aber nirgends definiert, und
   diese Regel hat die 104px in Wahrheit erzeugt. Uebrig bleibt der Rahmen:
   der ist seitenspezifisch (der Untergrund soll ihn spaeter einfaerben, #322)
   und gehoert deshalb nicht in die Library. */
.sp-kopf__portrait .tc-avatar {
  border: 2px solid var(--tc-border-default);
}
/* Platzhalter fuer den spaeteren Avatarrahmen aus dem Untergrund (#322). */
.sp-kopf__portrait.hat-rahmen .tc-avatar {
  border-color: var(--tc-accent);
  box-shadow: 0 0 14px var(--tc-accent-glow);
}

.sp-kopf__systeme {
  display: flex;
  flex-wrap: wrap;
  gap: var(--tc-space-2);
  margin-top: var(--tc-space-3);
}

.sp-sys {
  font-size: var(--tc-text-sm);
  color: var(--tc-text-default);
  background: rgba(0, 0, 0, .25);
  border: 1px solid var(--tc-border-default);
  border-radius: var(--tc-radius-full);
  padding: var(--tc-space-1) var(--tc-space-3);
}

.sp-kopf__keinkontakt {
  font-size: var(--tc-text-sm);
  color: var(--tc-text-muted);
}

/* --------------------------------------------------------------- Anordnung */

/* Einspaltig bis 900px, darueber zwei Spalten. Auf dem Rechner lief vorher
   alles untereinander — eine sehr lange Spalte mit viel Leerraum rechts. */
.sp-spalten {
  display: grid;
  gap: var(--tc-space-5);
  align-content: start;
}

@media (min-width: 900px) {
  .sp-spalten {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
  /* Nur "Alte Rechnungen" laeuft ueber beide Spalten — der Block, der bei
     einem fremden Profil den Einstieg traegt.

     ⚠️ Hier stand bis zum 14.08.2026 zusaetzlich `:nth-child(2)`, und das war
     ein Positionsraten mit Nebenwirkung: Auf dem EIGENEN Profil faellt
     _geschichte() weg, also war das zweite Panel nicht mehr die Chronik,
     sondern die TERMINE — eine schmale Liste, ueber die volle Breite gezogen.
     Tim: "Wo X auftauchen wird, kann wohl neben die Chronik."
     Jetzt ordnen sich alle uebrigen Panels von selbst zweispaltig:
     Chronik | Termine, darunter Vitrine | Banner, dann Werke | Aufgeschnappt.
     Eine Regel, die von der Position abhaengt, meint nicht das, was sie
     trifft — sie meint, was an dieser Stelle GERADE steht. */
  .sp-panel--gross {
    grid-column: 1 / -1;
  }
}

/* --------------------------------------------------------------- Textteile */

.sp-text    { color: var(--tc-text-default); margin: 0 0 var(--tc-space-3); }
.sp-unter   { color: var(--tc-text-muted); font-size: var(--tc-text-sm);
              margin: var(--tc-space-4) 0 var(--tc-space-2); }
.sp-leer    { color: var(--tc-text-muted); margin: 0; }
.sp-hinweis { color: var(--tc-text-default); margin: var(--tc-space-3) 0 0;
              padding-top: var(--tc-space-3); border-top: 1px solid var(--tc-border-default); }

/* .sp-mehr war bis zum 14.08.2026 ein vollstaendiger Zweitbau von
   tc-button--link: eigener Hintergrund, eigener Rahmen, eigene Schriftgroesse,
   eigenes Hover. Die Variante gibt es in button.css seit jeher — gemessen
   waren die beiden nebeneinander sichtbar verschieden (13,12px ohne Radius
   gegen 11,52px mit 8px Radius). Das Markup traegt jetzt
   `tc-button tc-button--link sp-mehr`; hier bleibt nur, was die Komponente
   nicht mitbringt: der Abstand nach oben. */
.sp-mehr {
  margin-top: var(--tc-space-4);
  /* tc-button--link setzt min-height:auto — am Finger zu klein (Heuristik 5).
     Gleiche Spezifitaet (0,1,0) wie .tc-button--link, aber spieler.css laedt
     NACH button.css, also gewinnt diese Regel. Im Browser nachgemessen, nicht
     angenommen (CLAUDE.md §10, Spezifitaetsfalle). */
  min-height: 36px;
}
/* Kein eigenes :hover mehr — tc-button--link ist bereits unterstrichen und
   hellt beim Ueberfahren auf. Die alte Regel hat das nur nachgebaut. */

/* -------------------------------------------------------------- Bilanz */

/* Der staerkste Block der Seite bekommt sichtbar mehr Gewicht als die
   uebrigen — er beantwortet "was hatten wir miteinander". */
.sp-bilanz {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--tc-space-5);
  padding: var(--tc-space-4) 0 var(--tc-space-5);
}

.sp-bilanz__seite {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--tc-space-2);
}

.sp-bilanz__zahl {
  font-size: clamp(2.6rem, 9vw, 4rem);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--tc-text-strong);
  line-height: .95;
}

.sp-bilanz__wer {
  font-size: var(--tc-text-sm);
  color: var(--tc-text-muted);
  max-width: 9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sp-bilanz__doppel {
  color: var(--tc-text-muted);
  font-size: var(--tc-text-2xl);
  align-self: flex-start;
  margin-top: var(--tc-space-2);
}

/* Datenfarben (§9): Sie bedeuten etwas ueber das Ergebnis, nicht ueber die
   Stimmung — Semantik-Token statt Theme-Akzent. */
.sp-bilanz--vorn   .sp-bilanz__seite:first-child .sp-bilanz__zahl { color: var(--tc-success); }
.sp-bilanz--hinten .sp-bilanz__seite:last-child  .sp-bilanz__zahl { color: var(--tc-danger); }

/* -------------------------------------------------------------- Termine */

.sp-termine, .sp-sachen, .sp-eintraege { list-style: none; margin: 0; padding: 0; }

.sp-termin {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--tc-space-2);
  padding: var(--tc-space-2) 0;
  border-bottom: 1px solid var(--tc-border-subtle);
}
.sp-termin:last-child { border-bottom: none; }

.sp-termin__datum {
  font-variant-numeric: tabular-nums;
  color: var(--tc-text-muted);
  font-size: var(--tc-text-sm);
  min-width: 5.5em;
}
.sp-termin__titel { color: var(--tc-text-default); flex: 1 1 8rem; }
.sp-termin__mit {
  font-size: var(--tc-text-sm);
  color: var(--tc-success);
  border: 1px solid var(--tc-success-border);
  background: var(--tc-success-bg);
  border-radius: var(--tc-radius-sm);
  padding: 0 var(--tc-space-1);
}

.sp-einladen {
  margin-top: var(--tc-space-4);
  padding-top: var(--tc-space-4);
  border-top: 1px solid var(--tc-border-default);
}
.sp-einladen__frage {
  color: var(--tc-text-muted);
  font-size: var(--tc-text-sm);
  margin: 0 0 var(--tc-space-2);
}
.sp-einladen__liste { display: flex; flex-wrap: wrap; gap: var(--tc-space-2); }

/* --------------------------------------------------------------- Sachen */

.sp-sache {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--tc-space-2);
  padding: var(--tc-space-2) 0;
  border-bottom: 1px solid var(--tc-border-subtle);
}
.sp-sache:last-child { border-bottom: none; }
.sp-sache__art    { font-size: var(--tc-text-sm); color: var(--tc-text-muted); min-width: 8em; }
.sp-sache__name   { color: var(--tc-text-strong); }
.sp-sache__zusatz { font-size: var(--tc-text-sm); color: var(--tc-text-muted); }
.sp-sache__wert   { margin-left: auto; font-variant-numeric: tabular-nums;
                    color: var(--tc-highlight); font-weight: 600; }
.sp-sache.is-ruhend { opacity: .55; }

/* ------------------------------------------------------------ Tier-Pillen */

.sp-tiere {
  display: flex;
  flex-wrap: wrap;
  gap: var(--tc-space-2);
  margin-bottom: var(--tc-space-3);
}

.sp-tier {
  font-size: var(--tc-text-sm);
  font-variant-numeric: tabular-nums;
  border: 1px solid;
  border-radius: var(--tc-radius-sm);
  padding: var(--tc-space-1) var(--tc-space-2);
}
/* Medaillenfarben sind Datenfarben und bleiben hart (§9). */
.sp-tier--platinum { color: #b8c4cc; border-color: rgba(184, 196, 204, .35); background: rgba(184, 196, 204, .07); }
.sp-tier--gold     { color: #d9b451; border-color: rgba(217, 180, 81, .35);  background: rgba(217, 180, 81, .08); }
.sp-tier--silver   { color: #c0c0c0; border-color: rgba(192, 192, 192, .3);  background: rgba(192, 192, 192, .07); }
.sp-tier--bronze   { color: #c8956a; border-color: rgba(200, 149, 106, .35); background: rgba(200, 149, 106, .08); }

/* --------------------------------------------------------------- Werke */

.sp-galerie {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: var(--tc-space-2);
}
/* ⚠️ DIE HUELLE IST DAS RASTERELEMENT (01.09.2026, Taskwerk #504) — seit
   die Resonanz unter dem Bild steht. `min-width: 0`, weil Grid-Elemente
   `min-width: auto` haben und der Inhalt sonst die Spaltenbreite sprengt.
   Dieselbe Bauart wie `.wt-bild-huelle` im Dashboard-Teaser. */
.sp-galerie__huelle {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.sp-galerie__bild {
  display: block;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--tc-radius-sm);
  border: 1px solid var(--tc-border-default);
  transition: border-color var(--tc-motion-normal, 200ms ease);
}
.sp-galerie__bild:hover { border-color: var(--tc-accent); }
.sp-galerie__bild img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ⚠️ DIE KACHEL BRAUCHT DAFUER `position: relative` — sie hatte keine.
   Ohne sie bezoege sich das absolut gesetzte Datum auf den naechsten
   positionierten Vorfahren und stuende irgendwo auf der Seite (01.09.2026,
   Taskwerk #529). */
.sp-galerie__bild { position: relative; }

/* Wann das Bild entstanden ist. Bis zum 01.09.2026 stand hier gar kein
   Datum: Sechs Bilder nebeneinander, und man konnte nicht unterscheiden,
   ob jemand gestern gearbeitet hat oder im April.
   Unten quer statt in einer Ecke — der Streifen deckt nur die letzten
   Bildpixel ab, und die tragen bei einem Modellfoto selten die Aussage. */
.sp-galerie__wann {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 2px 6px;
  font-size: 0.68rem;
  line-height: 1.4;
  color: var(--tc-text-default);
  background: linear-gradient(to top, rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0));
  text-align: right;
  pointer-events: none;
}

.sp-eintrag {
  padding: var(--tc-space-2) 0;
  border-bottom: 1px solid var(--tc-border-subtle);
}
.sp-eintrag:last-child { border-bottom: none; }
.sp-eintrag__text   { color: var(--tc-text-default); margin: 0 0 var(--tc-space-1); }
.sp-eintrag__datum  { font-size: var(--tc-text-sm); color: var(--tc-text-muted); }

/* ------------------------------------------------------------- Zurueck */

.sp-zurueck {
  display: inline-block;
  color: var(--tc-text-muted);
  text-decoration: none;
  font-size: var(--tc-text-sm);
  padding: var(--tc-space-2) 0;
  margin-bottom: var(--tc-space-3);
  min-height: 36px;
}
.sp-zurueck:hover { color: var(--tc-highlight); }

/* ----------------------------------------------------------------- Mobil */

@media (max-width: 600px) {
  .sp-termin__datum { min-width: 0; }
  .sp-sache__art    { min-width: 0; }
  .sp-bilanz        { gap: var(--tc-space-4); }
  .sp-kopf__portrait .tc-avatar { width: 88px; height: 88px; }
}

/* tc-button--sm ist 32px hoch — am Schreibtisch richtig, am Finger zu klein.
   Heuristik 5 verlangt mindestens 36px. Bewusst NUR auf dieser Seite und nur
   bei grobem Zeiger: Die Library-Komponente global zu aendern wuerde jeden
   Kompaktbereich der Plattform mitverschieben.
   Spezifitaet 0,3,0 — schlaegt .tc-button--sm (0,1,0) unabhaengig von der
   Ladereihenfolge (§10, Spezifitaetsfalle). */
@media (hover: none) and (pointer: coarse) {
  .sp-einladen__liste .tc-button,
  .tc-page-header__actions .tc-button,
  .tc-panel__body .tc-button {
    min-height: 36px;
    padding-top: var(--tc-space-2);
    padding-bottom: var(--tc-space-2);
  }
}

/* --------------------------------------------------- Siegquoten je System
   Tim, 14.08.2026: "Ich haette gerne jedes System zusammen. Inkl.
   Gesamtsiegesquote in % pro System."

   Baut auf .sp-sache auf, statt eine zweite Listenoptik einzufuehren —
   dieselbe Zeilenform wie "Unter seinem Banner" darunter. Nur der Abstand
   nach oben und die Tabellenziffern kommen dazu; die Prozentzahlen sollen
   untereinander stehen, sonst tanzt die Spalte bei 8 % / 67 % / 100 %. */
.sp-quoten {
  margin-top: var(--tc-space-3);
  border-top: 1px solid var(--tc-border-subtle);
  padding-top: var(--tc-space-2);
}
.sp-quoten .sp-sache__zusatz { font-variant-numeric: tabular-nums; }

/* -------------------------------------------- Kommentare mit Ziel (14.08.2026)
   Tim: "Die Kommentare muss man klicken koennen und zum Kontext kommen."
   Ein Kommentar ohne seinen Gegenstand ist eine Zeile ohne Aussage. Der
   ganze Eintrag ist die Trefferflaeche, nicht nur der Hinweistext — am
   Finger trifft man sonst danebem. */
.sp-eintrag--klickbar { padding: 0; }
.sp-eintrag__ziel {
  display: block;
  padding: var(--tc-space-2) 0;
  color: inherit;
  text-decoration: none;
  border-radius: var(--tc-radius-sm, 6px);
  transition: background-color var(--tc-motion-fast, 120ms) ease;
}
.sp-eintrag__ziel:hover,
.sp-eintrag__ziel:focus-visible { background: var(--tc-deco-warm-bg); }
.sp-eintrag__hinweis {
  display: inline-block;
  margin-left: var(--tc-space-2);
  font-size: var(--tc-text-sm);
  color: var(--tc-highlight);
}
/* Die Bildkacheln sind jetzt Schalter, nicht nur Links — das darf man sehen. */
.sp-galerie__bild { cursor: zoom-in; }

/* ------------------------------------------------- Geburtstag (14.08.2026)
   Phase 1: An dem Tag faellt er auf, sonst steht er ruhig in der Kopfzeile.
   Die Farbe ist Auszeichnungsgold, keine Datenfarbe — hier bedeutet nichts
   "gut" oder "schlecht", es ist eine Feststellung (CLAUDE.md §9). */
.sp-geburtstag.is-heute {
  color: var(--tc-highlight);
  font-weight: 600;
}

/* Der Kuchen (17.09.2026, #328) steht zwischen Kopf und Spalten. Der Kopf
   bringt seinen Abstand nach unten mit, die Spalten keinen nach oben —
   gemessen: 24 px darueber, 0 px darunter. */
.sp-kuchen {
  margin-bottom: var(--tc-space-5);
}

/* ------------------------------------------- Kopf auf dem Rechner (14.08.2026)
   Tim: "Kannst du die Desktop Ansicht vom Profil noch optimieren, bitte. […]
   Sonst gerne noch ein finales Polish, damit es fertiger wirkt."

   Gemessen war der Kopf 391px hoch bei 1252px Seitenhoehe — fast ein Drittel
   der Seite fuer ein Portrait und drei Zeilen Text, weil tc-page-header alles
   zentriert untereinander stapelt. Am Handy ist das genau richtig; auf dem
   Rechner steht daneben nur Leere.

   Deshalb hier ein Zweispalter: Portrait links ueber die volle Hoehe, alles
   Uebrige rechts, linksbuendig. Die Komponente selbst bleibt unberuehrt — sie
   zentriert auf jeder anderen Seite zu Recht. */
@media (min-width: 900px) {
  /* Das Portrait wird aus dem Fluss genommen und links hineingestellt; der
     Textblock bekommt links Platz dafuer. Kein Grid, keine Spalten.

     ⚠️ WARUM NICHT GRID — der erste Versuch am 14.08.2026 sah richtig aus und
     war es nicht. Das Portrait stand auf `grid-row: 1 / -1`, um ueber alle
     Zeilen zu reichen. Aber `-1` zeigt auf die letzte Linie des EXPLIZITEN
     Rasters, und ein solches gibt es hier nicht (die Zeilen entstehen
     implizit aus den Kindern). Also landete das Portrait allein in Zeile 1
     und machte sie 109px hoch — genau seine eigene Hoehe. Der Name sass oben
     darin, der Untertitel begann 70px darunter: die Luecke, die Tim gemeldet
     hat ("Datt isset aber noch nich").

     Gemessen sichtbar an `grid-template-rows: 109px 36px 33px 43px 46px` —
     die erste Zeile faellt aus der Reihe. Meine erste Diagnose (Zeilenhoehe)
     und meine zweite (geerbtes gap) waren beide falsch; gefunden hat es erst
     das Auslesen des berechneten Rasters.

     Die absolute Fassung ist unempfindlich dagegen, WIE VIELE Zeilen der Kopf
     hat — und die Zahl schwankt: eigenes gegen fremdes Profil, mit und ohne
     Titel, mit und ohne Systemchips. Jede Loesung mit `span N` waere eine
     Zahl, die beim naechsten Element still danebenliegt. */
  .sp-kopf {
    text-align: left;
    padding: var(--tc-space-5);
    padding-left: calc(104px + var(--tc-space-5) * 2);
    min-height: calc(104px + var(--tc-space-5) * 2);
  }
  /* Spezifitaet 0,3,0 mit Absicht. header.css hebt JEDEN direkten Slot mit
     `.tc-page-header > *:not(.tc-page-header__banner-img) { position: relative }`
     ueber das Bannerbild — das ist 0,2,0 und schlug meine erste Fassung
     (`.sp-kopf__portrait`, 0,1,0). Sichtbar war nur die Folge: `left: 24px`
     und `transform` griffen, `position: absolute` nicht, und weil `left` bei
     `position: relative` vom FLUSS-Ort aus verschiebt, landete das Portrait
     24px rechts hinter dem Innenabstand — mitten im Text.
     Gemessen an `getComputedStyle().position === 'relative'`; im Quelltext
     sah die Regel vollkommen richtig aus (CLAUDE.md §10, Spezifitaetsfalle). */
  .tc-page-header.sp-kopf .sp-kopf__portrait {
    position: absolute;
    left: var(--tc-space-5);
    /* Oberkante statt Mitte: Mittig sass das Portrait auf Hoehe von Untertitel
       und Metazeile, waehrend der Name darueber stand — zwei Achsen, die nicht
       zueinander passten. Jetzt beginnt es dort, wo auch der Name beginnt. */
    top: var(--tc-space-5);
    margin-bottom: 0;
    z-index: 1;
  }
  /* Der Titel traegt sonst die Zeilenhoehe der gestapelten Fassung (104px bei
     35px Schrift) — neben dem Portrait riss das eine zweite Luecke. */
  .sp-kopf .tc-page-header__title {
    line-height: 1.1;
    margin-bottom: var(--tc-space-1);
  }
  /* ⚠️ `text-align: left` am Kopf reicht fuer diese beiden NICHT.
     `__meta` und `__actions` sind Flex-Container mit `justify-content: center`
     aus header.css — Flex richtet sich nicht nach text-align, sondern nach
     justify-content. Die Metazeile stand deshalb weiter mittig, waehrend Name
     und Untertitel schon links sassen; genau die schiefe Achse, die Tim
     gemeldet hat ("Sieht besser aus, aber noch nicht gut"). */
  .sp-kopf .tc-page-header__meta { justify-content: flex-start; }

  /* Die Aktion (Einstellungen bzw. Kontakt) stand als eigene Zeile ganz unten
     und liess den Kopf unten ausfransen. Oben rechts sitzt sie da, wo man eine
     Nebenaktion sucht, und kostet keine eigene Zeile mehr.
     Spezifitaet 0,3,0 aus demselben Grund wie beim Portrait: header.css hebt
     jeden direkten Slot per `> *:not(...)` auf `position: relative` (0,2,0). */
  .tc-page-header.sp-kopf .tc-page-header__actions {
    position: absolute;
    top: var(--tc-space-4);
    right: var(--tc-space-5);
    margin-top: 0;
    justify-content: flex-end;
    width: auto;
    z-index: 1;
  }
}


/* ----------------------------------------------------------------------------
   EHRENTITEL IM KOPF (20.08.2026)
   ----------------------------------------------------------------------------
   Sie stehen bewusst NICHT in der Vitrine: Ein Achievement ist etwas, das man
   geholt hat, ein Ehrentitel etwas, das man IST. Und dieses Profil ist der
   einzige Ort, an dem ihn ANDERE sehen — im Tresor sieht ihn nur der Traeger
   selbst.

   Abgesetzt vom Level-Badge, weil er eine andere Sorte Auszeichnung ist: Das
   Level waechst weiter, der Ehrentitel ist eingefroren und wird nie wieder
   vergeben. Es gibt sie genau dreimal auf der Plattform.
   -------------------------------------------------------------------------- */
.tc-page-header__badge.sp-ehrentitel {
  border-color: var(--tc-accent);
  background: rgba(201, 169, 89, 0.12);
  color: var(--tc-highlight);
  cursor: help;
}


/* ============================================================================
 * AUF DEINEN KOPF — Kopfgelder (#323, 29.08.2026)
 * ----------------------------------------------------------------------------
 * Eine Liste, kein Raster: Es sind selten mehr als drei, und jede Zeile trägt
 * drei verschieden gewichtete Angaben (wer, von wem, wofür). Nebeneinander
 * gestellt läsen sie sich wie gleichrangige Felder — sie sind es nicht.
 * ========================================================================== */
.sp-kopfgeld {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sp-kopfgeld__zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 8px 12px;
  background: rgba(139, 0, 0, 0.07);
  border: 1px solid rgba(139, 0, 0, 0.28);
  border-radius: var(--tc-radius-md, 8px);
}

/* Blutrot, nicht Theme-Akzent: Ein Kopfgeld ist eine Drohung, und die Farbe
   sagt hier etwas über die Sache aus (Datenfarbe nach §9). */
.sp-kopfgeld__wen {
  font-weight: 600;
  color: var(--tc-text-strong);
}

.sp-kopfgeld__wer {
  font-size: var(--tc-text-xs, 0.72rem);
  color: var(--tc-text-muted);
}

/* Der Lohn steht in einer eigenen Zeile, wenn es eng wird — er ist oft ein
   ganzer Satz („Ein Twix XXL. So n Twix kann man durchbrechen."). */
.sp-kopfgeld__lohn {
  flex-basis: 100%;
  font-size: var(--tc-text-xs, 0.72rem);
  color: var(--tc-highlight);
  font-style: italic;
}

.sp-kopfgeld__eigene {
  margin: 10px 0 0;
  font-size: var(--tc-text-sm, 0.85rem);
  color: var(--tc-text-muted);
}

.sp-kopfgeld__mehr { margin-top: 12px; }


/* ============================================================================
 * DIE VISITENKARTE IM KOPF (#323, 29.08.2026)
 * ----------------------------------------------------------------------------
 * ⚠️ `justify-content` MUSS HIER STEHEN. .tc-statline ist ein Flex-Container,
 * und der richtet sich NICHT nach dem `text-align: left` des Kopfes — genau
 * dieselbe Stelle, an der die Meta-Zeile schon einmal nachgebessert werden
 * musste, nachdem Tim „Sieht besser aus, aber noch nicht gut" gemeldet hatte.
 * Ohne die Zeile stehen die drei Zahlen mittig über einem linksbündigen Kopf.
 *
 * Und `position: relative` — header.css setzt es für alle DIREKTEN Kinder von
 * .tc-page-header (Spezifität 0,2,0). Bei gesetztem Bannerbild rutschte ein
 * Element ohne eigenen Stapelplatz sonst darunter.
 * ========================================================================== */
.sp-kopf__karte {
  justify-content: flex-start;
  gap: 22px;
  margin-top: 10px;
  position: relative;
  z-index: 1;
}

@media (max-width: 480px) {
  /* Drei Zahlen passen bei 375px in eine Reihe, aber nur knapp — der Abstand
     gibt nach, nicht die Schrift. */
  .sp-kopf__karte { gap: 14px; }
}


/* ============================================================================
 * ZWEI NEUE ABSCHNITTE — Herausforderungen und das Profilbuch
 * (#317 + #321, 06.09.2026)
 * ----------------------------------------------------------------------------
 * `sp-liste` ist die schlichte Schwester von `sp-eintraege`: eine Reihe von
 * Zeilen ohne Trennlinien, für Inhalte, die als Aufzählung gelesen werden und
 * nicht als Verlauf. Die Herausforderungen benutzen sie flach, das Profilbuch
 * mit dem Modifier `--buch`.
 *
 * ⚠️ ES GIBT KEINE GRÖSSENANGABE AM LÖSCH-KNOPF. Er trägt `tc-button--icon`
 * aus button.css (§7k), und ein `width` hier würde die Komponente still
 * überstimmen — das Stilblatt lädt NACH button.css, und bei gleicher
 * Spezifität gewinnt die spätere Regel. Genau daran sind am 21.08.2026
 * neunzehn migrierte Knöpfe hängengeblieben.
 * ========================================================================== */
.sp-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* ⚠️ `min-width: 0` an BEIDEN Seiten, nicht nur am Text. Flex-Kinder haben die
   Vorgabe `auto`, und ein einziges Glied mit dieser Vorgabe hält die
   Mindestbreite seines Inhalts fest und schiebt sie nach oben durch — bei
   375px lief die Zeile sonst über den Rand (§10, die `minmax(0, 1fr)`-Falle
   in ihrer Flex-Form). */
.sp-zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  min-width: 0;
  padding: 8px 12px;
  background: var(--tc-deco-warm-bg, rgba(201, 169, 89, 0.06));
  border: 1px solid var(--tc-border-subtle, rgba(255, 255, 255, 0.08));
  border-radius: var(--tc-radius-md, 8px);
}

.sp-zeile__text {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--tc-text-default);
  overflow-wrap: anywhere;
}

/* Nebensache in der Zeile: Datum, Klammerzusatz, Statushinweis. */
.sp-dim {
  font-size: var(--tc-text-xs, 0.72rem);
  color: var(--tc-text-muted);
}

/* ⚠️ `text-decoration` GEHÖRT HIERHER, nicht ins Theme. `mordheim-theme.css`
   setzt global `a { text-decoration: none }` — spieler.html lädt die Datei
   aber NICHT. Ein `<a>` ohne eigene Regel wäre hier blau unterstrichen; das
   ist derselbe Fall, der am 03.09.2026 die Reiter im Untergrund erwischt hat.
   Und die Trefferfläche: 36px nach Heuristik 5, unter `pointer: coarse` mehr —
   der Wert kommt aus dem Token, nicht als getippte Zahl. */
.sp-link {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: var(--tc-touch-min, 36px);
  color: var(--tc-highlight);
  font-size: var(--tc-text-sm, 0.85rem);
  text-decoration: none;
  white-space: nowrap;
}

.sp-link:hover,
.sp-link:focus-visible { text-decoration: underline; }


/* ---------------------------------------------------------------- Profilbuch
 * Ein Eintrag ist ein kleiner Zettel: Kopfzeile mit Verfasser und Datum, dann
 * der Text. Mehr Luft zwischen den Einträgen als in der flachen Liste — hier
 * wird gelesen, nicht überflogen.
 * -------------------------------------------------------------------------- */
.sp-liste--buch { gap: 12px; }

.sp-buch-eintrag {
  padding: 10px 12px;
  /* Der Zettel setzt sich vom Panel ab: surface-1 ist die Karte,
     surface-2 liegt darauf. `--tc-bg-elevated` stand hier zuerst und
     gibt es NICHT — mit Rückfall nicht kaputt, aber vom Theme
     abgekoppelt, genau wie die drei Fälle im Kopf von tokens.css. */
  background: var(--tc-bg-surface-2);
  border: 1px solid var(--tc-border-subtle, rgba(255, 255, 255, 0.08));
  border-left: 3px solid var(--tc-accent);
  border-radius: var(--tc-radius-md, 8px);
}

.sp-buch-kopf {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-bottom: 6px;
  color: var(--tc-text-strong);
}

/* Schiebt den Knopf ans Ende, egal wie lang der Name ist. */
.sp-buch-weg {
  margin-left: auto;
  color: var(--tc-text-muted);
}

.sp-buch-weg:hover,
.sp-buch-weg:focus-visible {
  color: var(--tc-danger, #c0392b);
  border-color: var(--tc-danger-border, rgba(192, 57, 43, 0.5));
}

/* ⚠️ `pre-wrap`, damit getippte Zeilenumbrüche stehen bleiben — ein Eintrag
   ist Fließtext von Hand, keine Datenzeile. Dazu `anywhere`, sonst sprengt
   ein einziges langes Wort die Spalte (§10). */
.sp-buch-text {
  margin: 0;
  color: var(--tc-text-default);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Das Formular steht UNTER den Einträgen: Man liest erst, was da ist, und
   schreibt dann. Umgekehrt stünde die Einladung über fremden Worten. */
.sp-buch-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  margin-top: 14px;
}

.sp-buch-form .tc-textarea { width: 100%; }

.sp-buch-label {
  font-size: var(--tc-text-sm, 0.85rem);
  color: var(--tc-text-muted);
}
