/* ============================================================================
   Anwendungsweite Träger, die die Stilschicht nicht liefert.

   Alles hier ist Layout außerhalb des Kern-Inventars und damit vorläufig (FE-28) —
   eingetragen unter „Bauteile außerhalb des Kern-Inventars" im Frontend-Plan.
   Keine Literale: Farben, Maße und Radien kommen aus packages/tokens (FE-11).
   ========================================================================== */

/* --- Eingebettete Icon-Sprites --------------------------------------------- *
 * Die Symbole müssen im Dokument stehen, damit <use href="#…"> sie findet,
 * dürfen selbst aber keinen Platz belegen: Ein <svg> ohne Maße ist 300 × 150
 * px gross und stand als leerer Streifen über jeder Seite. Kein display:none —
 * darin verlieren Verläufe und Masken ihren Bezug.                            */
.sprite {
  position: absolute;
  inline-size: 0;
  block-size: 0;
  overflow: hidden;
}

/* --- Auth-Seiten: eine Karte in der Mitte ---------------------------------- */
.auth {
  display: grid;
  place-items: center;
  min-block-size: 100vh;
  padding: var(--space-5);
  background: var(--bg-region);
}

.auth__card {
  inline-size: 100%;
  max-inline-size: 28rem;
}

.auth__brand {
  margin-block-end: var(--space-5);
}

.auth__title {
  font-size: var(--font-size-title);
  margin-block-end: var(--space-4);
}

.auth__footer {
  margin-block-start: var(--space-4);
  font-size: var(--font-size-small);
  color: var(--zone-text-quiet);
}

/* --- Kennzahlen: Kacheln -------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--space-4);
}

/* --- Werkzeugleiste über Listen ------------------------------------------- */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: var(--space-3);
  /* Luft zum Ergebnis — zusätzlich zum Stapelabstand des Panels. */
  margin-block-end: var(--space-4);
}

.toolbar__field {
  flex: 1 1 12rem;
  min-inline-size: 10rem;
}

/* --- Abschnitt mit Überschrift -------------------------------------------- */
.section__title {
  font-size: var(--font-size-body);
  margin-block-end: var(--space-3);
}

/* --- Layout-Feinheiten ---------------------------------------------------- */
.layout__sidebar {
  position: sticky;
  inset-block-start: 0;
  block-size: 100vh;
  overflow-y: auto;
}

.nav__footer {
  margin-block-start: auto;
  padding-block-start: var(--space-4);
}

.sidebar--flex {
  display: flex;
  flex-direction: column;
}

.table--rows td {
  font-weight: 400;
}

.table__actions {
  white-space: nowrap;
}

.text-quiet {
  color: var(--zone-text-quiet);
  font-size: var(--font-size-small);
}

/* --- Chips in einer Reihe --------------------------------------------------- */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* --- Legende unter der Matrix ---------------------------------------------- */
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  font-size: var(--font-size-small);
  color: var(--zone-text-quiet);
}

.legend__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* --- Antwortauswahl in der eigenen Matrixzeile ----------------------------- */
.table__select {
  min-inline-size: 8rem;
}

/* --- Kopfzeile mit Status ---------------------------------------------------- */
.header__meta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-inline-start: var(--space-2);
  vertical-align: middle;
}

/* --- Liste von Spielrunden ----------------------------------------------------- */

/* --- Plätze in einer Runde ------------------------------------------------- *
 * Gefüllte Figur heisst besetzt, offene heisst gesucht. Vorläufig /
 * außerhalb Kern-Inventar, abgeleitet aus der Avatar-Reihe.                  */
.slots {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* Die Figuren stehen dicht an dicht — eine Reihe, keine Kette aus Einzelnen. */
.slots__icons {
  display: inline-flex;
  align-items: center;
}

.slots__icon--taken {
  color: var(--zone-text-strong);
}

/* Offene Plätze treten zurück, bleiben aber deutlich erkennbar: Der
   Unterschied liegt in Füllung UND Farbe, nie in der Farbe allein (FE-33). */
.slots__icon--open {
  color: var(--zone-text-quiet);
}

.slots__extra {
  margin-inline-start: var(--space-1);
  font-size: var(--font-size-small);
  font-weight: 700;
  color: var(--zone-text-quiet);
}

/* Kurzform „1/4" mit einer Figur davor — sagt, worum es geht, ohne Reihe. */
.slots__label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--font-size-small);
  font-weight: 700;
}

/* --- Panel mit den besten Treffern ---------------------------------------- */
.match {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-2);
}

.match + .match {
  border-block-start: var(--border-hairline) solid var(--zone-border);
}

.match__body {
  flex: 1 1 16rem;
  min-inline-size: 0;
}

.match__title {
  font-weight: 700;
}

/* --- Vollständig besetzt --------------------------------------------------- *
 * Zurückgenommen, aber lesbar: Die Karte wird blasser, der Text behält seinen
 * Kontrast. Dass die Runde voll ist, steht zusätzlich als Pille daneben —
 * nie nur über die Farbe (FE-33).                                            */
.card--muted {
  background: var(--bg-region);
}

.card--muted .card__title,
.card--muted .chip {
  opacity: 0.75;
}

/* --- Marke an der Ecke einer Karte ---------------------------------------- *
 * Für Hinweise, die beim Überfliegen sofort auffallen sollen — etwa einen
 * Serientermin. Die Karte reserviert oben rechts Platz, damit die Marke den
 * Titel nicht überdeckt.                                                     */
.card--marked {
  position: relative;
  padding-inline-end: var(--space-6);
}

.card__badge {
  position: absolute;
  inset-block-start: var(--space-3);
  inset-inline-end: var(--space-3);
}

/* --- Symbolmarke an der Ecke ---------------------------------------------- *
 * Nur das Zeichen, kein Text: An der Ecke einer Karte würde eine Beschriftung
 * den Inhalt überdecken. Die Textfassung steht für Screenreader daneben.     */
.badge-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--size-chip);
  block-size: var(--size-chip);
  border-radius: var(--radius-full);
  color: var(--zone-carrier-text);
  background: var(--zone-carrier-bg);
  border: var(--border-hairline) solid var(--zone-border);
}

/* --- Karte für heute ------------------------------------------------------- *
 * Die Fläche wechselt auf das Signaturgrün. Weil die Zone mitwechselt, passen
 * Text und Ränder darin ohne eine einzige zusätzliche Regel (FE-13).         */
.card--today {
  background: var(--zone-surface);
  border-color: var(--zone-border);
}

/* --- Raster der Startseite ------------------------------------------------ *
 * So viele Spalten, wie Karten von mindestens --size-card-min hineinpassen,
 * höchstens vier: Der innere max() hält jede Spalte auf mindestens ein
 * Viertel der Breite (abzüglich drei Lücken). Auf dem Handy, wo die Breite
 * unter das Minimum fällt, nimmt min() die volle Breite — eine Spalte.      */
.matches {
  --matches-column-min: max(
    min(var(--size-card-min), 100%),
    calc((100% - 3 * var(--space-4)) / 4)
  );

  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--matches-column-min), 1fr));
  grid-auto-rows: 1fr;
  align-items: stretch;
  gap: var(--space-4);
  overflow: visible;
}

/* Kein z-index und damit kein eigener Stapelkontext: So liegt jeder Tooltip
   aus einer Karte über allen Nachbarkarten, auch über den späteren.        */
.card--listing {
  position: relative;
  display: flex;
  flex-direction: column;
  min-block-size: 100%;
  overflow: visible;
}

/* --- Gesuchskarte ----------------------------------------------------------- *
 * Bewusst anders als die Karte einer Spielrunde (Issue #17). Eine Spielrunde
 * ist ein Ereignis: Ort, Termin, Programm — der Gastgeber ist eine
 * Nebenangabe. Ein Gesuch ist das Gegenteil: EINE PERSON SUCHT ANSCHLUSS.
 * Deshalb steht die Person oben, der offene Bedarf ist die erste Zahl, und die
 * Angaben stehen als Beschreibungsliste statt als Kopfzeile über einem
 * Coverstreifen.
 *
 * Eine Kante links trug den Unterschied früher zusätzlich; sie ist seit
 * Issue #66 weg. FE-33 bleibt gewahrt, weil der Aufbau selbst unterscheidet:
 * Person oben, offener Bedarf als erste Zahl, Angaben als Liste — nichts
 * davon hängt an einer Farbe.                                               */
.seeking-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-block-size: 100%;
}

.seeking-card__head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
}

.seeking-card__head > .person-line {
  flex: 1;
  min-inline-size: 0;
}

/* Die erste Zahl auf der Karte: warum es dieses Gesuch gibt. */
.seeking-card__need {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
  text-align: end;
  color: var(--zone-text-strong);
}

.seeking-card__party {
  font-size: var(--font-size-chip);
  color: var(--zone-text-quiet);
  font-variant-numeric: tabular-nums;
}

.seeking-card__title {
  font-size: var(--font-size-body);
  font-weight: 700;
}

.seeking-card__title > a {
  color: inherit;
  text-decoration: none;
}

.seeking-card__title > a:hover {
  text-decoration: underline;
}

/* Symbol links, Angabe rechts — eine Zeile je Tatsache. Das Symbol trägt die
   Bedeutung nicht allein: Daneben steht sie versteckt im Text (FE-24). */
.seeking-card__facts {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-2) var(--space-3);
  margin: 0;
  font-size: var(--font-size-small);
}

.seeking-card__facts > dt {
  color: var(--zone-text-quiet);
}

.seeking-card__facts > dd {
  margin: 0;
  min-inline-size: 0;
}

.seeking-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-block-start: auto;
  padding-block-start: var(--space-3);
  border-block-start: var(--border-hairline) solid var(--zone-border);
  font-size: var(--font-size-small);
}

/* Der Ablaufhinweis bricht nicht mitten im Wort um — lieber die ganze Zeile
   umbrechen lassen. */
.seeking-card__foot > .text-quiet {
  white-space: nowrap;
}

/* „Noch einer gesucht" steht links vom Knopf statt oben in der Ecke: Dort
   wird entschieden, ob man sich meldet, und dort gehoert die Zahl hin.
   Waagerecht statt untereinander, damit sie eine Zeile bleibt. */
.seeking-card__need--inline {
  flex-direction: row;
  align-items: baseline;
  gap: var(--space-2);
  text-align: start;
  white-space: nowrap;
}

/* Bild links, Formular rechts — bei schmalen Bildschirmen untereinander. */
.avatar-edit {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-4);
}

/* Grösser als in Listen: Hier sieht man nach, ob das Bild taugt.
   Die Stilschicht hat die Grösse schon, wir setzen nur die Variable um. */
.avatar-edit .avatar {
  --size-avatar: var(--size-avatar-xl);
  font-size: var(--font-size-h3);
}

.avatar-edit > .stack {
  flex: 1 1 16rem;
}

/* Wer sucht, steht bei den Tatsachen und nicht im Kopf — kleiner als der Rest
   der Karte, weil die Runde zaehlt und nicht, wer sie ausrichtet. */
.seeking-card__host {
  font-size: var(--font-size-small);
}

/* **Der Knopf sitzt rechts, egal welcher es ist.** Je Richtung gibt es nur
   einen — „Anfragen" bei einer Runde, die Mitspieler sucht, „Einladen" bei
   einer Person, die Anschluss sucht. Beide stehen an derselben Stelle, damit
   das Auge ihn nicht suchen muss, wenn die Karten untereinander stehen. */
.seeking-card__second,
.seeking-card__actions {
  display: flex;
  gap: var(--space-2);
  margin-inline-start: auto;
}

/* Die Seitenzahlen rücken vom Raster ab — mehr als der Stapelabstand. */
.matches + nav {
  margin-block-start: var(--space-4);
}

/* Angaben oben, darunter der Titel, dann die Linie zu den Spielen. */
.card__intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-block-end: var(--space-2);
  border-block-end: var(--border-hairline) solid var(--zone-border);
}

.card__intro .card__title {
  margin: 0;
}

.card__intro .card__title a {
  color: inherit;
  text-decoration: none;
}

/* Je Angabe ein Badge (Issue #70). Sie tragen ihre Schrift und ihren Ton
   selbst — hier steht nur, wie sie sich reihen. Die Mittelpunkte dazwischen
   sind damit weg: Ein Badge grenzt sich selbst ab.                         */
.card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* Der Titel steht oben — sichtbar wie im Markup.
   Vorher zog `order: -1` die Angaben darüber. Das war für den Sprung per
   Überschrift gedacht, drehte aber die Leserichtung um: Man sah erst Datum und
   Ort und musste raten, wozu sie gehören. Der Titel sagt, worum es geht; alles
   andere ist seine Beschreibung. */

/* Die Personenzeile selbst steht in der Stilschicht (components.css,
   „Personenzeile"). Hier steht nur, wie sie sich in unsere Karten fügt. */

/* Name, Plätze und Melde-Knopf stehen in einer Zeile am unteren Rand. */
.card__end {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-block-start: auto;
}

/* --- Aktionen am Fuss einer Karte ------------------------------------------ *
 * Autor links, Anzahl und Knopf zusammen rechts. Der Name weicht mit
 * Auslassung.                                                              */
.card--listing .card__foot {
  margin-block-start: 0;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--space-3);
}

/* Nicht wachsen: Der Tooltip zentriert sich auf das details, und das soll
   so breit sein wie Avatar und Name, nicht wie die halbe Zeile. Ein langer
   Name schrumpft bis auf 5rem.                                             */
.card--listing .card__foot .person-line {
  flex: 0 1 auto;
  min-inline-size: 5rem;
}

/* Der Auto-Rand schiebt Plätze und Knopf gemeinsam an den rechten Rand. */
.card--listing .card__foot .slots {
  margin-inline-start: auto;
}

.card--listing .card__foot .person-line > summary {
  min-inline-size: 0;
  max-inline-size: 100%;
}

/* In der engen Zeile reicht die Zahl — die Figuren würden den Namen verdrängen. */
.card--listing .card__foot .slots__icons {
  display: none;
}

.card--listing .card__foot .slots,
.card--listing .card__foot .card__actions {
  flex: none;
}

.card__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex: none;
  padding-block-start: 0;
}

/* --- Vollständig besetzt --------------------------------------------------- *
 * Deutlicher als nur blass: eine farbige Kante an der Seite, dazu die Pille
 * im Warnton. Beides zusammen, nie die Farbe allein (FE-33).                 */
.card--full {
  border-color: var(--border-error);
  border-inline-start-width: var(--border-indicator);
  background: var(--bg-region);
}

/* --- Spielcover in Listen ------------------------------------------------- *
 * Quadratische Kachel plus Name darunter. Ohne Bilddatenbank trägt `.tile`
 * das Würfel-Zeichen — dieselbe Lücke wie im Styleguide.                     */
.covers {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.cover-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  min-inline-size: 0;
  max-inline-size: 100%;
}

.cover-item__tip {
  display: flex;
  flex-direction: column;
  align-items: center;
  inline-size: 100%;
  max-inline-size: 100%;
}

.cover-item__tip > summary {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: inherit;
  inline-size: 100%;
  min-inline-size: 0;
  max-inline-size: 100%;
}

.cover-item__name {
  inline-size: 100%;
  min-inline-size: 0;
  max-inline-size: 100%;
  font-size: var(--font-size-chip);
  line-height: 1.2;
  color: var(--zone-text-strong);
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cover-item__link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: inherit;
  inline-size: 100%;
  min-inline-size: 0;
  max-inline-size: 100%;
  color: inherit;
  text-decoration: none;
}

.game-catalog {
  margin: 0;
  padding: 0;
  list-style: none;
}

.game-catalog__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-2);
  color: inherit;
  text-decoration: none;
  border-block-end: var(--border-hairline) solid var(--zone-border);
}

.game-catalog__item:hover {
  color: var(--zone-text-strong);
}

.game-detail {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: start;
}

.game-detail__cover {
  inline-size: 12rem;
  block-size: 12rem;
  flex: none;
}

/* --- Was auf dich wartet --------------------------------------------------- *
 * Eine Liste von Wegen, jeder mit einer Zahl am Ende. Keine Kacheln: Eine Zahl
 * ohne Weg ist eine Anzeige, und eine Anzeige kann man nicht abarbeiten.      */
.todos {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: 0;
  margin: 0;
  list-style: none;
}

.todos__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--size-target-min);
  padding-inline: var(--space-3);
  border-radius: var(--radius-control);
  background: var(--zone-card-bg);
  border: var(--border-hairline) solid var(--border-panel);
  color: var(--zone-text-strong);
  text-decoration: none;
}

.todos__item:hover {
  border-color: var(--zone-border-interactive);
}

/* Der Text nimmt den Platz, die Zahl und der Pfeil bleiben rechts. */
.todos__text {
  flex: 1;
  min-inline-size: 0;
}

/* Der Pfeil ist der leise Teil — er sagt nur, dass es weitergeht. */
.todos__item > .icon:last-child {
  color: var(--zone-text-quiet);
}

/* --- Rangliste am Ort ------------------------------------------------------ *
 * Platz, Person, Zahl. Der eigene Eintrag hebt sich ab — wer eine Liste liest,
 * sucht zuerst sich selbst. Er trägt zusätzlich die kräftige Kante links, denn
 * eine Fläche allein ist Farbe allein (FE-33).                               */
.ranking {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: 0;
  margin: 0;
  list-style: none;
  counter-reset: none;
}

.ranking__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-block-size: var(--size-target-min);
  padding-inline: var(--space-3);
  border: var(--border-hairline) solid var(--border-panel);
  border-radius: var(--radius-control);
  background: var(--zone-card-bg);
}

.ranking__row[aria-current] {
  background: var(--zone-surface);
  border-inline-start-width: var(--border-indicator);
  border-inline-start-color: var(--zone-text-strong);
  font-weight: 700;
}

/* --- Chartzeile --------------------------------------------------------------- *
 * Dieselbe Zeile wie die Rangliste am Ort — nur stehen hier Titel statt
 * Personen (§ 0.4). Links der Name, rechts die Note mit ihrer Grundlage.     */
.chart__game {
  flex: 1;
  min-inline-size: 0;
}

.chart__game > a {
  color: inherit;
  font-weight: 700;
  text-decoration: none;
}

.chart__game > a:hover {
  text-decoration: underline;
}

.chart__score {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
  font-variant-numeric: tabular-nums;
}

.chart__score > .text-quiet {
  font-size: var(--font-size-chip);
}

/* Die Platzziffer hat feste Breite, damit die Namen untereinander beginnen. */
.ranking__place {
  flex: none;
  min-inline-size: var(--size-rank-place);
  color: var(--zone-text-quiet);
  font-variant-numeric: tabular-nums;
  text-align: end;
}

.ranking__row > .person-line {
  flex: 1;
  min-inline-size: 0;
}

/* --- Profil einer Person --------------------------------------------------- *
 * Kopf: Bild mit Wappen links, Name, Rang und Note rechts daneben. Am Handy
 * untereinander — 96 px Bild und ein Name passen dort nicht in eine Zeile.
 * Was hier steht, entscheidet `loadPublicProfile`, nicht die Fläche.        */
.profile__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
}

/* Die Angaben als Paare: Beschriftung klein darüber, Wert darunter. Sie
   ordnen sich in Spalten, solange Platz ist — eine lange Liste untereinander
   liest sich bei vier Angaben schlechter als drei nebeneinander. */
.profile__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--size-fact-min), 1fr));
  gap: var(--space-4);
  margin: 0;
}

.profile__facts dt {
  color: var(--zone-text-quiet);
  font-size: var(--font-size-chip);
}

.profile__facts dd {
  margin: 0;
}

/* Kommende Spielrunden: je eine Zeile, die ganze Zeile ist der Weg. */
.profile__gatherings {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

.profile__gathering {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-block-size: var(--size-target-min);
  padding-inline: var(--space-3);
  border-radius: var(--radius-control);
  color: var(--zone-text-strong);
  text-decoration: none;
}

.profile__gathering:hover {
  background: var(--bg-sunken);
}

/* Der Rang steht unter dem Bild als Aussage, nicht als Beizeile — er ist das
   Einzige, was neben dem Namen über die Person gesagt wird. */
.profile__rank {
  margin: 0;
  font-weight: 700;
}

/*
 * QR-Code zum Einrichten des zweiten Faktors (Issue #20). Der Code trägt
 * seine Farben im SVG — feste, nicht zonenabhängige: Ein Lesegerät braucht
 * vollen Kontrast. Die weisse Fläche ringsum gehört zum Code, ohne sie
 * erkennt ihn keine Kamera zuverlässig.
 */
.qr-code {
  inline-size: var(--size-qr);
  max-inline-size: 100%;
  background: var(--on-fixed-white-surface);
  border-radius: var(--radius-card);
  padding: var(--space-2);
}

.qr-code > svg {
  display: block;
  inline-size: 100%;
  block-size: auto;
}
