/* ==========================================================================
   HINWEIS: Alle Regeln für Spiel-Bildschirme sind auf #game-view begrenzt.
   Die Hülle (Kopfzeile, Startseite, Katalog, Fußzeile) kommt aus dem
   Rivalz-Design in rivalz-*.css und darf hiervon nicht überschrieben
   werden. Global bleiben nur :root, Keyframes und die Bühnen-Regeln.
   ========================================================================== */

:root {
  /* ==========================================================================
     Rivalz-Palette — Pitch Lime auf Tiefschwarz.

     Die Namen stammen aus dem hellen Ursprungsdesign und bleiben absichtlich
     erhalten: 280 Verwendungen im Stylesheet greifen darauf zu. Geändert
     wurden nur die Werte.

     Wichtig zum Verständnis: --ink heißt "maximaler Kontrast zur Seite".
     Im hellen Design war das Fast-Schwarz, hier ist es Fast-Weiß. Flächen,
     die --ink/--violet/--orange als Hintergrund nutzen, tragen deshalb
     dunkle Schrift (--on-solid) statt der früheren weißen.
     ========================================================================== */
  --ease-kinetic: cubic-bezier(0.16, 1, 0.3, 1);

  --ink: #EEF3F0;            /* war #020204 — jetzt die Kontrastfarbe im Dunkeln */
  --on-solid: #080C0A;       /* neu: Schrift auf hellen/farbigen Flächen */

  --bg: #0F1613;             /* war #EFEFF2; bis 30.09.2026 #080C0A */
  --card: #19221E;           /* war #FFFFFF; bis 30.09.2026 #111815 */
  --panel: #202A25;          /* war #F5F4F8; bis 30.09.2026 #172019 */

  --violet: #00E57A;         /* Markenfarbe — war #522EDE */
  --violet-deep: #00C96B;    /* war #2710EB */
  --orange: #FFC53D;         /* Zweitakzent — war #EA4F23 */

  --text: #EEF3F0;           /* war #16151B */
  --muted: #A6B2AB;          /* war #6E6A7A */
  --line: rgba(255, 255, 255, 0.10);   /* war rgba(2,2,4,.09) */

  --correct: #00C96B;        /* war #17A65A */
  --present: #FFC53D;        /* war #E9A23B */
  --absent: #47534D;         /* war #A6A3B0 */

  /* Dieselben Markenfarben noch einmal als RGB-Tripel. Grund: rund 30 Regeln
     brauchen die Marke als durchscheinende Toenung, und rgba() kann keine
     Hex-Variable aufnehmen. Genau deshalb hat der Rebrand sie verfehlt --
     die Werte oben wurden getauscht, die rgba()-Literale blieben auf der
     alten Palette stehen (Lime-Schrift auf violettem Grund). Wer die Marke
     aendert, aendert beides; die Tripel gehoeren neben ihre Hex-Zwillinge. */
  --violet-rgb: 0, 229, 122;        /* = --violet      #00E57A */
  --violet-deep-rgb: 0, 201, 107;   /* = --violet-deep #00C96B */
  --orange-rgb: 255, 197, 61;       /* = --orange      #FFC53D */

  --bronze: #C07B5C;
  --silver: #A49BA4;
  --gold: #FFC53D;
}

/* ==========================================================================
   Dieselbe Palette fuer den hellen Modus

   WARUM DAS GEFEHLT HAT. Die Palette oben steht auf :root und schaltet nicht
   um — sie wurde beim Rebrand von hell auf dunkel gebracht, indem die WERTE
   getauscht wurden (die Kommentare sagen es: "war #FFFFFF"). Die Huelle
   (rivalz-*.css) arbeitet dagegen mit Themen-Tokens und schaltet sehr wohl.
   Ergebnis: Wer sein System auf hell stehen hat — und das ist die Vorgabe,
   Dunkel kommt erst ueber prefers-color-scheme — bekam eine helle Huelle mit
   fast schwarzen Spielflaechen darin. Gemessen: --card und --panel lagen in
   BEIDEN Themen bei einer Helligkeit von 0,008 beziehungsweise 0,013.

   Die Werte sind keine Erfindung, sondern die des urspruenglichen hellen
   Designs — sie stehen als "war ..." in den Kommentaren oben und werden hier
   wieder eingesetzt.

   ZWEI STELLEN SIND KEINE RUECKKEHR, sondern neu:

   --violet ist die Marke und bleibt in beiden Themen Lime. Als FLAECHE ist
   das richtig, als SCHRIFT auf Weiss aber unlesbar (Kontrast 1,8). Deshalb
   traegt der helle Modus einen dunkleren Lime-Ton fuer Schrift; dieselbe
   Ueberlegung wie bei --color-primary-text in rivalz-tokens.css.

   --on-solid bleibt dunkel. Lime und Gold sind in beiden Themen helle
   Flaechen, die Schrift darauf muss also dunkel bleiben — hier waere ein
   Umschalten der Fehler.

   Beide Bloecke, damit ein ausdrueckliches data-theme in JEDE Richtung
   gewinnt: prefers-color-scheme allein wuerde den Umschalter in der Kopfzeile
   uebergehen.
   ========================================================================== */
:root[data-theme='light'] {
  /* WARMES PAPIER, dieselben Werte wie --paper-* in rivalz-tokens.css.

     Die Spielflaechen liegen in derselben Seite wie die Huelle; zwei
     verschiedene Weisstoene nebeneinander — hier ein blaustichiges #E7E7EC,
     dort ein warmes #F3EFE6 — saehen aus wie zwei Anwendungen. Die Palette
     hier bleibt eigenstaendig (sie ist aelter und traegt Spielbegriffe wie
     --absent), aber ihre Neutraltoene kommen jetzt aus derselben Familie.

     Gemessen: Karte gegen Grund 1,15 · --muted gegen die Karte 8,07 ·
     --text gegen die Karte 18,8. */
  --ink: #14110D;
  --bg: #F3EFE6;
  --card: #FFFFFF;
  /* Deutlich tiefer als der Grund, nicht dazwischen. Gemessen hob sich
     --panel im dunklen Thema mit 1,18 vom Grund ab, im hellen nur mit 1,05 —
     Zeilen, die direkt auf der Seite liegen (Profil, Rangreihen), sahen
     deshalb aus wie gar nichts. Jetzt 1,13 gegen den Grund und 1,29 gegen
     die weisse Karte; derselbe Ton wie --color-bg-inset in der Huelle. */
  --panel: #E8E2D5;
  --text: #14110D;
  --muted: #574F42;
  --line: rgba(38, 33, 25, 0.14);
  --absent: #A9A18E;
  /* Marke als SCHRIFT auf hellem Grund — die Flaechenfarbe bleibt --violet.
     lime-700, gemessen 4,72 gegen die weisse Karte. */
  --violet-text: #026639;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --ink: #14110D;
    --bg: #F3EFE6;
    --card: #FFFFFF;
    --panel: #E8E2D5;
    --text: #14110D;
    --muted: #574F42;
    --line: rgba(38, 33, 25, 0.14);
    --absent: #A9A18E;
    --violet-text: #026639;
  }
}

/* Im dunklen Modus ist die Marke als Schrift unproblematisch — dort ist
   --violet-text schlicht --violet. Einmal als Vorgabe, damit Regeln, die die
   Variable benutzen, in beiden Themen etwas finden. */
/* Schrift auf einer --ink-Flaeche.

   --on-solid kann das NICHT leisten, und der Unterschied ist der Kern des
   Problems: --violet und --orange sind in beiden Themen helle Flaechen, die
   Schrift darauf muss also immer dunkel sein. --ink dagegen heisst
   "maximaler Kontrast zur Seite" und kippt mit dem Thema — im Dunkeln
   Fast-Weiss, im Hellen Fast-Schwarz. Eine Variable fuer beides ergab im
   hellen Modus Dunkel auf Dunkel: der aktive Modus-Knopf war unlesbar
   (gemessen: Kontrast 1,1). */
/* SIGNALFARBEN HABEN ZWEI ROLLEN, und im hellen Thema muessen die auseinander.

   Als FLAECHE ist Lime richtig, wie es ist: ein leuchtender Knopf mit dunkler
   Schrift darauf. Als SCHRIFT auf einer hellen Karte ist derselbe Ton
   unlesbar — gemessen 1,68 gegen Weiss, Gold sogar 1,58. Und genau so wurde
   er benutzt: 57 Regeln setzten `color: var(--violet-text)`, 25 `var(--orange)`,
   12 `var(--correct)`. Fast hundert Stellen, an denen im hellen Modus Text
   stand, den man nicht lesen konnte.

   Deshalb fuer jede Signalfarbe eine zweite Fassung. Im dunklen Thema ist sie
   die Farbe selbst — dort leuchtet beides richtig. Im hellen ist sie die
   tiefe Variante. Wer eine Signalfarbe als SCHRIFT einsetzt, nimmt ab jetzt
   die -text-Fassung; als Flaeche bleibt es beim Original.

   Gemessen auf der weissen Karte / auf dem Papier:
   Wie tief, entscheidet die DUNKELSTE helle Flaeche (--panel #E8E2D5), nicht
   die weisse Karte. Gemessen Karte / Papier / Panel:
     violet-text  #026639  7,09 / 6,18 / 5,49   correct-text #096634  7,09 / 6,18 / 5,49
     orange-text  #7A5303  6,85 / 5,97 / 5,31   present-text #6E5400  7,16 / 6,24 / 5,55
     rot-text     #A11430  7,90 / 6,88 / 6,12   warn-text    #8A3E00  7,58 / 6,61 / 5,87
     bronze-text  #7A4530  7,72 / 6,72 / 5,98   silver-text  #5C5760  7,03 / 6,13 / 5,45 */
:root {
  --violet-text: var(--violet);
  --orange-text: var(--orange);
  /* Drei fast gleiche helle Rottoene standen als rohe Hex-Werte im Blatt
     (#FF6B85, #ff6b6b, #ff7a6b) — Fehlermeldung, verlorener Lauf,
     Fotofinish. Auf Weiss lagen sie bei 2,7 bis 2,8. Ein Token statt drei
     Schreibweisen; im dunklen Thema bleibt es der bisherige Ton.

     ACHTUNG, hier stand kurzzeitig `--rot-text: var(--rot-text)`: Die
     Ersetzung der rohen Hex-Werte lief ueber ihre eigene Definition. Eine
     Eigenschaft, die sich selbst zuweist, ist ungueltig und faellt auf
     nichts zurueck — im hellen Thema fiel es nicht auf, weil der Block
     darunter sie neu setzt, im dunklen war die Schrift dann farblos. */
  --rot-text: #FF6B85;
  --warn-text: #FF9A4D;
  --correct-text: var(--correct);
  --present-text: var(--present);
  --bronze-text: var(--bronze);
  --silver-text: var(--silver);
  --gold-text: var(--gold);
  --on-ink: #080C0A;
}
:root[data-theme='light'] {
  --on-ink: #FFFFFF;
  --rot-text:     #A11430;
  --warn-text:    #8A3E00;
  --gold-text:    #7A5303;
  --orange-text:  #7A5303;
  --correct-text: #096634;
  --present-text: #6E5400;
  --bronze-text:  #7A4530;
  --silver-text:  #5C5760;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --on-ink: #FFFFFF;
    --rot-text:     #A11430;
    --warn-text:    #8A3E00;
    --gold-text:    #7A5303;
    --orange-text:  #7A5303;
    --correct-text: #096634;
    --present-text: #6E5400;
    --bronze-text:  #7A4530;
    --silver-text:  #5C5760;
  }
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) { --on-ink: #FFFFFF; }
}* { box-sizing: border-box; }html { scroll-behavior: smooth; }
/* Seitengrund und Textfarbe kommen aus den Themen-Tokens, NICHT aus der
   Palette oben.
   Vorher stand hier "background: var(--bg)" mit dem fest dunklen Wert aus
   :root. Weil styles.css nach rivalz-base.css geladen wird, gewann diese
   Zeile — der helle Modus hat den Seitenhintergrund deshalb nie erreicht.
   Sichtbar wurde das erst, seit Karten und Rahmen die Token benutzen: weisse
   Kacheln auf schwarzem Grund. Der Dateikopf verlangt ohnehin, dass die
   Huelle aus den rivalz-*.css kommt; diese Zeile widersprach ihm. */
body {
  margin: 0;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--color-bg);
  color: var(--color-fg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
}
/* Die Spielflaeche bleibt in beiden Themen dunkel. Das ist Absicht und keine
   vergessene Ecke: Die Spiele sind auf Tiefschwarz entworfen (Lebensherzen,
   Fotofinish-Blitzen, Konfetti, die Farbverlaeufe der Kacheln), und 280
   Regeln greifen auf die Palette --bg/--card/--panel/--text zu. Ein heller
   Spielbildschirm waere kein Umschalten, sondern ein zweites Design.
   Die Huelle darum herum folgt dem Thema. */
body.im-spiel { background: var(--bg); color: var(--text); }
#game-view { background: var(--bg); color: var(--text); }

/* Namenskollision, die erst im hellen Thema auffiel: Die Spiele benutzen
   class="card" — dieselbe Klasse wie die Katalogkacheln der Huelle. Deren
   Regel in rivalz-components.css setzt "background: var(--color-surface)".
   Im dunklen Thema ist das zufaellig fast dieselbe Farbe wie --card, im
   hellen wird die Flaeche weiss, waehrend die Schrift aus --text hell bleibt:
   Weiss auf Weiss.
   Der Dateikopf verlangt ohnehin, dass Spielregeln auf #game-view begrenzt
   sind; die hoehere Spezifitaet holt die Spielkarte hier zurueck. */
#game-view .card {
  background: var(--card);
  color: var(--text);
  border-color: var(--line);
}

/* UND DIE KACHEL-BEWEGUNGEN GEHOEREN AUCH NICHT HIERHER.

   Gemeldet, zweimal: "Im Spiel Abseits wackelt bzw. bewegt sich der
   Bildschirm immer ein bisschen, wenn man draufklickt." Beim ersten Mal war
   die Bildlaufleiste schuld (siehe scrollbar-gutter in rivalz-base.css) —
   das war echt und behoben, aber es war nur die Haelfte.

   Die andere Haelfte ist dieselbe Klassenkollision, die den Block darueber
   noetig gemacht hat. `.card` ist die KATALOGKACHEL: Sie hebt sich beim
   Ueberfahren um fuenf Pixel und sackt beim Druecken auf translateY(-1px)
   scale(0.99). Fuer eine Kachel von 260 Pixeln ist das die richtige
   Rueckmeldung.

   Abseits baut seinen ganzen Spielbildschirm aus dieser Klasse. Gemessen:
   912 x 877 Pixel. scale(0.99) verschiebt die Kanten dort um gut vier Pixel,
   und der Schweberuck kommt schon beim blossen Darueberfahren dazu — bei
   JEDEM Klick, weil man zum Klicken darauf zeigt.

   Ein Spielbildschirm ist keine Kachel. Er hebt sich nicht, und er federt
   nicht. Was die Knoepfe darin tun, bleibt unberuehrt: Die tragen ihre
   eigene Rueckmeldung, und die ist an ihrer Groesse richtig.

   NUR UNTER #game-view. Die echten Kacheln stehen im Katalog und behalten
   alles. */
#game-view .card:hover,
#game-view .card:active {
  transform: none;
}

/* Die Leiste im Spiel gehoert zur Spielflaeche, nicht zur Huelle. Sie holte
   sich ihren Grund aus --color-bg (Themen-Token) und ihre Schrift aus --text
   (Spielpalette) — im hellen Thema also Weiss auf Weiss. */
#game-view .spielleiste {
  background: var(--bg);
  border-bottom-color: var(--line);
}/* Grain-Overlay für Textur (avexa-Referenz) */
#game-view body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='140'%20height='140'%3E%3Cfilter%20id='n'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.85'%20numOctaves='2'/%3E%3C/filter%3E%3Crect%20width='100%25'%20height='100%25'%20filter='url(%23n)'/%3E%3C/svg%3E");
}::selection { background: var(--color-primary); color: var(--color-on-primary); }#game-view :focus-visible {
  outline: 2px solid var(--violet);
  outline-offset: 2px;
}
/* Auch die Bildlaufleiste gehoert zur Huelle. Mit dem festen --bg blieb im
   hellen Modus ein dunkler Streifen am Rand stehen. */
::-webkit-scrollbar { width: 10px; }::-webkit-scrollbar-track { background: var(--color-bg); }::-webkit-scrollbar-thumb {
  background: var(--color-border-strong);
  border-radius: 8px;
  border: 2px solid var(--color-bg);
}::-webkit-scrollbar-thumb:hover { background: var(--color-fg-subtle); }/* ---------- Topbar ---------- */
#game-view .topbar {
  background: var(--card);
  border-bottom: 1px solid var(--line);
  padding: 18px 24px;
}#game-view .topbar-inner {
  max-width: 960px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 14px;
}#game-view .brand-row { display: flex; align-items: center; justify-content: space-between; }#game-view .lang-switch {
  display: inline-flex;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}#game-view .lang-btn {
  border: none;
  background: none;
  font-family: inherit;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--muted);
  padding: 6px 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}#game-view .lang-btn:hover { color: var(--ink); }#game-view .lang-btn.active { background: var(--ink); color: var(--on-ink); }#game-view .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  color: var(--ink);
  text-transform: lowercase;
}#game-view .logo-mark {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--violet);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}#game-view .logo-mark svg { width: 22px; height: 22px; display: block; }#game-view .tag {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--ink);
  color: var(--on-solid);
  padding: 4px 10px;
  border-radius: 999px;
  vertical-align: middle;
  margin-left: 8px;
}/* Profil-Leiste */
.profile-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 10px 14px;
}.avatar-wrap { position: relative; flex-shrink: 0; cursor: pointer; }.avatar {
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--card);
  border: 3px solid var(--violet-text);
  display: flex; align-items: center; justify-content: center;
  color: var(--violet-text);
}.avatar svg { width: 26px; height: 26px; }.level-badge {
  position: absolute; bottom: -4px; right: -6px;
  background: var(--orange);
  color: var(--on-solid);
  font-weight: 800;
  font-size: 0.68rem;
  min-width: 20px; height: 20px;
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--card);
  padding: 0 3px;
}#game-view .profile-info { flex: 1; min-width: 0; }.profile-name-row { display: flex; align-items: center; gap: 6px; cursor: pointer; }.profile-name { font-weight: 700; font-size: 0.98rem; color: var(--ink); }#game-view .profile-edit-hint { font-size: 0.7rem; color: var(--muted); }.xp-bar-track {
  background: var(--line);
  border-radius: 6px;
  height: 9px;
  width: 100%;
  max-width: 260px;
  overflow: hidden;
  margin-top: 5px;
}.xp-bar-fill {
  background: linear-gradient(90deg, var(--violet), var(--violet-deep));
  height: 100%;
  transition: width 0.5s ease;
}#game-view .xp-label { font-size: 0.68rem; color: var(--muted); margin-top: 2px; }.trophy-count {
  display: flex; align-items: center; gap: 6px;
  font-weight: 800;
  color: var(--orange-text);
  font-size: 1rem;
  flex-shrink: 0;
}.trophy-count svg { width: 19px; height: 19px; }
/* Kurzes Aufblitzen bei XP- und Levelgewinn. Galt nur unter #game-view — dort
   saß die alte Kopfleiste. Die Ziele stehen jetzt in der Profilkachel auf der
   Startseite, also global. Ohne diese Zeile bliebe die Klasse hängen: Ohne
   Animation feuert kein animationend, das sie wieder entfernt. */
.bump { animation: bumpPop 0.45s cubic-bezier(0.3, 1.6, 0.4, 1); }
.hub__big.bump, .hub__sub.bump { display: inline-block; }
@keyframes bumpPop {
  40% { transform: scale(1.25); }
  100% { transform: scale(1); }
}/* ---------- Layout ---------- */
/* Ursprünglich "main" — galt für Katalog und Spiel. Die Hülle bringt ihr
   eigenes Layout mit, deshalb gilt es jetzt nur noch für die Spielansicht.
   #game-view IST das main-Element, "#game-view main" träfe nichts. */
#game-view { flex: 1; padding: 32px 24px; max-width: 960px; margin: 0 auto; width: 100%; }.view { display: none; }
/* Sichtbarkeit darf NIE von einer Animation abhängen: Grundzustand ist sichtbar,
   die Animation blendet nur zusätzlich ein (kein fill-mode "both", sonst bleibt
   der Inhalt bei opacity 0 hängen, falls die Animation nicht sauber läuft). */
.view.active { display: block; opacity: 1; animation: fadeUp 0.4s cubic-bezier(0.2, 0.7, 0.2, 1); }

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}/* ---------- Hero ---------- */
#game-view .hero {
  position: relative;
  padding: 56px 0 48px;
}.hero::before {
  content: "";
  position: absolute;
  inset: -60px -100px 0;
  z-index: -1;
  background:
    radial-gradient(560px 300px at 18% 10%, rgba(var(--violet-rgb), 0.14), transparent 65%),
    radial-gradient(480px 260px at 85% 25%, rgba(var(--orange-rgb), 0.1), transparent 65%);
  pointer-events: none;
}.hero-dots {
  position: absolute;
  top: 40px; right: 0;
  width: 180px; height: 130px;
  background-image: radial-gradient(var(--ink) 1.3px, transparent 1.4px);
  background-size: 14px 14px;
  opacity: 0.12;
  -webkit-mask-image: radial-gradient(closest-side, #000, transparent);
  mask-image: radial-gradient(closest-side, #000, transparent);
  pointer-events: none;
}#game-view .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 18px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}#game-view .eyebrow-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--violet);
  animation: pulseDot 2s ease-in-out infinite;
}
@keyframes pulseDot {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--violet-rgb), 0.4); }
  50% { box-shadow: 0 0 0 6px rgba(var(--violet-rgb), 0); }
}.hero-title {
  display: flex;
  flex-direction: column;
  margin: 0 0 22px;
  font-size: clamp(2.8rem, 8vw, 4.8rem);
  font-weight: 900;
  letter-spacing: -0.05em;
  line-height: 0.98;
  color: var(--ink);
}#game-view .ht-line { display: block; }#game-view .ht-line.accent {
  font-style: italic;
  background: linear-gradient(100deg, var(--violet) 0%, var(--violet-deep) 45%, var(--orange) 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: hueSlide 6s ease-in-out infinite alternate;
}
@keyframes hueSlide {
  to { background-position: 100% 0; }
}.hero-sub {
  margin: 0 0 24px;
  max-width: 560px;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--muted);
}/* Driftende Streak-Textur (kontrollierte Bewegung) */
#game-view .hero.kinetic::after {
  content: "";
  position: absolute;
  inset: -30% -12% -10%;
  z-index: -1;
  pointer-events: none;
  background: repeating-linear-gradient(114deg, transparent 0 42px, rgba(var(--violet-rgb), 0.045) 42px 44px);
  animation: streakDrift 16s linear infinite;
}
@keyframes streakDrift {
  to { transform: translateX(88px); }
}/* ---------- Kinetic: Scroll-Reveal ---------- */
#game-view .reveal {
  opacity: 0;
  transform: translateY(42px);
  transition: opacity 0.7s var(--ease-kinetic), transform 0.7s var(--ease-kinetic);
  transition-delay: var(--d, 0s);
}#game-view .reveal.in { opacity: 1; transform: none; }#game-view .tile.reveal {
  opacity: 0;
  transform: translateY(42px);
  transition: transform 0.6s var(--ease-kinetic), opacity 0.6s var(--ease-kinetic), box-shadow 0.22s ease, border-color 0.18s ease;
  transition-delay: var(--d, 0s);
}#game-view .tile.reveal.in { opacity: 1; transform: none; }/* ---------- Kinetic: Scroll-Fortschritt ---------- */
#game-view .scroll-progress {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: linear-gradient(90deg, var(--violet), var(--violet-deep) 55%, var(--orange));
  z-index: 300;
  will-change: transform;
}/* ---------- Kinetic: Ticker-Leiste ---------- */
#game-view .ticker {
  width: 100vw;
  margin-left: calc(-50vw + 50%);
  overflow: hidden;
  /* Im hellen Ursprungsdesign war das ein schwarzes Band mit weißer Schrift.
     Umgekehrt wäre es hier ein grelles weißes Band mitten auf dunkler Seite —
     deshalb stattdessen ein ruhiges Band wie im Rivalz-Design. */
  background: var(--panel);
  color: var(--muted);
  border-block: 1px solid var(--line);
  padding: 15px 0;
  margin-top: 8px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}.ticker-track {
  display: flex;
  width: max-content;
  animation: marquee 24s linear infinite;
}.ticker-item {
  display: inline-flex;
  align-items: center;
  gap: 30px;
  padding-right: 30px;
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}.ticker-item .dot { color: var(--orange-text); font-size: 0.7rem; }
@keyframes marquee {
  to { transform: translateX(-50%); }
}.ticker:hover .ticker-track { animation-play-state: paused; }/* ---------- Katalog-Sektion ---------- */
#game-view .section-title {
  margin: 24px 0 6px;
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  color: var(--ink);
}#game-view .hint { color: var(--muted); margin-top: 0; margin-bottom: 20px; font-size: 0.95rem; }#game-view .pill-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 28px; }#game-view .pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.82rem;
  font-weight: 700;
  padding: 7px 16px;
  border-radius: 999px;
  background: var(--card);
  border: 1.5px solid var(--ink);
  color: var(--ink);
}#game-view .pill.violet { background: var(--violet); border-color: var(--violet); color: var(--on-solid); }#game-view .pill.orange { background: var(--orange); border-color: var(--orange); color: var(--on-solid); }/* ---------- Katalog ---------- */
#game-view .grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(150px, auto);
  grid-auto-flow: dense;
  gap: 16px;
  perspective: 1000px;
}#game-view .tile.featured {
  grid-column: span 2;
  grid-row: span 2;
  display: flex;
  flex-direction: column;
}#game-view .tile.featured .icon { width: 60px; height: 60px; font-size: 1.7rem; }#game-view .tile.featured h3 { font-size: 1.55rem; margin-top: 16px; }#game-view .tile.featured p { font-size: 0.98rem; max-width: 34ch; }#game-view .tile.featured .tile-stats { margin-top: auto; }#game-view .tile {
  background: var(--card);
  border-radius: 20px;
  padding: 20px;
  cursor: pointer;
  transition: transform 0.22s var(--ease-kinetic), box-shadow 0.22s ease, border-color 0.18s ease;
  border: 1px solid var(--line);
  position: relative;
  transform-style: preserve-3d;
  will-change: transform;
}#game-view .tile:hover {
  border-color: var(--violet-text);
  box-shadow: 0 18px 40px rgba(var(--violet-deep-rgb), 0.16);
}#game-view .tile.disabled { cursor: default; opacity: 0.55; }#game-view .tile.disabled:hover { transform: none; border-color: var(--line); box-shadow: none; }#game-view .tile.tier-bronze { border-bottom: 4px solid var(--bronze-text); }#game-view .tile.tier-silver { border-bottom: 4px solid var(--silver-text); }#game-view .tile.tier-gold { border-bottom: 4px solid var(--gold-text); }#game-view .tile .icon {
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel);
  border-radius: 14px;
  transition: transform 0.18s cubic-bezier(0.2, 0.7, 0.2, 1);
}#game-view .tile .icon svg { width: 24px; height: 24px; }#game-view .tile:hover .icon { transform: scale(1.08) rotate(-4deg); }#game-view .icon.tone-violet, #game-view .h2-icon.tone-violet { background: rgba(var(--violet-rgb), 0.1); color: var(--violet-text); }#game-view .icon.tone-orange, #game-view .h2-icon.tone-orange { background: rgba(var(--orange-rgb), 0.1); color: var(--orange-text); }#game-view .icon.tone-ink, #game-view .h2-icon.tone-ink { background: rgba(2, 2, 4, 0.06); color: var(--ink); }#game-view .tile h3 { margin: 12px 0 4px; font-size: 1.05rem; letter-spacing: -0.02em; color: var(--ink); }#game-view .tile p { margin: 0; font-size: 0.85rem; color: var(--muted); line-height: 1.45; }#game-view .tile .tile-stats {
  margin-top: 10px;
  font-size: 0.75rem;
  color: var(--violet-text);
  font-weight: 700;
}#game-view .badge {
  position: absolute;
  top: 14px; right: 14px;
  font-size: 0.65rem;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--violet);
  color: var(--on-solid);
  font-weight: 700;
  letter-spacing: 0.03em;
}#game-view .badge.soon { background: var(--panel); color: var(--muted); border: 1px solid var(--line); }#game-view .back-btn {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  margin-bottom: 16px;
  padding: 6px 0;
}#game-view .back-btn:hover { color: var(--ink); }#game-view .game-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 28px;
  animation: fadeUp 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}#game-view .game-card h2 { margin-top: 0; letter-spacing: -0.03em; color: var(--ink); }#game-view .game-h2 { display: flex; align-items: center; gap: 12px; }#game-view .h2-icon {
  width: 40px; height: 40px;
  border-radius: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}#game-view .h2-icon svg { width: 22px; height: 22px; }/* ---------- Wordle ---------- */
#game-view .wordle-row { display: flex; gap: 6px; margin-bottom: 8px; }#game-view .wordle-cell {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--line);
  border-radius: 10px;
  font-weight: 700;
  font-size: 1.1rem;
  text-transform: uppercase;
  transition: transform 0.25s ease;
  background: var(--card);
}#game-view .wordle-cell.correct { background: var(--correct); border-color: var(--correct); color: var(--on-solid); animation: flipIn 0.35s ease; }#game-view .wordle-cell.present { background: var(--present); border-color: var(--present); color: var(--on-solid); animation: flipIn 0.35s ease; }/* Einzige Ausnahme von --on-solid: --absent ist eine DUNKLE Fläche.
   Dunkle Schrift darauf käme auf 2,45:1 und wäre unlesbar; --text erreicht
   7,16:1. (Nachgerechnet am 10.09.2026 gegen die heutigen Werte —
   #47534D gegen #080C0A und #EEF3F0. Hier stand vorher 1,9:1, aus einer
   älteren Palette.) */
#game-view .wordle-cell.absent { background: var(--absent); border-color: var(--absent); color: var(--text); animation: flipIn 0.35s ease; }

@keyframes flipIn {
  from { transform: rotateX(90deg); }
  to { transform: rotateX(0deg); }
}#game-view input[type="text"], #game-view select {
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: 12px;
  padding: 10px 14px;
  color: var(--text);
  font-size: 1rem;
  width: 100%;
  max-width: 280px;
  font-family: inherit;
}#game-view input[type="text"]:focus, #game-view select:focus {
  outline: none;
  border-color: var(--violet-text);
}/* Auch global: die Knoepfe stecken in den Modals an document.body. */
/* .avatar-overlay MUSS hier stehen. Der Dialog haengt an document.body und
   liegt damit ausserhalb von #game-view — ohne diesen Selektor bekam keiner
   seiner beiden Knoepfe eine Knopfform: keine Fuellung, kein Radius, kein
   Innenabstand und vor allem keine font-size. Genau die Warnung aus
   CLAUDE.md ("was an document.body haengt, muss global stehen"), diesmal
   nicht bei einer Animation, sondern bei einer Schaltflaeche.

   Dass es ein Versehen war und keine Absicht, sagt die Datei selbst: weiter
   unten steht `.avatar-aktionen .action { flex: 1 1 0; }` — eine Regel, die
   nur Sinn ergibt, wenn .action dort auch greift. */
#game-view button.action, .modal button.action, .avatar-overlay button.action {
  background: var(--violet);
  /* --on-solid statt white: --violet ist seit dem Farbwechsel das helle
     Signalgruen, kein dunkles Violett mehr. Weisse Schrift darauf kommt auf
     1,7:1 — in BEIDEN Themen unlesbar. Der :root-Block dieser Datei sagt es
     selbst: "Flaechen, die --ink/--violet/--orange als Hintergrund nutzen,
     tragen dunkle Schrift (--on-solid) statt der frueheren weissen." Diese
     Zeile war beim Wechsel stehengeblieben. */
  color: var(--on-solid);
  border: none;
  border-radius: 999px;
  padding: 11px 22px;
  font-size: 0.95rem;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  margin-left: 8px;
  box-shadow: 0 6px 18px rgba(var(--violet-rgb), 0.25);
  transition: transform 0.1s ease, background 0.15s ease, box-shadow 0.15s ease;
}#game-view button.action:hover, .modal button.action:hover { background: var(--violet-deep); box-shadow: 0 8px 24px rgba(var(--violet-deep-rgb), 0.32); }#game-view button.action:active, .modal button.action:active { transform: scale(0.96); }#game-view button.action:disabled, .modal button.action:disabled { background: var(--absent); color: var(--muted); cursor: default; box-shadow: none; }/* ==========================================================================
   Die Ratetafel — Spielerpass und Spielstaette
   --------------------------------------------
   ZWEI SPIELE, EIN AUFBAU. Beide laufen durch renderRateSpiel(); was sie
   unterscheidet, ist eine Farbe (--rate-ton) und was in den Kacheln steht.

   WAS HIER STAND UND GEGANGEN IST (12.09.2026, zweiter Anlauf):
     .rate-vorschlaege   die Auswahlliste beim Tippen. Kein anderes Spiel hier
                         zeigt den Vorrat, aus dem gesucht wird — aus Tippen
                         wurde Auswaehlen.
     die Leerzeilen      sechs gestrichelte Zeilen, die vierhundert Pixel mit
                         nichts fuellten. Die Karte wirkte leer, weil sie leer
                         WAR. An ihrer Stelle steht die Akte, und wie viele
                         Versuche bleiben, sagen sechs Punkte in einer Zeile.
   ========================================================================== */
#game-view .rate-karte { --rate-ton: var(--violet); }
/* Die zwei Spielfarben aus game-art.js: Flieder fuer den Spielerpass,
   Bernstein fuer die Spielstaette. Sie kommen NUR auf der Akte vor — als
   Kachelfarbe waeren sie ein dritter Zustand neben gruen und bernstein. */
#game-view .rate-karte--whoami  { --rate-ton: #C6A2E8; }
#game-view .rate-karte--stadium { --rate-ton: #FFCF6B; }
/* Boxen und Kaefig, 16.09.2026. Dieselben Toene wie auf den Kacheln
   (KACHEL_AKZENT in game-art.js) — zwei Orte fuer eine Farbe waeren zwei
   Orte, an denen sie auseinanderlaufen kann, aber CSS kann die Tabelle aus
   dem Modul nicht lesen. Wer einen Ton aendert, aendert beide. */
#game-view .rate-karte--boxen   { --rate-ton: #E0517F; }
#game-view .rate-karte--kaefig  { --rate-ton: #7C73E6; }

/* ---------- Die Akte ---------- */
#game-view .rate-akte {
  margin: 16px 0 18px;
  padding: 14px 16px 12px;
  border-radius: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 3px solid var(--rate-ton);
}
#game-view .rate-akte-kopf {
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--rate-ton);
  margin-bottom: 10px;
}
#game-view .rate-akte-liste { margin: 0; display: grid; gap: 7px; }
#game-view .rate-akte-zeile {
  display: grid;
  /* 104 px UND NICHT 84 (23.09.2026, gemessen). Die Spalte muss das laengste
     EINZELNE WORT fassen, nicht die laengste Beschriftung: Ein Wort ohne
     Trennstelle bricht nicht um, es laeuft ueber die Spalte hinaus. Gemessen
     bei 0.66rem, fett, Versalien, 0.08em Sperrung:

       Erstmals Gastgeber 141 · Grand-Prix-Starts 130 · Grand-Prix-Siege 118
       Bester Schnitt 104 · Goldmedaillen 102 · Koerpergroesse 97

     Die ersten drei und "Bester Schnitt" haben eine Trennstelle (Leerzeichen
     oder Bindestrich) und brechen auf zwei Zeilen; "Goldmedaillen" und
     "Koerpergroesse" haben keine und brauchen die Breite. 104 deckt beide.

     Sichtbar wurde es mit den NFL-Kacheln, da stand "KOERPERGROESSE" auf
     "unter 193". Der Fehler ist aelter: Olympias Austragungsort und der
     Fahrerpass tragen seit dem 22.09.2026 laengere Beschriftungen.

     KEIN `auto` und kein `max-content`: Jede Zeile ist ein eigenes Raster,
     also bekaeme jede eine andere Spaltenbreite und nichts stuende mehr
     untereinander — genau der Fehler, den die Ligatabelle am 13.09.2026
     hatte. */
  grid-template-columns: 104px 1fr;
  gap: 12px;
  align-items: baseline;
  font-size: 0.9rem;
}
#game-view .rate-akte-zeile dt {
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
#game-view .rate-akte-zeile dd { margin: 0; font-weight: 650; }
/* Offen heisst: dazu ist noch nichts bekannt. Leise, aber nicht unsichtbar —
   die Zeile sagt ja, was es zu erfahren GIBT. */
#game-view .rate-akte-zeile.ist-offen dd { color: var(--muted); font-weight: 500; font-style: italic; }
#game-view .rate-akte-zeile.ist-sicher dd { color: var(--correct-text); font-weight: 800; }

/* ---------- Die Tipps ---------- */
/* Das Raster ist ein Grid und keine Flexbox: Name links, Kacheln rechts, und
   die Kacheln aller Zeilen muessen UNTEREINANDER stehen. Genau darin liegt
   der Wert der Tafel — man liest eine Spalte hinunter ("Land dreimal
   falsch"). Mit Flexbox haengt die Spaltenbreite am laengsten Namen JEDER
   Zeile einzeln, und die Spalten wackeln. */
#game-view .rate-tafel { margin: 0 0 18px; }
#game-view .rate-kopfzeile,
#game-view .rate-reihe {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
}
#game-view .rate-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
#game-view .rate-kopfzeile { margin-bottom: 6px; }
#game-view .rate-reihe {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 8px 10px 8px 14px;
  animation: slideIn 0.25s ease;
}
#game-view .rate-reihe--treffer { border-color: var(--correct-text); background: rgba(23, 166, 90, 0.1); }
#game-view .rate-name {
  font-weight: 700;
  font-size: 0.92rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#game-view .rate-name--kopf,
#game-view .rate-feldname {
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
}
#game-view .rate-name--kopf { text-align: left; padding-left: 4px; }
#game-view .rate-kacheln { display: flex; gap: 6px; }
#game-view .rate-feldname {
  width: 46px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* DIE KACHEL IST EIN GRID MIT EINER ZEILE, und das ist der Unterschied zur
   ersten Fassung: Dort standen Zahl und Pfeil als zwei Inline-Elemente
   verschiedener Groesse nebeneinander, und die kleinere Schrift zog die
   gemeinsame Grundlinie nach oben — "1944" sass sichtbar zu hoch. Jetzt
   zentriert das Grid beides in beiden Achsen, unabhaengig von der
   Schriftgroesse. */
#game-view .rate-kachel {
  width: 46px; height: 46px;
  display: grid;
  grid-auto-flow: column;
  align-content: center;
  justify-content: center;
  align-items: center;
  gap: 1px;
  border-radius: 12px;
  background: var(--card);
  border: 1px solid var(--line);
  font-size: 0.86rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  white-space: nowrap;
}
#game-view .rate-kachel--treffer { background: var(--correct); border-color: var(--correct); color: var(--on-solid); }
#game-view .rate-kachel--nah { background: var(--present); border-color: var(--present); color: var(--on-solid); }
#game-view .rate-kachel--leer { color: var(--muted); }
#game-view .rate-zahl { line-height: 1; }
#game-view .rate-pfeil { font-size: 0.8em; line-height: 1; }

/* ---------- Eingabe und Versuche ---------- */
#game-view .rate-eingabe { margin-bottom: 4px; }
#game-view .rate-fuss { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
/* Sechs Punkte statt sechs Leerzeilen. Dieselbe Auskunft auf einer Zeile
   statt auf vierhundert Pixeln. */
#game-view .rate-pips { display: inline-flex; gap: 5px; }
#game-view .rate-pip {
  width: 9px; height: 9px;
  border-radius: 999px;
  border: 1.5px solid var(--rate-ton);
  transition: background 0.2s ease, opacity 0.2s ease;
}
#game-view .rate-pip.ist-weg { background: var(--rate-ton); opacity: 0.35; border-color: transparent; }
#game-view .rate-uebrig { color: var(--muted); font-size: 0.82rem; }

/* AUF DEM HANDY STEHT DER NAME UEBER DEN KACHELN, nicht daneben.

   Gemessen bei 375 px: Die Zeile ist 269 breit, fuenf Kacheln zu 38 plus vier
   Abstaende plus Polster nehmen 226 davon — fuer den Namen blieben 35 Pixel,
   und "Camp Nou" stand dort als "Ca…". Ein Tipp, den man nicht lesen kann,
   macht die ganze Tafel wertlos: Man vergleicht ja Zeile gegen Zeile. */
@media (max-width: 560px) {
  #game-view .rate-kachel { width: 38px; height: 38px; font-size: 0.72rem; border-radius: 10px; }
  #game-view .rate-feldname { width: 38px; font-size: 0.55rem; letter-spacing: 0.04em; }
  #game-view .rate-kacheln { gap: 4px; justify-content: space-between; }
  #game-view .rate-reihe,
  #game-view .rate-kopfzeile { grid-template-columns: 1fr; gap: 6px; padding: 8px 10px; }
  #game-view .rate-name { font-size: 0.86rem; white-space: normal; }
  #game-view .rate-name--kopf { display: none; }
  #game-view .rate-kopfzeile { padding-block: 0; }
  #game-view .rate-akte-zeile { grid-template-columns: 72px 1fr; gap: 8px; font-size: 0.84rem; }
}

@keyframes slideIn {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}#game-view .club-path { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0; }#game-view .club-chip {
  background: var(--panel);
  border: 1px solid var(--line);
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 0.88rem;
  font-weight: 600;
}#game-view .result {
  margin-top: 16px;
  padding: 12px 16px;
  border-radius: 12px;
  font-weight: 600;
}#game-view .result.win { background: rgba(23, 166, 90, 0.12); color: var(--correct-text); }#game-view .result.lose { background: rgba(var(--orange-rgb), 0.1); color: var(--orange-text); }.xp-gain {
  display: inline-block;
  margin-left: 8px;
  font-size: 0.85rem;
  color: var(--violet-text);
  font-weight: 700;
}#game-view .input-row { display: flex; align-items: center; margin-top: 12px; }/* ---------- Rank the Club ---------- */
#game-view .rank-list { display: flex; flex-direction: column; gap: 8px; margin: 16px 0; }#game-view .rank-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 14px;
}#game-view .rank-row.rank-correct { border-color: var(--correct-text); background: rgba(23, 166, 90, 0.1); }#game-view .rank-row.rank-wrong { border-color: var(--orange-text); background: rgba(var(--orange-rgb), 0.08); }#game-view .rank-pos { font-weight: 700; color: var(--muted); width: 20px; }#game-view .rank-name { flex: 1; font-weight: 600; }#game-view .rank-btn {
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  width: 30px; height: 30px;
  cursor: pointer;
  font-size: 1rem;
}#game-view .rank-btn:disabled { opacity: 0.3; cursor: default; }#game-view .rank-btn:hover:not(:disabled) { background: var(--violet); color: var(--on-solid); border-color: var(--violet); }

/* ---- Rangfolge: Ziehen ---------------------------------------------------
   Die Zeilen verschieben sich beim Ziehen per transform, deshalb der
   Uebergang. Die GEZOGENE Zeile bekommt ihn ausdruecklich nicht: Sie soll dem
   Zeiger sofort folgen, nicht mit einer Sechstelsekunde Verspaetung
   hinterherlaufen. */
#game-view .rank-row { transition: transform 0.16s ease, border-color 0.15s ease; }
#game-view .rank-row--ziehbar { cursor: grab; }
#game-view .rank-row--zieht {
  transition: none;
  position: relative;
  z-index: 2;
  cursor: grabbing;
  border-color: var(--violet-text);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);
}
/* Waehrend eines Zuges darf nichts markiert werden — sonst zieht man ueber
   drei Zeilen und hat am Ende deren Text blau hinterlegt. */
#game-view .rank-list--zieht { user-select: none; }
/* touch-action: none NUR am Griff. Auf der ganzen Zeile liesse sich die Seite
   dort, wo die Liste steht, nicht mehr scrollen — und das ist auf dem Handy
   der halbe Bildschirm. Mit der Maus zieht deshalb die ganze Zeile, mit dem
   Finger nur hier. */
#game-view .rank-griff {
  display: flex;
  align-items: center;
  color: var(--muted);
  cursor: grab;
  touch-action: none;
  /* HOCH STATT BREIT. Der Finger braucht eine Flaeche, aber auf dem Handy ist
     die Zeile nur 269 px breit und die Namen brechen schon um — jeder Pixel
     Breite kostet dort eine zweite Zeile. Also in die HOEHE: `stretch` macht
     das Ziel so hoch wie die Zeile (52 px und mehr), und die negativen Raender
     schieben es in das Polster der Zeile hinein, statt daneben Platz zu
     nehmen. Gemessen 24 px breit, volle Zeilenhoehe hoch. */
  align-self: stretch;
  margin: -10px 0 -10px -14px;
  padding: 0 6px 0 14px;
}
#game-view .rank-griff svg { width: 18px; height: 18px; }
#game-view .rank-row--zieht .rank-griff { cursor: grabbing; }
#game-view .rank-ziehhinweis { color: var(--muted); font-size: 0.82rem; margin: 10px 0 0; }

/* ---- Rangfolge: die Loesung als Liste -----------------------------------
   Sie stand bis zum 10.09.2026 als Satz in der Ergebniszeile ("A (12) → B (9)
   → …"). Als Liste in derselben Form wie die abgegebene Reihenfolge laesst
   sie sich Zeile gegen Zeile vergleichen, statt zwischen Liste und Fliesstext
   zu springen. */
#game-view .rank-loesung { margin-top: 22px; }
#game-view .rank-loesung-titel {
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}
/* Die Loesung ist Auskunft, kein Spielfeld: eine Spur flacher als die Liste
   darueber, damit klar bleibt, welche der beiden die eigene Abgabe ist. */
#game-view .rank-list--loesung .rank-row { background: transparent; }
#game-view .rank-wert { color: var(--muted); font-variant-numeric: tabular-nums; font-weight: 700; }

/* AUF DEM HANDY IST DIE ZEILE 269 PX BREIT, und fuenf Elemente teilen sie
   sich: Griff, Nummer, Name, zwei Pfeile. Der Griff kostet dort Platz, den
   der Name braucht — gemessen ueber 40 Zeilen, wie viele davon umbrechen:

     ohne Griff, weite Abstaende          5 von 40   Name 147 px
     mit Griff, weite Abstaende          16 von 40   Name 123 px
     mit Griff, dieser Block              8 von 40   Name 136 px
     Nummer als Griff, gar kein Symbol    4 von 40   Name 151 px

   Die letzte Zeile waere die beste Zahl und die schlechteste Loesung: Eine
   Ziffer sieht nicht so aus, als koenne man sie anfassen. Es bleibt also beim
   sichtbaren Griff, nur schmaler — und der ehrliche Preis dafuer sind vier
   umgebrochene Zeilen von vierzig, nicht elf.

   Der Griff wird schmaler, nicht kleiner: Ueber `align-self: stretch` ist er
   so hoch wie die Zeile (49 px), das Ziel fuer den Finger liegt also in der
   Hoehe ueber der 44-px-Marke, auch wenn es nur 29 px breit ist. */
@media (max-width: 560px) {
  #game-view .rank-row { gap: 5px; padding: 10px 12px; }
  #game-view .rank-btn { width: 25px; height: 25px; font-size: 0.88rem; }
  #game-view .rank-griff { margin-left: -12px; padding: 0 3px 0 12px; }
  #game-view .rank-griff svg { width: 14px; height: 14px; }
}
#game-view footer {
  text-align: center;
  color: var(--muted);
  font-size: 0.78rem;
  padding: 20px 16px;
}/* ---------- Modal ---------- */
/* Global (nicht auf #game-view begrenzt), aus demselben Grund wie beim
   Konfetti weiter unten: askInput(), showComingSoon() und der Anmeldedialog
   haengen ihr Overlay an document.body. Das ist ein Geschwister von
   <main id="game-view">, kein Kind — mit "#game-view .modal-overlay" hat die
   Regel nie gegriffen, und das Fenster fiel unformatiert ans Seitenende. */
#game-view .modal-overlay, .modal-overlay {
  position: fixed; inset: 0;
  background: rgba(2, 2, 4, 0.5);
  display: flex; align-items: center; justify-content: center;
  /* Siehe .avatar-overlay: derselbe Ebenenfehler, nur noch tiefer. */
  z-index: var(--z-modal);
}#game-view .modal, .modal {
  background: var(--card);
  padding: 28px;
  border-radius: 20px;
  max-width: 320px;
  text-align: center;
  border: 1px solid var(--line);
}#game-view .modal button, .modal button { margin-top: 12px; }#game-view .modal input, .modal input {
  margin-top: 12px;
  max-width: 100%;
}/* ---------- Level-Up Toast ---------- */
/* Ebenfalls global: showLevelUpToast(), ligaToast() und zeigeToast() haengen
   an document.body. */
#game-view .level-up-toast, .level-up-toast {
  position: fixed;
  top: 20px;
  left: 50%;
  display: flex;
  align-items: center;
  gap: 8px;
  background: linear-gradient(110deg, var(--violet), var(--violet-deep));
  color: var(--on-solid);
  padding: 12px 26px;
  border-radius: 999px;
  font-weight: 800;
  font-size: 0.95rem;
  box-shadow: 0 10px 30px rgba(var(--violet-deep-rgb), 0.35);
  /* Ueber allem, auch ueber einem offenen Dialog: eine Meldung ist die
     Antwort auf etwas, das gerade passiert ist. Auf 50 lag sie unter der
     Kopfleiste (200) — am oberen Rand also genau dort, wo sie erscheint. */
  z-index: var(--z-toast);
  animation: toastIn 0.35s ease, toastOut 0.4s ease 2.4s forwards;
}#game-view .toast-icon, .toast-icon { display: inline-flex; }#game-view .toast-icon svg, .toast-icon svg { width: 18px; height: 18px; }@keyframes toastIn {
  from { transform: translate(-50%, -20px); opacity: 0; }
  to { transform: translate(-50%, 0); opacity: 1; }
}
@keyframes toastOut {
  to { transform: translate(-50%, -20px); opacity: 0; }
}/* ---------- Karriereweg 2.0 ---------- */
#game-view .cp-card { position: relative; }/* .cp-mode-row ist weg: Flugroute traegt seit dem 09.09.2026 den gemeinsamen Spiel-Kopf (.modus-reihe). .cp-mode-btn bleibt — der Best-of-Umschalter im Duell benutzt ihn weiter. */#game-view .cp-mode-btn {
  background: var(--card);
  border: 1.5px solid var(--line);
  color: var(--muted);
  border-radius: 999px;
  padding: 7px 16px;
  font-size: 0.85rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}#game-view .cp-mode-btn:hover { color: var(--ink); border-color: var(--ink); }#game-view .cp-mode-btn.active { background: var(--ink); color: var(--on-ink); border-color: var(--ink); font-weight: 700; }#game-view .cp-note {
  background: rgba(var(--violet-rgb), 0.08);
  color: var(--violet-text);
  padding: 9px 14px;
  border-radius: 12px;
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 10px;
}#game-view .cp-map-wrap {
  background: #0C1A24;
  border-radius: 18px;
  overflow: hidden;
  margin: 14px 0;
  border: 1px solid var(--line);
}#game-view .cp-map { width: 100%; height: auto; display: block; }#game-view .cp-map-bg { fill: #0C1A24; }#game-view .cp-world { fill: #17231D; stroke: var(--ink-700); stroke-width: 0.5; }#game-view .cp-grid-line { stroke: rgba(255,255,255,0.035); stroke-width: 1; }#game-view .cp-flight-path {
  fill: none;
  stroke: var(--orange);
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: cpDrawPath 1.1s ease forwards;
}
@keyframes cpDrawPath {
  to { stroke-dashoffset: 0; }
}#game-view .cp-marker { animation: cpMarkerIn 0.4s ease backwards; }
@keyframes cpMarkerIn {
  from { opacity: 0; transform: scale(0.4); transform-origin: center; }
  to { opacity: 1; transform: scale(1); }
}#game-view .cp-dot { fill: var(--violet); stroke: #040706; stroke-width: 1.5; }#game-view .cp-dot-pulse {
  fill: none;
  stroke: var(--violet);
  stroke-width: 2;
  opacity: 0.7;
  animation: cpPulse 1.8s ease-out infinite;
}
@keyframes cpPulse {
  from { r: 7; opacity: 0.7; }
  to { r: 18; opacity: 0; }
}#game-view .cp-dot-label {
  fill: var(--text);
  font-size: 15px;
  font-weight: 700;
  text-anchor: middle;
}#game-view .cp-plane {
  font-size: 22px;
  text-anchor: middle;
  animation: cpPlaneBob 1.6s ease-in-out infinite;
}
@keyframes cpPlaneBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}#game-view .cp-stations-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 4px 0 8px;
}#game-view .cp-stations-head span { color: var(--violet-text); }
/* ---- Die naechste Station kaufen (11.09.2026) ----------------------------
   Steht zwischen Liste und Frage: Hier endet, was man weiss, und hier
   beginnt, was man tippen soll. Der Knopf ist bewusst "ghost" — die
   Hauptsache dieser Runde ist das Raten, nicht das Aufdecken. */
#game-view .cp-aufdecken {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 10px 0 4px;
}
#game-view .cp-aufdecken .action { flex: 0 1 auto; }
#game-view .cp-aufdecken-preis {
  font-size: 0.76rem; color: var(--muted); font-variant-numeric: tabular-nums;
}
@media (max-width: 520px) {
  #game-view .cp-aufdecken { gap: 8px; }
  #game-view .cp-aufdecken .action { flex: 1 1 100%; }
}#game-view .cp-stations { display: flex; flex-direction: column; gap: 6px; margin: 0 0 16px; }#game-view .cp-station-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  gap: 2px 10px;
  align-items: center;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 9px 12px;
  font-size: 0.85rem;
}/* Nur die neu aufgedeckte Station animiert — sonst "wandert" die ganze Liste bei jedem Redraw. */
#game-view .cp-station-row.is-new { animation: slideIn 0.25s ease; }#game-view .cp-station-num {
  grid-column: 1;
  grid-row: 1 / 3;
  align-self: center;
  background: var(--violet);
  color: var(--on-solid);
  font-weight: 700;
  border-radius: 50%;
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.78rem;
}#game-view .cp-station-club { font-weight: 700; grid-column: 2; }#game-view .cp-station-meta { color: var(--muted); font-size: 0.78rem; grid-column: 2; }#game-view .cp-station-stats { color: var(--orange-text); font-size: 0.78rem; font-weight: 600; grid-column: 3; grid-row: 1 / 3; align-self: center; text-align: right; white-space: nowrap; }#game-view .cp-timer { margin-top: 8px; color: var(--muted); font-size: 0.85rem; }#game-view .cp-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }#game-view button.secondary, .modal button.secondary {
  background: transparent;
  color: var(--ink);
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  padding: 10px 20px;
  font-size: 0.95rem;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  margin-left: 8px;
  transition: background 0.15s ease;
}#game-view button.secondary:hover, .modal button.secondary:hover { background: rgba(2, 2, 4, 0.06); }/* ---------- Career Trail ---------- */
#game-view .cp-title {
  margin: 10px 0 2px;
  font-size: clamp(1.8rem, 4.5vw, 2.4rem);
  font-weight: 900;
  letter-spacing: -0.04em;
  color: var(--ink);
}#game-view .cp-tagline { margin: 0 0 6px; color: var(--muted); font-size: 0.95rem; }#game-view .cp-km {
  display: block;
  height: 1.2rem;
  line-height: 1.2rem;
  margin: -4px 0 12px;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--orange-text);
  letter-spacing: 0.02em;
}#game-view .cp-station-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 4px solid var(--violet-text);
  border-radius: 14px;
  padding: 14px 18px;
  margin-bottom: 18px;
  animation: slideIn 0.3s ease;
}#game-view .cp-station-eyebrow {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}#game-view .cp-station-headline { font-size: 1.3rem; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); }#game-view .cp-station-stats-line { margin-top: 4px; font-size: 0.82rem; font-weight: 600; color: var(--orange-text); }#game-view .cp-question {
  font-size: 1.1rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-bottom: 12px;
}/* .cp-options und .cp-option sind weg (09.09.2026): Sie trugen die vier Vereine der Stationsfrage "Wohin ging er als Naechstes?". Die Frage gibt es nicht mehr — jede Runde legt die ganze Karriere offen. */#game-view .cp-subtle { font-size: 0.85rem; color: var(--muted); }#game-view .cp-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 0;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}#game-view .cp-divider::before, #game-view .cp-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}#game-view .cp-linkbtn {
  background: none;
  border: none;
  color: var(--violet-text);
  font-weight: 700;
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  padding: 0;
}#game-view .cp-linkbtn:hover { text-decoration: underline; }#game-view .cp-linkbtn:disabled { color: var(--muted); cursor: default; text-decoration: none; }#game-view .cp-hints { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }#game-view .cp-hint-chip {
  background: rgba(var(--violet-rgb), 0.08);
  border: 1px solid rgba(var(--violet-rgb), 0.2);
  color: var(--ink);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 0.82rem;
  animation: slideIn 0.25s ease;
}#game-view .cp-hint-chip b { color: var(--violet-text); }#game-view .cp-guess-meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-top: 10px;
  font-size: 0.85rem;
  color: var(--muted);
  font-weight: 600;
}/* Hinweis-Shop */
#game-view .cp-hint-shop { margin-top: 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 12px 14px; }#game-view .cp-shop-label { font-size: 0.68rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }#game-view .cp-shop-items { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }#game-view .cp-shop-btn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  background: var(--card); border: 1.5px solid var(--line); border-radius: 12px; padding: 9px 12px;
  font-size: 0.88rem; font-weight: 700; font-family: inherit; color: var(--ink); cursor: pointer; text-align: left;
  transition: border-color 0.15s ease, transform 0.12s ease;
}#game-view .cp-shop-btn span { font-size: 0.72rem; font-weight: 700; color: var(--violet-text); }#game-view .cp-shop-btn:hover:not(:disabled) { border-color: var(--violet-text); transform: translateY(-1px); }#game-view .cp-shop-btn:disabled { opacity: 0.5; cursor: default; }#game-view .cp-shop-hint { margin-top: 10px; font-size: 0.8rem; color: var(--muted); font-style: italic; }/* Wochen-Rückblick */
#game-view .cp-week { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; margin: 0 0 18px; }#game-view .cp-week-title { font-size: 0.68rem; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }#game-view .cp-week-dots { display: flex; gap: 8px; justify-content: center; margin-bottom: 12px; }#game-view .cp-week-dot { width: 20px; height: 20px; border-radius: 6px; }#game-view .cp-week-dot.hit { background: var(--correct); }#game-view .cp-week-dot.miss { background: var(--orange); }#game-view .cp-week-dot.empty { background: var(--line); }#game-view .cp-week-stats { display: flex; flex-wrap: wrap; gap: 6px 16px; justify-content: center; font-size: 0.82rem; color: var(--muted); }#game-view .cp-week-stats b { color: var(--ink); font-weight: 800; }
@media (max-width: 600px) {#game-view .cp-shop-items { grid-template-columns: 1fr; } }/* ---------- Duell ---------- *//* ---------- Höher oder Tiefer ---------- */
#game-view .cmp-streak { font-size: 0.9rem; color: var(--muted); margin-bottom: 12px; }#game-view .cmp-streak b { color: var(--orange-text); font-weight: 800; }#game-view .cmp-question { font-size: 1.15rem; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); text-align: center; margin-bottom: 16px; }#game-view .cmp-grid { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px; }#game-view .cmp-vs { font-weight: 800; color: var(--muted); font-size: 0.9rem; }#game-view .cmp-card {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: var(--card); border: 1.5px solid var(--line); border-radius: 18px;
  padding: 20px 14px; cursor: pointer; font-family: inherit; text-align: center;
  transition: transform 0.15s var(--ease-kinetic), border-color 0.15s ease;
}#game-view .cmp-card:hover:not(:disabled) { transform: translateY(-3px); border-color: var(--violet-text); }#game-view .cmp-card:disabled { cursor: default; }#game-view .cmp-flag { font-size: 1.8rem; }#game-view .cmp-meta { font-size: 0.75rem; color: var(--muted); }#game-view .cmp-card.cmp-correct { border-color: var(--correct-text); background: rgba(23, 166, 90, 0.1); }#game-view .cmp-card.cmp-wrong { border-color: var(--orange-text); background: rgba(var(--orange-rgb), 0.08); opacity: 0.75; }
@media (max-width: 600px) {#game-view .cmp-grid { grid-template-columns: 1fr; }#game-view .cmp-vs { padding: 4px 0; }
}
#game-view .cp-complete {
  text-align: center;
  padding: 22px 18px 6px;
  animation: fadeUp 0.4s var(--ease-kinetic) both;
}#game-view .cp-complete-tag {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}#game-view .cp-complete.win .cp-complete-tag { color: var(--correct-text); }#game-view .cp-complete-name {
  font-size: clamp(1.8rem, 5vw, 2.6rem);
  font-weight: 900;
  letter-spacing: -0.04em;
  color: var(--ink);
  margin: 4px 0;
}#game-view .cp-complete-sub { color: var(--muted); font-size: 0.9rem; margin-bottom: 18px; }/* Die Turnierteilnahmen in der Aufloesung. Eigene Zeile statt an die Unterzeile angehaengt: Position, Land und Geburtsjahr sind kurze Werte, "War dabei: WM 2014 · WM 2010 · Olympia 2008" ist ein Satz. Der Abstand der Unterzeile schrumpft nur dann, wenn die Zeile wirklich folgt — sonst stuende bei den 13 Prozent ohne Turnier eine Luecke, wo nichts ist. */#game-view .cp-complete-sub:has(+ .cp-complete-dabei) { margin-bottom: 4px; }#game-view .cp-complete-dabei { color: var(--muted); font-size: 0.9rem; margin-bottom: 18px; }#game-view .cp-badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 18px;
}#game-view .cp-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.8rem;
  font-weight: 700;
  padding: 6px 13px;
  border-radius: 999px;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--ink);
}#game-view .cp-complete-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-bottom: 16px;
}#game-view .cp-complete-grid > div {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 12px 16px;
  min-width: 82px;
}#game-view .cp-complete-grid b {
  display: block;
  font-size: 1.4rem;
  font-weight: 900;
  letter-spacing: -0.03em;
  color: var(--violet-text);
}#game-view .cp-complete-grid span {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}#game-view .cp-complete-line { color: var(--muted); font-size: 0.9rem; margin-bottom: 18px; }#game-view .cp-complete .cp-actions { justify-content: center; }/* Streak-Badge mit Freeze-Hinweis */
/* Die Serienzahl steht im gemeinsamen Spiel-Kopf (.spiel-serie). Hier bleibt
   nur die Zeile fuer den Freeze-Joker: Den hat allein Flugroute, und er sagt
   etwas anderes als die Zahl — naemlich, dass ein verpasster Tag einmal
   abgefangen wird. */
#game-view .cp-freeze-zeile { margin-top: 8px; }
#game-view #game-view .cp-freeze {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--violet-text);
  background: rgba(var(--violet-rgb), 0.1);
  border: 1px solid rgba(var(--violet-rgb), 0.25);
  border-radius: 999px;
  padding: 3px 10px;
  cursor: help;
}/* Endlos-Filter (Position/Region) */
#game-view .cp-filters { display: flex; flex-wrap: wrap; gap: 14px; margin: 10px 0 2px; }#game-view .cp-filter {
  display: inline-flex;
  flex-direction: column;
  gap: 5px;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}#game-view .cp-filter select {
  width: auto;
  min-width: 150px;
  max-width: 220px;
  font-size: 0.9rem;
  padding: 9px 12px;
}/* Freundes-Leaderboard */
#game-view .cp-leaderboard {
  margin-top: 20px;
  text-align: left;
  border-top: 1px solid var(--line);
  padding-top: 16px;
}#game-view .cp-leaderboard-title {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}#game-view .cp-leaderboard-row {
  display: grid;
  grid-template-columns: 26px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 12px;
  font-size: 0.9rem;
}#game-view .cp-leaderboard-row + .cp-leaderboard-row { margin-top: 4px; }#game-view .cp-leaderboard-row.me { background: rgba(var(--violet-rgb), 0.08); border: 1px solid rgba(var(--violet-rgb), 0.2); }#game-view .cp-lb-rank { font-weight: 800; color: var(--muted); text-align: center; }#game-view .cp-lb-name { font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }#game-view .cp-lb-score { font-weight: 700; color: var(--violet-text); white-space: nowrap; font-size: 0.85rem; }
/* Eigener Platz, wenn er unterhalb der besten zehn liegt: Lücke andeuten,
   damit die Sprungstelle sichtbar ist und die Reihen darunter nicht als
   Plätze 11 und 12 missverstanden werden. */
#game-view .cp-lb-luecke { text-align: center; color: var(--muted); letter-spacing: 0.3em; padding: 6px 0 2px; font-size: 0.8rem; }
#game-view .cp-lb-abstand { margin-top: 8px; font-weight: 700; font-size: 0.85rem; color: var(--violet-text); text-align: center; }
#game-view .cp-lb-gesamt { margin-top: 4px; font-size: 0.8rem; color: var(--muted); text-align: center; }/* View Transitions: weicher Katalog↔Spiel-Wechsel (~0.3s) */
#game-view ::view-transition-old(root), #game-view ::view-transition-new(root) {
  animation-duration: 0.3s;
  animation-timing-function: var(--ease-kinetic);
}#game-view ::view-transition-old(root) { animation-name: vtOut; }#game-view ::view-transition-new(root) { animation-name: vtIn; }
@keyframes vtOut { to { opacity: 0; transform: translateY(-8px); } }
@keyframes vtIn { from { opacity: 0; transform: translateY(10px); } }

@media (max-width: 600px) {#game-view .cp-station-row { grid-template-columns: 22px 1fr; }#game-view .cp-station-stats { grid-column: 1 / 3; grid-row: auto; text-align: left; }.hero { padding: 36px 0 32px; }.hero-dots { display: none; }#game-view .grid { grid-template-columns: 1fr; }#game-view .tile.featured { grid-column: auto; grid-row: auto; }
}

@media (prefers-reduced-motion: reduce) {*, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }html { scroll-behavior: auto; }
}/* ============================================================
   Zugänglichkeit, Skeletons, Cold-Start, Archiv (Polish-Batch)
   ============================================================ */
#game-view .sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}/* Skeleton-Loading */
#game-view .skel-card { display: flex; flex-direction: column; gap: 12px; }#game-view .skel {
  background: linear-gradient(90deg, var(--panel) 25%, rgba(255,255,255,.07) 37%, var(--panel) 63%);
  background-size: 400% 100%;
  border-radius: 10px;
  animation: skelShimmer 1.3s ease-in-out infinite;
}#game-view .skel-title { height: 34px; width: 45%; border-radius: 12px; }#game-view .skel-line { height: 14px; }#game-view .skel-map { height: 260px; border-radius: 18px; }#game-view .skel-row { height: 46px; border-radius: 12px; }#game-view .skel-btn { height: 44px; width: 160px; border-radius: 999px; }
@keyframes skelShimmer {
  0% { background-position: 100% 0; }
  100% { background-position: 0 0; }
}/* Cold-Start-Hinweis (Render Free Tier schläft nach ~15 Min.) */
/* GLOBAL, NICHT UNTER #game-view — und das ist zum dritten Mal dieselbe
   Falle. Der Hinweis haengt an document.body (showColdStartHint() in app.js),
   also hat `#game-view .cold-start-hint` NIE gegriffen: Er stand unformatiert
   am Seitenende, wenn er ueberhaupt erschien. Der Kommentar bei styles.css
   sagt es seit langem — was an document.body haengt, muss global stehen, das
   ist hier schon beim Konfetti und beim Avatar-Dialog schiefgegangen.

   Wie es hierher kam, steht ein paar Zeilen tiefer im Klartext: Ein
   Sammellauf hat `#game-view ` vor die Regeln gesetzt und dabei sogar
   Kommentartext erwischt ("#game-view feste Höhe"). */
.cold-start-hint {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--ink);
  /* --on-ink UND NICHT --on-solid, und das ist genau der Fall, den CLAUDE.md
     beschreibt: --ink heisst "hoechster Kontrast zur Seite" und KIPPT
     zwischen den Themes, --on-solid nicht. Gemessen im hellen Modus stand
     hier #080C0A auf #14110D — Kontrast 1,05, also unlesbar. Im dunklen
     Modus fiel es nicht auf, weil --ink dort hell ist.

     (Dass es ueberhaupt niemandem auffiel, hat einen zweiten Grund: Die
     Regel stand unter #game-view, das Element haengt an document.body — sie
     griff also nie. Siehe oben.) */
  color: var(--on-ink);
  font-size: 0.88rem;
  font-weight: 600;
  padding: 12px 20px;
  border-radius: 999px;
  box-shadow: 0 10px 30px rgba(2, 2, 4, 0.25);
  /* 250 und nicht mehr 200: Das Ladebild liegt auf 240, und dieser Hinweis
     ist genau der, der bei einem schlafenden Server darueber stehen muss. */
  z-index: 250;
  max-width: calc(100vw - 32px);
  animation: fadeUp 0.3s var(--ease-kinetic) both;
}
/* Der Kringel dreht sich auf DERSELBEN Flaeche wie die Schrift, also traegt
   er auch dieselbe Farbe. Vorher war der Ring hartes Weiss und der Bogen
   var(--ink) — also die Farbe des Hintergrunds, auf dem er liegt. Gemessen:
   Pille rgb(238,243,240), Bogen rgb(238,243,240). Er war unsichtbar. */
.cs-spinner {
  width: 14px; height: 14px;
  border: 2px solid color-mix(in srgb, var(--on-ink) 30%, transparent);
  border-top-color: var(--on-ink);
  border-radius: 50%;
  animation: csSpin 0.8s linear infinite;
  flex-shrink: 0;
}
@keyframes csSpin { to { transform: rotate(360deg); } }

/* Tor-Balken: eigene Zeile, feste Höhe → kein Layout-Sprung, kein Überlaufen.
   Die Torzahl selbst steht in der Statistik-Spalte (keine doppelte Anzeige). */
#game-view .cp-station-bar {
  grid-column: 2 / -1;
  height: 6px;
  margin-top: 5px;
  min-width: 0;
  overflow: hidden;
}#game-view .cp-bar-track {
  height: 6px;
  width: 100%;
  background: var(--line);
  border-radius: 3px;
  overflow: hidden;
}#game-view .cp-bar-fill {
  height: 100%;
  background: var(--orange);
  border-radius: 3px;
  min-width: 2px;
}/* Leben-Leiste: deutlich sichtbarer als die frühere Mini-Zeile */
/* Der Plus-Knopf an den Herzen (19.09.2026): ein Leben dazu, nur im
   Endlos-Modus. Klein und rund, damit er neben den Herzen steht und nicht
   neben den Handlungsknoepfen — er ist eine Beigabe, keine Hauptsache.
   44 Pixel Trefferflaeche ueber das Pseudoelement, die Flaeche selbst bleibt
   klein. */
#game-view .cp-leben-plus,
#game-view .cmp-leben-plus {
  position: relative;
  width: 26px; height: 26px;
  padding: 0; margin-left: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  color: var(--violet-text);
  font: 700 16px/1 var(--font-ui, inherit);
  cursor: pointer;
}
#game-view .cp-leben-plus::after,
#game-view .cmp-leben-plus::after {
  content: ""; position: absolute; inset: -9px;
}
#game-view .cp-leben-plus:disabled,
#game-view .cmp-leben-plus:disabled { opacity: 0.4; cursor: default; }

#game-view .cp-lives-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 9px 18px;
  margin-top: 14px;
  width: fit-content;
}#game-view .cp-lives-label {
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}#game-view .cp-lives { font-size: 1.35rem; letter-spacing: 3px; line-height: 1; cursor: default; }/* Statistik-Spalte bleibt einzeilig; die mittlere Grid-Spalte schrumpft stattdessen. */
#game-view .cp-station-stats { white-space: nowrap; }/* km-Zeile: Platz auch reserviert, wenn noch keine Distanz vorliegt */
/* Archiv: verpasste Tage nachholen */
#game-view .cp-archive {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 16px;
  margin: 0 0 18px;
  text-align: left;
}#game-view .cp-archive-title {
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}#game-view .cp-archive-hint { font-size: 0.8rem; color: var(--muted); margin: 4px 0 10px; }#game-view .cp-archive-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(86px, 1fr)); gap: 8px; }#game-view .cp-archive-day {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: 12px;
  padding: 9px 10px;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.12s ease;
}#game-view .cp-archive-day b { font-size: 0.88rem; font-weight: 800; color: var(--ink); }#game-view .cp-archive-day span { font-size: 0.68rem; font-weight: 700; color: var(--violet-text); }#game-view .cp-archive-day:hover:not([disabled]) { border-color: var(--violet-text); transform: translateY(-2px); }#game-view .cp-archive-day[disabled] { cursor: default; opacity: 0.6; }#game-view .cp-archive-day.done { border-color: var(--correct-text); background: rgba(23, 166, 90, 0.08); }#game-view .cp-archive-day.done span { color: var(--correct-text); }#game-view .cp-archive-day.missed { border-color: var(--orange-text); background: rgba(var(--orange-rgb), 0.07); }#game-view .cp-archive-day.missed span { color: var(--orange-text); }/* Modal-Aktionen (Eingabe-Modal statt prompt) */
#game-view .modal-actions, .modal-actions { display: flex; gap: 8px; justify-content: center; margin-top: 16px; }#game-view .modal-actions .secondary, .modal-actions .secondary { margin-left: 0; }/* ============================================================
   Duell-Visuals: VS-Keile, Stroke-Herzen, Score-Balken, Blickschutz, gestaffelte Stationen, Pass-Stempel
   ============================================================ */
/* Lebensanzeige als geometrische Stroke-Herzen */
#game-view .cp-lives { display: inline-flex; align-items: center; gap: 6px; line-height: 1; }#game-view .cp-heart { display: inline-flex; color: var(--orange-text); }#game-view .cp-heart svg { width: 20px; height: 20px; display: block; }#game-view .cp-heart.off { color: var(--absent); opacity: 0.5; }/* VS-Reveal: zwei Keile laufen aufeinander zu */
@keyframes wedgeIn-l { from { transform: translateX(-100%); } to { transform: translateX(0); } }
@keyframes wedgeIn-r { from { transform: translateX(100%); } to { transform: translateX(0); } }
@keyframes vsPop {
  from { transform: translate(-50%, -50%) scale(0.4); opacity: 0; }
  to { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}/* Blickschutz-Hinweis mit durchgestrichenem Auge */
#game-view .duel-lookaway {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: rgba(var(--orange-rgb), 0.08);
  border: 1px solid rgba(var(--orange-rgb), 0.22);
  color: var(--ink);
  border-radius: 14px;
  padding: 10px 16px;
  margin: 4px 0 18px;
  font-size: 0.88rem;
  font-weight: 600;
  text-align: left;
  max-width: 420px;
}/* Punktestand als Balken zusätzlich zur Zahl *//* Gestaffelte Stationsaufdeckung (Duell) */
#game-view .cp-station-row.is-stagger {
  animation: slideIn 0.35s var(--ease-kinetic) both;
  animation-delay: var(--d, 0s);
}/* Stationsnummer im Reisepass-Stempel-Look */
#game-view .cp-station-num { position: relative; }#game-view .cp-station-num::after {
  content: "";
  position: absolute;
  inset: -4px;
  border: 1.5px dashed var(--violet-text);
  border-radius: 50%;
  opacity: 0.45;
  transform: rotate(-8deg);
  pointer-events: none;
}/* ==========================================================================
   Fußball-Impostor
   Nutzt die vorhandenen Variablen; nichts hier definiert eigene Farben.
   ========================================================================== */
#game-view .impo-mitte { text-align: center; }.impo-feld { margin: 18px 0; }.impo-label {
  display: block;
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 8px;
}.impo-stepper {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 5px; max-width: 260px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--card);
}.impo-step {
  width: 46px; height: 46px; flex: none;      /* Fingergröße, nicht kleiner */
  border: 0; border-radius: 50%;
  background: var(--panel); color: var(--text);
  font-size: 1.3rem; font-weight: 700; cursor: pointer;
  transition: background 0.15s, transform 0.15s;
}.impo-step:hover { background: var(--line); }.impo-step:active { transform: scale(0.9); }.impo-wert { font-size: 1.6rem; font-weight: 800; font-variant-numeric: tabular-nums; }.impo-chips { display: flex; flex-wrap: wrap; gap: 8px; }.impo-chip {
  flex: 1 1 auto; min-height: 42px; padding: 9px 14px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--muted);
  font-size: 0.9rem; font-weight: 650; cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}.impo-chip[aria-pressed="true"] {
  background: var(--violet); border-color: var(--violet); color: var(--on-solid);
}.impo-anzahl { margin-left: 6px; opacity: 0.65; font-variant-numeric: tabular-nums; }.impo-fehler {
  padding: 12px 14px; border-radius: 14px;
  background: rgba(255, 77, 109, 0.14); color: var(--coral-300);
  font-size: 0.9rem; font-weight: 600;
}/* Die Karte dreht sich bewusst nicht: Bei einer 3D-Drehung wäre der Inhalt
   der Rückseite für Sekundenbruchteile halbtransparent sichtbar — beim
   Weiterreichen genau das, was nicht passieren darf. Deshalb hartes
   Umschalten, sichtbar ist immer nur genau eine Seite. */
#game-view .impo-karte {
  position: relative; width: 100%; max-width: 380px;
  margin: 18px auto; aspect-ratio: 3 / 4; max-height: 46svh;
  border: 1px solid var(--line); border-radius: 26px;
  background: var(--panel); overflow: hidden; cursor: pointer;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s;
}
/* Hier stand `.impo-karte:active { transform: scale(0.985) }`.

   Bei einem Knopf ist so ein Federn richtig. Diese Karte wird aber GEDRUECKT
   GEHALTEN, und waehrenddessen liest man das Wort darauf — die Skalierung
   lief also nicht als kurze Rueckmeldung ab, sondern stand die ganze Zeit an,
   und beim Loslassen sprang die Karte zurueck. Was man liest, darf sich nicht
   bewegen. Dass die Karte reagiert, sagen Rahmenfarbe und Schatten beim
   Aufdecken (.ist-offen) deutlich genug. */
.impo-karte.ist-offen {
  border-color: var(--violet-text);
  box-shadow: 0 12px 44px rgba(var(--marke-rgb), 0.28);
}.impo-vorne, .impo-hinten {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 22px; text-align: center;
}.impo-hinten { display: none; }.impo-karte.ist-offen .impo-vorne { display: none; }.impo-karte.ist-offen .impo-hinten { display: flex; }.impo-name { font-size: 1.6rem; font-weight: 800; letter-spacing: -0.02em; }.impo-rolle {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted);
}/* ROT NUR IN DER KLASSISCHEN SPIELART.

   In der verdeckten Fassung sieht die Karte des Maulwurfs aus wie jede
   andere — dort waere die Farbe der Verrat, den die gleiche Karte gerade
   verhindert. In der klassischen Fassung sagt die Karte ohnehin, woran man
   ist, und dann darf sie es auch zeigen.

   Die Klasse haengt deshalb an r.verraten und nicht an r.istImpostor; siehe
   impoRolle() in app.js. .impo-name.ist-impostor ist davon unberuehrt — die
   steht auf dem Aufloesungs- und dem Ergebnisbildschirm, wo alles
   offenliegt. */
#game-view .impo-rolle.ist-impostor { color: var(--coral-300); }
#game-view .impo-wort-gross.ist-impostor { color: var(--coral-300); }
#game-view .impo-wort-gross {
  font-family: "Archivo", "Inter", system-ui, sans-serif;
  font-size: clamp(1.5rem, 6vw, 2.3rem); font-weight: 900;
  line-height: 1.05; letter-spacing: -0.03em; text-wrap: balance;
}.impo-timer {
  font-size: 2.6rem; font-weight: 850; font-variant-numeric: tabular-nums;
  margin: 14px 0;
}.impo-timer.ist-aus { color: var(--coral-300); }.impo-verrat {
  margin: 18px 0; padding: 16px; border-radius: 18px;
  background: rgba(255, 77, 109, 0.10);
  border: 1px solid rgba(255, 77, 109, 0.35);
}

/* Ein Knopf, der klickbar aussieht und nichts tut, ist ein Fehler. Am Anschlag
   wird die Sperre deshalb auch sichtbar. */
.impo-step[disabled] { opacity: 0.3; pointer-events: none; }


/* ---------- Fehler: die falsche KARTE zeigt es, und zwar still -----------
   Der Weg dieser Rueckmeldung in drei Schritten: Erst blitzte das ganze
   Fenster rot (.wrong-flash) und der Rahmen pulsierte — das traf auch die
   RICHTIGE Karte daneben, man sah zuerst Rot und erst danach, was eigentlich
   falsch war. Dann wackelte nur noch die getippte Karte. Jetzt bewegt sich
   gar nichts mehr.

   Die Farbe bleibt, die BEWEGUNG geht. Sie war das, was den Fehler zur
   Strafe machte; die Faerbung dagegen ist die Information — sie sagt, welche
   der beiden Karten man getippt hat. Ohne sie zeigt die Aufloesung nur noch,
   was richtig war, und nicht mehr, was man selbst gewaehlt hat. */
#game-view .cmp-card-wrap.cmp-fail {
  border-color: rgba(255, 45, 75, 0.42);
  box-shadow: 0 0 0 1px rgba(255, 45, 75, 0.18);
}

#game-view .cmp-card-wrap.cmp-fail .cmp-card.cmp-wrong {
  border-color: #FF2D4B;
  background: rgba(255, 45, 75, 0.16);
  opacity: 1;
}

/* ---------- Kapitelband ----------
   Eine schmale Zeile ueber der Frage. Sie soll den Abschnitt rahmen, nicht
   mit ihm konkurrieren — deshalb klein, in der Markenfarbe, ohne Flaeche. */
#game-view .cmp-kapitel {
  display: flex; align-items: baseline; justify-content: center; gap: 8px;
  margin: 0 0 10px;
  font-size: 0.76rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.09em;
}
#game-view .cmp-kapitel-nr { color: var(--muted); }
#game-view .cmp-kapitel-label { color: var(--violet-text); }
/* Erste Runde eines Kapitels: schiebt sich einmal herein. */
#game-view .cmp-kapitel.neu { animation: kapitelAn 0.55s var(--ease-kinetic) both; }
@keyframes kapitelAn {
  0%   { opacity: 0; transform: translateY(-8px); letter-spacing: 0.3em; }
  100% { opacity: 1; transform: translateY(0);    letter-spacing: 0.09em; }
}

/* ---------- Schwellenrunde: eine Karte, ja oder nein ----------
   Eine Karte statt zweier, mittig und schmaler. Die beiden Antwortknoepfe
   sitzen darunter genau dort, wo sonst die zweite Karte waere — dadurch
   bleibt die Handhaltung dieselbe wie beim Vergleich. */
#game-view .cmp-schwelle {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
#game-view .cmp-card-solo {
  width: 100%; max-width: 340px;
  cursor: default;
}
#game-view .cmp-jaNein {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  width: 100%; max-width: 340px;
}
#game-view .cmp-jn {
  padding: 16px 10px;
  border-radius: var(--radius-md, 16px);
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--text);
  font-family: inherit; font-size: 1.05rem; font-weight: 800;
  cursor: pointer;
  transition: transform .16s var(--ease-kinetic), border-color .16s ease, background .16s ease;
}
#game-view .cmp-jn:hover:not(:disabled) { transform: translateY(-2px); border-color: var(--violet-text); }
#game-view .cmp-jn:disabled { cursor: default; }
#game-view .cmp-jn.cmp-correct { border-color: var(--correct-text); background: rgba(23, 166, 90, 0.14); }
#game-view .cmp-jn.cmp-wrong   { border-color: var(--orange-text);  background: rgba(var(--orange-rgb), 0.10); opacity: 0.75; }

/* Bedienhinweis, nur in der ersten Runde eines Laufs. Bewusst leise: Er soll
/* ---------- Serienstufen: HATTRICK und aufwaerts ----------
   Liegt ueber den Karten und ist nach gut einer Sekunde wieder weg.
   pointer-events: none, damit waehrend der Marke alles antippbar bleibt. */
#game-view .cmp-card-wrap { position: relative; }
#game-view .cmp-serie-marke {
  position: absolute; inset: 0; z-index: 6;
  display: grid; place-items: center;
  pointer-events: none;
  font-family: "Archivo", sans-serif;
  font-weight: 900; font-style: italic;
  letter-spacing: -0.03em; text-transform: uppercase;
  animation: serieMarke 1.1s var(--ease-kinetic) both;
}
#game-view .cmp-serie-marke.s3  { font-size: clamp(2rem, 9vw, 3.4rem);    color: var(--correct-text); text-shadow: 0 0 26px rgba(0, 201, 107, 0.55); }
#game-view .cmp-serie-marke.s5  { font-size: clamp(2.2rem, 10vw, 3.8rem); color: var(--present-text); text-shadow: 0 0 28px rgba(255, 197, 61, 0.60); }
#game-view .cmp-serie-marke.s7  { font-size: clamp(2.4rem, 11vw, 4.2rem); color: var(--sky-300);       text-shadow: 0 0 30px rgba(56, 189, 248, 0.65); }
#game-view .cmp-serie-marke.s10 { font-size: clamp(2.6rem, 12vw, 4.6rem); color: var(--coral-300);       text-shadow: 0 0 34px rgba(255, 77, 109, 0.70); }

@keyframes serieMarke {
  0%   { opacity: 0; transform: scale(0.7) rotate(-4deg); }
  18%  { opacity: 1; transform: scale(1.08) rotate(-2deg); }
  32%  { transform: scale(1) rotate(-2deg); }
  75%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1.04) translateY(-14px) rotate(-2deg); }
}

/* Fotofinish getroffen: kurzes gold-weisses Aufblitzen, unabhaengig von der
   Serie. Die engste Rundenart ist die schwerste — das darf man sehen. */
#game-view .cmp-card-wrap.cmp-knapp-treffer { animation: knappTreffer 0.9s ease-out 1; }
@keyframes knappTreffer {
  0%   { box-shadow: 0 0 0 0 rgba(255, 232, 150, 0.9); }
  35%  { box-shadow: 0 0 0 4px rgba(255, 232, 150, 0.55), 0 0 60px rgba(255, 197, 61, 0.5); }
  100% { box-shadow: 0 0 0 0 rgba(255, 232, 150, 0); }
}

/* Letztes Leben: schwacher roter Rand, verbleibendes Herz pulsiert. Deutlich
   ruhiger als der Fehlerzustand, damit beides unterscheidbar bleibt. */
#game-view .cmp-card-wrap.cmp-letztes-leben { border-color: rgba(255, 77, 109, 0.34); }
#game-view .cmp-lives.knapp .cmp-life:not(.lost) { animation: herzPuls 1.4s ease-in-out infinite; }
@keyframes herzPuls {
  0%, 100% { transform: scale(1);    opacity: 1; }
  50%      { transform: scale(1.18); opacity: 0.75; }
}


/* Reduzierte Bewegung: Die globale Regel weiter oben in dieser Datei kappt
   bereits jede animation-duration. Hier bleibt nur, was sonst als
   Dauerschleife weiterliefe. */
@media (prefers-reduced-motion: reduce) {
  #game-view .cmp-lives.knapp .cmp-life:not(.lost) { animation: none; }
}

/* ==========================================================================
   Höher oder Tiefer — Ausbaustufe
   HUD, Timer, Schwierigkeitsanzeige, Risiko, Power-Ups
   ========================================================================== */

/* ---------- Kopfzeile: Leben, Combo, Punkte ---------- */
#game-view .cmp-hud {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 12px;
}
#game-view .cmp-life { font-size: 1.15rem; color: var(--coral-400); letter-spacing: 1px; }
#game-view .cmp-life.lost { color: var(--absent); }
#game-view .cmp-score b { font-size: 1.25rem; font-weight: 900; color: var(--ink); }

@keyframes comboPulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}

/* ---------- Timer ---------- */
#game-view .cmp-timer {
  position: relative;
  height: 5px; border-radius: 999px;
  background: var(--panel); margin-bottom: 22px;
}
#game-view .cmp-timer-fill {
  height: 100%; width: 100%; border-radius: 999px;
  background: var(--violet);
  transition: width .1s linear, background .3s ease;
}
#game-view .cmp-timer-fill.urgent { background: var(--coral-400); }
#game-view .cmp-timer-num {
  position: absolute; right: 0; top: 8px;
  font-size: 0.7rem; font-weight: 700; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Zweitrangige Schaltflaeche neben dem Haupt-Knopf. */
#game-view .action.ghost, .avatar-overlay .action.ghost {
  background: transparent; border: 1.5px solid var(--line); color: var(--muted);
}
#game-view .action.ghost:hover, .avatar-overlay .action.ghost:hover { border-color: var(--violet-text); color: var(--violet-text); }

/* ---------- Auswahlbildschirm ---------- */

/* ---------- Laufende Aufstellung im Spiel ---------- */

/* ---------- Pass and Play ---------- */
#game-view .cmp-duo-hud {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 14px;
}
#game-view .cmp-duo-seat {
  background: var(--panel); border: 1.5px solid var(--line); border-radius: 12px;
  padding: 8px 10px; text-align: center;
}
#game-view .cmp-duo-seat.active {
  border-color: var(--violet-text); background: rgba(var(--marke-rgb), 0.10);
}
#game-view .cmp-duo-seat.out { opacity: 0.45; }
#game-view .cmp-duo-name {
  font-size: 0.72rem; font-weight: 800; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 4px;
}
#game-view .cmp-duo-seat.active .cmp-duo-name { color: var(--violet-text); }
#game-view .cmp-duo-seat .cmp-score b { font-size: 1.05rem; }

@media (max-width: 600px) {
  
  
}

/* ---------- Schwierigkeit ---------- */

#game-view .cmp-diff {
  font-size: 0.7rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: 0.06em; padding: 3px 10px; border-radius: 999px;
}
#game-view .cmp-diff-leicht     { background: rgba(0, 201, 107, 0.16); color: var(--lime-400); }
#game-view .cmp-diff-mittel     { background: rgba(255, 197, 61, 0.16); color: var(--gold-400); }
#game-view .cmp-diff-schwer     { background: rgba(255, 122, 61, 0.18); color: var(--warn-text); }
#game-view .cmp-diff-fotofinish { background: rgba(255, 77, 109, 0.20); color: var(--rot-text); animation: comboPulse 1s ease-in-out infinite; }
#game-view .cmp-statlabel { font-size: 0.8rem; color: var(--muted); font-weight: 600; }

#game-view .cmp-card-wrap.cmp-photofinish {
  border-color: rgba(255, 77, 109, 0.35);
  box-shadow: 0 0 0 1px rgba(255, 77, 109, 0.2);
}

/* ---------- Kartenwerte ---------- */
#game-view .cmp-value b.unknown { color: var(--muted); }
#game-view .cmp-unit { font-size: 0.7rem !important; color: var(--muted); font-weight: 600 !important; display: block; }
#game-view .cmp-card.cmp-tie { border-color: var(--present-text); background: rgba(255, 197, 61, 0.10); }

/* ---------- Risiko ---------- */

/* ---------- Power-Ups ---------- */
#game-view .cmp-power-row {
  display: flex; gap: 8px; margin-top: 10px; justify-content: center; flex-wrap: wrap;
}
#game-view .cmp-power {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1.5px solid var(--line); color: var(--ink);
  border-radius: 12px; padding: 8px 14px; font-size: 0.8rem; font-weight: 700;
  font-family: inherit; cursor: pointer; transition: all .15s ease;
}
#game-view .cmp-power:hover:not(:disabled) { border-color: var(--violet-text); color: var(--violet-text); }
#game-view .cmp-power:disabled { opacity: 0.32; cursor: default; }
#game-view .cmp-power.armed {
  border-color: var(--violet-text); background: rgba(var(--marke-rgb), 0.14); color: var(--violet-text);
}
#game-view .cmp-power-n {
  background: var(--card); border-radius: 999px; padding: 1px 7px;
  font-size: 0.7rem; color: var(--muted);
}

/* ---------- Ergebnis ---------- */
#game-view .cmp-context {
  margin-top: 6px; font-size: 0.82rem; color: var(--muted); font-weight: 500;
}
#game-view .cmp-speed { color: var(--orange-text); font-weight: 800; }
#game-view .cmp-gameover {
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line);
  font-size: 0.85rem; color: var(--muted);
}

@media (max-width: 600px) {
  #game-view .cmp-hud { font-size: 0.9rem; }
  #game-view .cmp-power { padding: 7px 11px; font-size: 0.75rem; }
  
}

@media (prefers-reduced-motion: reduce) {
  #game-view .cmp-diff-fotofinish { animation: none; }
}

/* ==========================================================================
   Profil-Seite — gerettet aus der versehentlich nach i18n.js kopierten CSS
   (Zeichenkodierung korrigiert).
   ========================================================================== */
#game-view .profile-view { padding-top: 4px; }
#game-view .profile-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding-bottom: 28px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--line);
}
/* OHNE width/height — und das ist der Punkt.

   Hier standen 84 px, und weiter unten steht seit laengerem eine Regel mit
   132 px, samt Begruendung ("dieselbe Groesse wie ein Spielerfoto"). Die hat
   nie gewirkt: Das Profil laeuft entgegen dem Kommentar dort NICHT ueber
   #catalog-view, sondern liegt in #game-view — gemessen, die Elternkette ist
   #game-view > #game-container > .profile-view. Ein Selektor mit id schlaegt
   einen mit Klasse, also gewann die aeltere Regel, und der Avatar blieb bei
   84 px. Mit der Groesse hier heraus greifen die beiden Regeln unten wieder,
   132 px und am Handy 112 px. */
#game-view .profile-hero-avatar {
  position: relative;
  border-radius: 50%;
  background: var(--panel);
  border: 2px solid var(--violet-text);
  display: flex; align-items: center; justify-content: center;
  color: var(--violet-text);
}
/* Zwei verschiedene Dinge stehen in diesem Kreis. Das gezeichnete Gesicht
   fuellt ihn aus — es IST das Bild. Das Strichsymbol dagegen (freunde.js
   setzt fuer fremde Profile ICONS.player ein, es gibt dort keinen Avatar zum
   Zeichnen) ist ein Symbol und bleibt kleiner als sein Kreis; 60 statt 40,
   damit es im groesseren Kreis dasselbe Verhaeltnis behaelt. */
#game-view .profile-hero-avatar svg { width: 60px; height: 60px; }
#game-view .profile-hero-avatar svg.avatar-bild { width: 100%; height: 100%; }
/* Der Anker fuer das Level-Abzeichen. Ohne ihn richtet sich das Abzeichen am
   Seitencontainer aus und landet unten rechts am Ende der Profilseite —
   gemessen 2349 px unter einem Avatar, der bei 112 px steht. */
#game-view .profile-hero-avatarWrap {
  position: relative;
  display: inline-block;
  line-height: 0;          /* sonst steht unter dem Kreis eine Zeilenluecke */
}
/* UNTEN LINKS, nicht rechts: In der rechten unteren Ecke sitzt schon der
   Stift. So traegt jede Seite des Kreises ein Abzeichen. */
#game-view .profile-hero-level {
  position: absolute; bottom: 2px; left: -6px;
  line-height: 1;
  background: var(--violet);
  color: var(--on-solid);
  font-weight: 800;
  font-size: 0.78rem;
  min-width: 24px; height: 24px;
  border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  border: 3px solid var(--card);
  padding: 0 4px;
}
#game-view .profile-hero-name {
  font-family: "Archivo", "Inter", system-ui, sans-serif;
  font-size: clamp(1.9rem, 5vw, 3rem);
  font-weight: 900;
  letter-spacing: -0.03em;
  line-height: 1.02;
  margin: 4px 0 0;
  color: var(--ink);
  text-wrap: balance;
}
#game-view .profile-hero-xp {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  max-width: 320px;
}
#game-view .profile-hero-xp-track {
  width: 100%; height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}
#game-view .profile-hero-xp-fill {
  height: 100%;
  background: var(--violet);
  border-radius: 999px;
  transition: width 0.5s var(--ease-kinetic);
}
#game-view .profile-hero-xp-label { font-size: 0.8rem; color: var(--muted); }
#game-view .profile-stat-grid { grid-template-columns: repeat(2, 1fr); }
#game-view .profile-stat-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 16px 8px;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
}
#game-view .profile-stat-num {
  font-family: "Archivo", "Inter", system-ui, sans-serif;
  font-size: clamp(1.2rem, 3.2vw, 1.7rem);
  font-weight: 800;
  color: var(--violet-text);
  display: flex; align-items: center; gap: 4px;
  letter-spacing: -0.02em;
}
#game-view .profile-stat-num svg { width: 20px; height: 20px; }
#game-view .profile-stat-label {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: center;
}

/* ==========================================================================
   Profil — Ergänzungen im Manager-Karten-Stil (Rang, Sterne, Attributwerte)
   ========================================================================== */
#game-view .profile-rank {
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--violet, #6c47ff);
  margin-top: 2px;
}
/* ---- Die Rangleiter -----------------------------------------------------

   Zugeklappt unter der XP-Leiste. Der eigene Rang steht schon in der
   Zusammenfassung, damit man sie nicht oeffnen muss, um zu wissen, wo man
   steht — aufklappen beantwortet nur die Frage nach dem Weiter.

   Das Dreieck des Browsers ist weg: Es sitzt links und rueckt die Zeile ein,
   sie soll aber buendig unter der Leiste stehen. Gleiche Bauart wie
   .liga-verlauf und .fr-verlauf. */
#game-view .rang-legende {
  width: 100%; margin: 10px 0 2px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
}
#game-view .rang-legende > summary { list-style: none; cursor: pointer; }
#game-view .rang-legende > summary::-webkit-details-marker { display: none; }
#game-view .rang-legende__kopf {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 14px;
  font-size: 0.78rem; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
}
#game-view .rang-legende__jetzt { color: var(--violet-text); letter-spacing: 0.02em; }
#game-view .rang-legende[open] .rang-legende__kopf { border-bottom: 1px solid var(--line); }
#game-view .rang-liste { list-style: none; margin: 0; padding: 8px 14px 0; }
#game-view .rang-zeile {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline; gap: 10px;
  padding: 5px 0; font-size: 0.84rem;
  /* Erreichte Raenge treten zurueck, ohne zu verschwinden: Sie sind die
     Skala, an der man den eigenen Stand abliest. */
  color: var(--muted);
}
#game-view .rang-zeile__titel { font-weight: 700; }
#game-view .rang-zeile.ist-erreicht .rang-zeile__titel { color: var(--text); }
#game-view .rang-zeile.ist-jetzt .rang-zeile__titel { color: var(--violet-text); }
#game-view .rang-zeile__ab { font-size: 0.76rem; white-space: nowrap; }
#game-view .rang-zeile__rest {
  font-size: 0.76rem; font-variant-numeric: tabular-nums; white-space: nowrap;
  text-align: right; min-width: 74px;
}
#game-view .rang-haken { color: var(--violet-text); font-weight: 800; }
#game-view .rang-legende .hint { padding: 2px 14px 12px; margin: 0; }

#game-view .profile-stars { display: flex; gap: 4px; margin: 8px 0 4px; }
#game-view .profile-star { display: inline-flex; color: var(--line); }
#game-view .profile-star svg { width: 18px; height: 18px; }
#game-view .profile-star.on { color: var(--present, #E9A23B); }

/* Stärkster Modus — Kurzfassung über der Attributliste */
#game-view .profile-best {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 12px 16px;
  margin-bottom: 20px;
}
#game-view .profile-best-label {
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .profile-best-name { font-weight: 800; color: var(--ink); margin-right: auto; }

/* Wertchip 1–20, farbcodiert wie in einer Manager-Aufstellung */
#game-view .profile-attr-chip {
  min-width: 34px;
  text-align: center;
  font-weight: 900;
  font-size: 0.9rem;
  padding: 5px 8px;
  border-radius: 8px;
  background: var(--absent);
  color: var(--ink-0);
}
#game-view .profile-attr-chip.stark { background: var(--correct, #17A65A); }
#game-view .profile-attr-chip.mittel { background: var(--violet, #6c47ff); }
#game-view .profile-attr-chip.schwach { background: var(--orange, #EA4F23); }
#game-view .profile-attr-chip.leer { background: var(--line); color: var(--muted); }


/* ==========================================================================
   Liga: gründen/beitreten, Saison-Tabelle, direkte Duelle
   ========================================================================== */
#game-view .liga-view { padding-top: 4px; }
/* Der Weg zurueck zur Reiterliste. Eigene Zeile ueber dem Ligennamen und
   nicht neben ihm: Der Name kann lang sein, und ein Zurueck, das je nach
   Namenslaenge umbricht, steht mal hier und mal dort. */
#game-view .liga-zurueck {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  margin-bottom: 6px;
  padding: 0;
  font-size: 0.86rem;
}

#game-view .liga-kopf { margin-bottom: 22px; }
#game-view .liga-code-zeile {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 8px;
}
#game-view .liga-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.15rem; font-weight: 900; letter-spacing: 0.18em;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 6px 14px; color: var(--ink);
}
#game-view .liga-mitglieder { font-size: 0.8rem; color: var(--muted); margin-left: auto; }

/* Das aufklappende Formular hinter "Freunde einladen" — steht direkt unter
   der Code-Zeile, aus der der Knopf kommt, `width: 100%`, weil es sonst neben
   dem Code stehen bleibt statt darunter (flex-wrap bricht Zeilen um, nicht
   Blockrichtung). */
#game-view .liga-einladen-form { width: 100%; margin-top: 4px; }
#game-view .liga-einladen-liste { list-style: none; margin: 0; padding: 0; }
#game-view .liga-einladen-zeile {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 8px 0;
}
#game-view .liga-einladen-zeile + .liga-einladen-zeile { border-top: 1px solid var(--line); }
#game-view .liga-einladen-name { font-weight: 700; font-size: 0.9rem; }

/* Die Einladungen ueber "Aktive Ligen" — dieselbe Zeilenform wie
   .liga-meine, aber mit zwei Knoepfen statt eines Pfeils, weil hier eine
   Entscheidung ansteht statt nur ein Weg hinein. */
#game-view .liga-einladungen {
  list-style: none; margin: 6px 0 16px; padding: 0;
  border: 1px solid var(--violet); border-radius: 12px;
  background: rgba(0, 229, 122, 0.08);
}
#game-view .liga-einladung {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px; padding: 12px 14px;
}
#game-view .liga-einladung + .liga-einladung { border-top: 1px solid var(--line); }
#game-view .liga-einladung__text { font-size: 0.9rem; font-weight: 700; flex: 1 1 180px; }
#game-view .liga-einladung__aktionen { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
#game-view .liga-einladung__annehmen { padding: 8px 16px; font-size: 0.85rem; min-height: 0; }
#game-view .liga-einladung__ablehnen { font-size: 0.8rem; }

#game-view .liga-karte {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 18px; margin-bottom: 14px;
  display: flex; flex-direction: column; gap: 12px;
}
#game-view .liga-karte-titel {
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .liga-karte input { max-width: 100%; }

/* Flex, damit rechts etwas stehen kann: die Restzeit der Saison und der
   Sammelknopf. Vorher war es eine Blockzeile, und `margin-left: auto` am
   Knopf tat schlicht nichts — er klebte an der Ueberschrift. Im Browser
   gesehen, nicht am Selektor abgelesen.

   `gap` statt Abstaenden an den Kindern, und `align-items: center`, weil der
   Knopf hoeher ist als die 0,7-rem-Schrift daneben. */
#game-view .liga-abschnitt-titel {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); margin: 24px 0 10px;
}

/* Saison-Tabelle */
#game-view .liga-tabelle { display: flex; flex-direction: column; gap: 4px; }
#game-view .liga-zeile {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 58px 42px 42px 52px;
  align-items: center; gap: 8px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: 10px 12px; font-size: 0.9rem;
}
#game-view .liga-kopfzeile {
  background: none; border: none; padding: 2px 12px;
  font-size: 0.66rem; font-weight: 800; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .liga-zeile.ich { border-color: var(--violet, #6c47ff); background: rgba(var(--violet-rgb), 0.1); }
#game-view .liga-platz { font-weight: 900; color: var(--muted); text-align: center; }
#game-view .liga-platz.top { color: var(--present, #E9A23B); }
#game-view .liga-zeile .liga-name {
  font-weight: 700; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#game-view .liga-punkte { font-weight: 900; color: var(--violet, #6c47ff); }

/* "Sp" — ausgetragene Duelle, als kleine Kachel statt als nackte Zahl. Die
   Spalte ist gemittelt statt rechtsbuendig: Ein einzelnes Tile liest sich in
   der Mitte seiner Spalte als Tile, rechtsbuendig saehe es aus wie eine
   halbfertige Zahlenspalte. Dieselbe Bauweise wie .liga-form__x daneben —
   Kreis statt Reihe, weil hier immer genau ein Wert steht. */
#game-view .liga-spiele { display: flex; justify-content: center; min-width: 0; }
#game-view .liga-spiele__kachel {
  box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center;
  height: 20px; padding: 0 6px; max-width: 100%;
  border-radius: 7px; background: var(--color-bg-inset, var(--line));
  font-style: normal; font-weight: 800; font-size: 0.76rem; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Duell fordern */
#game-view .liga-fordern {
  display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 14px 16px; margin-bottom: 14px;
}
#game-view .liga-fordern select { min-width: 150px; }

/* Duell-Liste */
#game-view .liga-duelle { display: flex; flex-direction: column; gap: 6px; }
#game-view .liga-duell {
  display: grid;
  /* FUENF SPALTEN, nicht vier: Gegner, Modus, Stand, Status — und der Knopf.
     Bei vieren fiel er als fuenftes Kind in eine neue Rasterzeile, landete in
     Spalte 1 (1fr) und zog sich ueber die ganze Breite. Sichtbar wurde das
     erst, als "Du bist dran" nach oben kam und die Zeile gross wurde. */
  grid-template-columns: minmax(0, 1fr) auto auto auto auto;
  align-items: center; gap: 10px;
  background: var(--panel); border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: 12px; padding: 10px 14px; font-size: 0.88rem;
}
#game-view .liga-duell.dran { border-left-color: var(--violet, #6c47ff); }
#game-view .liga-duell.gewonnen { border-left-color: var(--correct, #17A65A); }
/* `--rot-text` und nicht `--orange`: Gold steht im Farbsystem fuer XP und
   Trophaeen, die Niederlage ist Koralle — die Freundesliste macht es
   nebenan schon so. Aufgefallen ist es erst am 12.09.2026, und zwar aus
   einem Grund: Dieser Abschnitt wurde NIE gezeichnet, weil der Duell-Liste
   das Feld `entschieden` fehlte. Die Farbe war also seit jeher falsch und
   hat niemand gesehen. */
#game-view .liga-duell.verloren { border-left-color: var(--rot-text, #FF6B85); }
#game-view .liga-duell-gegner { font-weight: 800; color: var(--ink); }
#game-view .liga-duell-modus { font-size: 0.78rem; color: var(--muted); }
#game-view .liga-duell-stand { font-weight: 900; color: var(--violet, #6c47ff); white-space: nowrap; }
#game-view .liga-duell-status { font-size: 0.76rem; color: var(--muted); white-space: nowrap; }
/* "Spielen" und "Zurückziehen" koennen beide stehen — wer selbst gefordert
   hat und noch nicht dran war, sieht beide. EIN Kind im Raster statt zwei:
   ohne den Umschlag waere der Knopf, der als fuenftes Kind neben die
   bestehenden vier passte, beim sechsten ein Rasterzeilenumbruch, der ueber
   die volle Breite zieht — derselbe Fehler, den der Kommentar bei der
   Spaltenzahl oben schon einmal beschreibt, nur eine Spalte weiter. */
#game-view .liga-duell-aktionen { display: flex; gap: 6px; justify-self: end; }
#game-view .liga-duell .action,
#game-view .liga-duell .secondary { padding: 6px 14px; font-size: 0.82rem; }

#game-view .liga-hinweis { font-size: 0.78rem; color: var(--muted); font-style: italic; margin-top: 14px; }

@media (max-width: 600px) {
  #game-view .liga-zeile { grid-template-columns: 28px minmax(0,1fr) 50px 34px 34px 44px; font-size: 0.82rem; gap: 6px; }
  #game-view .liga-duell { grid-template-columns: minmax(0,1fr) auto; row-gap: 6px; }
  #game-view .liga-fordern { flex-direction: column; align-items: stretch; }
}



/* ==========================================================================
   Impostor: Abstimmung, Rateversuch, Punktestand
   ========================================================================== */

/* ---------- Abstimmung ---------- */
/* auto-fit statt fester Spaltenzahl: 3 bis 15 Mitspieler sollen alle ohne
   eigenen Umbruchpunkt sauber aufgehen. */
#game-view .impo-tipps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(58px, 1fr));
  gap: 10px;
  margin: 18px 0;
}
#game-view .impo-tipp {
  aspect-ratio: 1;
  border: 1.5px solid var(--line);
  border-radius: 16px;
  background: var(--panel);
  color: var(--text);
  font-size: 1.35rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
}
#game-view .impo-tipp:active { transform: scale(0.94); }
#game-view .impo-tipp[aria-pressed="true"] {
  background: var(--violet);
  border-color: var(--violet);
  color: var(--on-solid);
}

/* ---------- Rateversuch ----------
   Hier standen .impo-optionen und .impo-option: das Raster mit sechs
   Woertern zur Wahl. Der Maulwurf bekommt keine Auswahl mehr, er sagt das
   Wort laut — geblieben sind zwei Knoepfe fuer die Runde. */
#game-view .impo-rateknoepfe {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 18px 0 4px;
}
@media (min-width: 520px) {
  #game-view .impo-rateknoepfe { flex-direction: row; justify-content: center; }
  #game-view .impo-rateknoepfe .action { min-width: 190px; }
}

/* ---------- Punktestand ---------- */
#game-view .impo-tabelle {
  margin: 12px 0 22px;
  text-align: left;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
}
#game-view .impo-zeile {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
  font-weight: 650;
}
#game-view .impo-zeile:last-child { border-bottom: none; }
/* Die Impostor der eben gespielten Runde bleiben markiert — sonst muss man
   beim Punktelesen wieder nach oben scrollen, um sie zuzuordnen. */
#game-view .impo-zeile.war-impostor { color: var(--coral-300); }
#game-view .impo-plus {
  font-variant-numeric: tabular-nums;
  color: var(--violet-text);
  font-weight: 800;
}
#game-view .impo-summe {
  min-width: 2.2ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 1.15rem;
  font-weight: 800;
}
#game-view .impo-name.ist-impostor { color: var(--coral-300); }

/* ==========================================================================
   Höher oder Tiefer: automatischer Rundenwechsel

   Der Weiter-Knopf laeuft von selbst ab. Der Balken zeigt die verbleibende
   Zeit, ein Klick kuerzt sie ab. So bleibt das Spiel im Fluss, ohne dass
   jemand die Aufloesung verpasst.
   ========================================================================== */
#game-view .cmp-next-auto {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

#game-view .cmp-next-bar {
  position: absolute;
  left: 0; bottom: 0;
  height: 3px;
  width: 100%;
  background: currentColor;
  opacity: 0.55;
  pointer-events: none;
  border-radius: 0 2px 2px 0;
}

/* Wer reduzierte Bewegung eingestellt hat, sieht keinen laufenden Balken.
   Der automatische Wechsel selbst bleibt — er ist keine Animation. */
@media (prefers-reduced-motion: reduce) {
  #game-view .cmp-next-bar { display: none; }
}

/* ==========================================================================
   Höher oder Tiefer — Spielbildschirm, überarbeitet
   Ein Band weniger je Information: Kopfzeile, Frage, Karten, Fußzeile.
   Alle Regeln unter #game-view. Was an document.body hängt (Konfetti,
   Pokalregen), steht weiter oben global — sonst greift es nicht.
   ========================================================================== */

/* ---------- Kopfzeile: Leben · Punkte · Combo in einer Zeile ---------- */
#game-view .cmp-hud {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 12px; margin-bottom: 14px;
}
#game-view .cmp-hud .cmp-lives { justify-self: start; }
#game-view .cmp-hud .cmp-score { justify-self: center; }
#game-view .cmp-lives { font-size: 1rem; letter-spacing: 2px; line-height: 1; }
#game-view .cmp-score b {
  font-size: 1.6rem; font-weight: 900; color: var(--ink);
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
/* ---------- Frage ---------- */
#game-view .cmp-ask { text-align: center; margin-bottom: 18px; }
#game-view .cmp-question {
  font-size: 1.3rem; font-weight: 800; letter-spacing: -0.02em;
  color: var(--ink); line-height: 1.25; margin-bottom: 6px;
}
#game-view .cmp-statline {
  display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap;
}
#game-view .cmp-statlabel { font-size: 0.75rem; color: var(--muted); font-weight: 600; }

/* ---------- Karten ---------- */
#game-view .cmp-card {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  text-align: center; padding: 18px 14px;
}
#game-view .cmp-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; }
#game-view .cmp-flag { font-size: 1.35rem; line-height: 1; }
#game-view .cmp-name {
  font-weight: 800; font-size: 1.05rem; color: var(--ink); letter-spacing: -0.01em;
}
#game-view .cmp-role { font-size: 0.78rem; color: var(--violet-text); font-weight: 700; }
#game-view .cmp-meta {
  font-size: 0.72rem; color: var(--muted); line-height: 1.35;
  /* Vereinsliste darf zwei Zeilen brauchen, aber nicht die Karte sprengen. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
#game-view .cmp-value { margin-top: 10px; }
#game-view .cmp-value b {
  display: block; font-size: 1.75rem; font-weight: 900; color: var(--orange-text);
  line-height: 1.1; font-variant-numeric: tabular-nums;
}
#game-view .cmp-unit {
  display: block; font-size: 0.68rem; color: var(--muted); font-weight: 600;
}

/* ---------- Auflösung ---------- */
#game-view .cmp-out {
  margin-top: 14px; padding: 12px 14px; border-radius: 12px;
  border: 1.5px solid var(--line); background: var(--panel); text-align: center;
}
#game-view .cmp-out-head {
  font-size: 0.95rem; font-weight: 800; letter-spacing: -0.01em; color: var(--ink);
}
#game-view .cmp-out-head b { color: inherit; }
#game-view .cmp-out-win { border-color: var(--correct-text); background: rgba(23, 166, 90, 0.10); }
#game-view .cmp-out-win .cmp-out-head { color: var(--correct-text); }
#game-view .cmp-out-lose { border-color: var(--coral-400); background: rgba(255, 77, 109, 0.10); }
#game-view .cmp-out-lose .cmp-out-head { color: var(--rot-text); }
#game-view .cmp-context { margin-top: 4px; font-size: 0.8rem; color: var(--muted); font-weight: 500; }

/* ---------- Bilanz am Ende eines Laufs ---------- */
#game-view .cmp-bilanz {
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); text-align: left;
}
#game-view .cmp-bilanz-titel {
  font-size: 1.5rem; font-weight: 900; color: var(--ink); text-align: center;
  letter-spacing: -0.02em; margin-bottom: 10px; font-variant-numeric: tabular-nums;
}
#game-view .cmp-bilanz-zeile {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 5px 0; font-size: 0.82rem; color: var(--muted);
}
#game-view .cmp-bilanz-zeile b { color: var(--ink); font-weight: 800; font-variant-numeric: tabular-nums; }
#game-view .cmp-bilanz-zeile.hoch b, #game-view .cmp-bilanz-zeile.hoch span { color: var(--gold-400, #FFC53D); }
#game-view .cmp-bilanz-zeile.leise { opacity: 0.7; }

/* Prozentrang: ein Balken sagt mehr als die Zahl allein. */
#game-view .cmp-rang { margin-top: 10px; }
#game-view .cmp-rang-text { font-size: 0.82rem; color: var(--muted); margin-bottom: 6px; }
#game-view .cmp-rang-text b { color: var(--violet-text); font-weight: 900; }
#game-view .cmp-rang-bar {
  height: 6px; border-radius: 999px; background: var(--panel); overflow: hidden;
}
#game-view .cmp-rang-fill {
  height: 100%; border-radius: 999px; background: var(--violet);
  transition: width .6s cubic-bezier(.22,1,.36,1);
}

/* ---------- Weiter-Knopf mit Countdown ---------- */
#game-view .cmp-next-count {
  margin-left: 8px; font-size: 0.8rem; opacity: 0.75;
  font-variant-numeric: tabular-nums;
}

/* ---------- Fußzeile: unter welchen Bedingungen läuft der Lauf ---------- */
#game-view .cmp-foot {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line);
}
#game-view .cmp-foot-tags { font-size: 0.72rem; color: var(--muted); font-weight: 600; }
#game-view .cmp-foot-btn {
  background: none; border: none; padding: 0;
  font-family: inherit; font-size: 0.72rem; font-weight: 700;
  color: var(--violet-text); cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px;
}
#game-view .cmp-foot-btn:hover { opacity: 0.75; }

@media (max-width: 600px) {
  #game-view .cmp-question { font-size: 1.12rem; }
  #game-view .cmp-value b { font-size: 1.5rem; }
  #game-view .cmp-card { padding: 14px 12px; }
}

/* Bilanz als eigener, neutraler Kasten — nicht im roten Fehlerkasten. */
#game-view .cmp-bilanz-kasten {
  margin-top: 12px; padding: 16px 16px 14px; border-top: none;
  border: 1.5px solid var(--line); border-radius: 12px; background: var(--panel);
}

/* Sekunden am Timer, ohne dass das Skript die Einheit mitschreiben muss. */
#game-view .cmp-timer-num::after { content: " s"; opacity: 0.7; }

/* Combo bleibt schlichter Text und wird erst bei einer Serie zur Plakette. */
/* ---------- Handy: Karten bleiben nebeneinander ----------
   Ein Vergleichsspiel, bei dem man zum Vergleichen scrollen muss, ist keins.
   Die ältere Regel stellt sie unter 600px untereinander — hier wieder
   zurückgeholt und dafür alles enger gesetzt. */
@media (max-width: 600px) {
  #game-view .cmp-grid {
    grid-template-columns: 1fr auto 1fr;
    gap: 6px; align-items: stretch;
  }
  #game-view .cmp-vs { padding: 0; font-size: 0.7rem; align-self: center; }
  #game-view .cmp-card { padding: 12px 8px; gap: 2px; }
  #game-view .cmp-card-head { flex-direction: column; gap: 3px; }
  #game-view .cmp-flag { font-size: 1.15rem; }
  #game-view .cmp-name { font-size: 0.88rem; line-height: 1.2; }
  #game-view .cmp-role { font-size: 0.68rem; }
  #game-view .cmp-meta { font-size: 0.64rem; -webkit-line-clamp: 3; }
  #game-view .cmp-value { margin-top: 8px; }
  #game-view .cmp-value b { font-size: 1.3rem; }
  #game-view .cmp-unit { font-size: 0.6rem; }

  #game-view .cmp-foot { flex-wrap: wrap; row-gap: 4px; }
  #game-view .cmp-score b { font-size: 1.4rem; }
}

/* ==========================================================================
   Höher oder Tiefer — der Startbildschirm
   Weniger Kästen, mehr Luft. Farbe trägt nur die Auswahl, alles andere ist
   neutral. Haarlinien statt Rahmen um jedes Element.

   Die Schrittzählung ("Schritt 1 von 2") stand hier, solange es zwei Seiten
   gab. Seit der Grad in der Leiste über dem Spiel sitzt, ist es eine.
   ========================================================================== */

#game-view .cmp-wizard { padding-top: 28px; }

#game-view .cmp-wiz-head { margin-bottom: 26px; }
#game-view .cmp-wiz-title {
  font-family: var(--font-display, inherit);
  font-size: 2rem; font-weight: 800; letter-spacing: -0.03em;
  line-height: 1.05; color: var(--ink); margin: 0;
}

#game-view .cmp-setup-problem {
  margin: 0 0 20px; padding: 10px 12px; border-radius: 10px;
  border: 1px solid rgba(255, 77, 109, 0.4); background: rgba(255, 77, 109, 0.08);
  font-size: 0.82rem; color: var(--coral-300);
}

/* ---------- Startkarte der Tages-Challenge ----------
   Keine Schaltflächen, sondern drei Angaben: was heute ansteht und unter
   welchen Bedingungen. Die Vorgabe ist für alle gleich, hier gibt es nichts
   zu wählen — deshalb Zeilen und keine Auswahlzeilen. */
#game-view .cmp-tages-fakten {
  list-style: none; margin: 0 0 26px; padding: 0;
  border-top: 1px solid var(--line);
}
#game-view .cmp-tages-fakten li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 13px 4px; border-bottom: 1px solid var(--line);
}
#game-view .cmp-tages-fakten b {
  font-size: 0.95rem; font-weight: 700; color: var(--ink);
}
#game-view .cmp-tages-fakten span {
  font-size: 0.8rem; color: var(--muted); text-align: right;
}

/* HIER STANDEN DIE GROSSEN AUSWAHLZEILEN (.cmp-pick*) — "Allein" und "Zu
   zweit" im Einrichtungsbildschirm von Kopf an Kopf. Weg seit dem
   11. September 2026: Der Modus oben beantwortet die Frage schon, und zwei
   Knoepfe, die dem Knopf darueber widersprechen koennen, sind keine
   Einstellung, sondern eine Falle. Siehe loadCompareChoice() in app.js. */

/* ---------- Nebenentscheidungen: Umschaltleiste ---------- */
#game-view .cmp-seg-group { margin-bottom: 22px; }
#game-view .cmp-seg-label {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 8px;
}
#game-view .cmp-seg {
  display: flex; gap: 3px; padding: 3px;
  background: var(--panel); border-radius: 11px; border: 1px solid var(--line);
}
#game-view .cmp-seg-btn {
  flex: 1 1 0; padding: 9px 10px; border: none; border-radius: 8px;
  background: none; color: var(--muted);
  font-family: inherit; font-size: 0.84rem; font-weight: 700;
  cursor: pointer; transition: all .15s ease;
}
#game-view .cmp-seg-btn:hover:not(:disabled):not(.active) { color: var(--ink); }
/* Nicht var(--card) nehmen: das ist dunkler als --panel, der aktive Knopf
   sähe aus wie ein Loch statt wie ausgewählt. */
#game-view .cmp-seg-btn.active {
  background: rgba(var(--marke-rgb), 0.14); color: var(--violet-text);
}
#game-view .cmp-seg-btn:disabled { opacity: 0.3; cursor: default; }
/* Hier standen die Regeln fuer den Zeitraum (.cmp-chipline/.cmp-miniChip),
   die Notiz darunter (.cmp-seg-note) und die Extras-Schalter (.cmp-switch*).
   Alle drei Bloecke sind mit ihrer Auswahl aus Schritt 2 verschwunden — siehe
   schritt2() in app.js. */

@media (max-width: 600px) {
  #game-view .cmp-wiz-title { font-size: 1.6rem; }
  #game-view .cmp-wizard { padding-top: 20px; }
}

/* ==========================================================================
   Rundenarten: Zuordnung und Bonuskette
   ========================================================================== */

/* ---------- Zuordnung: die Zahl steht offen über der Frage ---------- */
/* Die Einheit stand als Bildunterschrift unter der Zahl und in 0.7rem — "630"
   gross, "Spiele" klein darunter. Gelesen wird aber ein Satzteil: 630 Spiele.
   Also dieselbe Groesse, in einer Zeile, und nur ueber das Gewicht getrennt,
   damit die Zahl trotzdem zuerst gesehen wird. */
#game-view .cmp-zahl { margin-bottom: 10px; line-height: 1.1; }
#game-view .cmp-zahl b {
  display: inline; font-family: var(--font-display, inherit);
  font-size: 2.6rem; font-weight: 900; color: var(--orange-text);
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
}
#game-view .cmp-zahl .cmp-unit {
  /* Die negative Laufweite der Zahl frisst das Leerzeichen zwischen beiden auf,
     also kommt der Abstand hier her und nicht aus dem Markup. */
  display: inline !important; margin-top: 0; margin-left: 0.14em;
  font-family: var(--font-display, inherit);
  font-size: 2.6rem !important; font-weight: 600 !important;
  color: var(--orange-text); letter-spacing: -0.02em;
}

/* ---------- Bonusrunde ---------- */
#game-view .cmp-bonus-marke {
  display: inline-block; margin-bottom: 8px;
  padding: 3px 10px; border-radius: 999px;
  background: rgba(255, 197, 61, 0.14); color: var(--gold-400, #FFC53D);
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
}

#game-view .cmp-kette { display: flex; flex-direction: column; gap: 6px; }
#game-view .cmp-kette-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 11px 12px; border-radius: 12px;
  border: 1.5px solid var(--line); background: var(--panel);
  font-family: inherit; text-align: left; cursor: pointer;
  transition: all .15s ease;
}
#game-view .cmp-kette-row:hover:not(:disabled) { border-color: var(--violet-text); }
#game-view .cmp-kette-row:disabled { cursor: default; }
#game-view .cmp-kette-nr {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line); color: var(--muted);
  font-size: 0.8rem; font-weight: 900; font-variant-numeric: tabular-nums;
}
#game-view .cmp-kette-row.gewaehlt {
  border-color: var(--violet-text); background: rgba(var(--marke-rgb), 0.10);
}
#game-view .cmp-kette-row.gewaehlt .cmp-kette-nr {
  border-color: var(--violet); background: var(--violet); color: var(--ink-950, #080C0A);
}
#game-view .cmp-kette-row.treffer { border-color: var(--correct-text); background: rgba(23, 166, 90, 0.10); }
#game-view .cmp-kette-row.treffer .cmp-kette-nr { border-color: var(--correct-text); color: var(--correct-text); }
#game-view .cmp-kette-row.daneben { border-color: rgba(255, 77, 109, 0.5); opacity: 0.8; }
#game-view .cmp-kette-row.daneben .cmp-kette-nr { border-color: var(--rot-text); color: var(--rot-text); }
#game-view .cmp-kette-text { flex: 1 1 auto; min-width: 0; }
#game-view .cmp-kette-name {
  display: block; font-size: 0.92rem; font-weight: 800; color: var(--ink);
  letter-spacing: -0.01em;
}
#game-view .cmp-kette-meta {
  display: block; margin-top: 1px; font-size: 0.7rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#game-view .cmp-kette-wert {
  flex: 0 0 auto; font-size: 0.95rem; font-weight: 900; color: var(--orange-text);
  font-variant-numeric: tabular-nums;
}
#game-view .cmp-kette-hilfe {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  margin-top: 10px; font-size: 0.72rem; color: var(--muted);
}

/* ---------- Trefferquote unter der Auflösung ---------- */
#game-view .cmp-quote {
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line);
  font-size: 0.76rem; color: var(--muted); font-weight: 600;
}

@media (max-width: 600px) {
  #game-view .cmp-zahl b,
  #game-view .cmp-zahl .cmp-unit { font-size: 2.1rem !important; }
  #game-view .cmp-kette-row { padding: 9px 10px; gap: 9px; }
  #game-view .cmp-kette-name { font-size: 0.84rem; }
}

/* ---------- Rückblick auf die vorige Runde ---------- */
#game-view .cmp-rueckblick { opacity: 0.96; }
#game-view .cmp-rueckblick-kopf {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 16px;
  padding-bottom: 10px; border-bottom: 1px solid var(--line);
}
#game-view .cmp-rueckblick-marke {
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .cmp-rueckblick-hinweis { font-size: 0.72rem; color: var(--violet-text); font-weight: 600; }
/* Im Rückblick wird nicht gespielt — die Karten sind reine Anzeige. */
#game-view .cmp-rueckblick .cmp-card { cursor: default; }

/* Die Fußzeile trägt jetzt bis zu drei Elemente. */
#game-view .cmp-foot { justify-content: space-between; }
#game-view .cmp-foot-tags { text-align: center; flex: 1 1 auto; }

/* .cp-mode-hint und der Reihenfolge-Schalter .cp-order-* sind weg
   (09.09.2026). Die Erklaerzeile macht jetzt .modus-hinweis im gemeinsamen
   Kopf, und "chronologisch / gemischt" ist keine eigene Leiste mehr, sondern
   der Grad — Experte mischt, entschieden im Server. */

/* ==========================================================================
   Der gemeinsame Spiel-Kopf

   Dieselbe Leiste ueber jedem Spiel: Modus-Knoepfe, eine Zeile was der Modus
   bedeutet, grosser Titel, Tagline, Serie. Die Regeln stehen bewusst NEBEN
   den cp-*-Regeln der Flugroute und nicht als zweite Kopie: Flugroute war
   die Vorlage, und zwei Saetze Werte fuer dasselbe Aussehen laufen frueher
   oder spaeter auseinander. Wer hier etwas aendert, aendert es fuer alle
   neun Spiele gleichzeitig — das ist der Sinn.
   ========================================================================== */
#game-view .spiel-kopf { margin-bottom: 4px; }
#game-view .modus-reihe { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
#game-view .modus-btn {
  background: var(--card);
  border: 1.5px solid var(--line);
  color: var(--muted);
  border-radius: 999px;
  padding: 7px 16px;
  font-size: 0.85rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
#game-view .modus-btn:hover { color: var(--ink); border-color: var(--ink); }
#game-view .modus-btn.active {
  background: var(--ink); color: var(--on-ink); border-color: var(--ink); font-weight: 700;
}
#game-view .modus-hinweis {
  margin: 6px 0 0;
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.35;
}
#game-view .spiel-titel {
  margin: 10px 0 2px;
  font-size: clamp(1.8rem, 4.5vw, 2.4rem);
  font-weight: 900;
  letter-spacing: -0.04em;
  color: var(--ink);
}
#game-view .spiel-tagline { margin: 0 0 6px; color: var(--muted); font-size: 0.95rem; }

/* ---- Der Spielkopf auf dem Telefon --------------------------------------

   Gemeldet: "Die Spiele selber sollten auf eine Seite passen, damit man
   waehrend eines Spiels nicht scrollen muss."

   GEMESSEN, WOHIN DIE PIXEL GEHEN, bei 375 x 812 und vor jedem Eingriff:

     Spiel        Seite   Kopf   Modusreihe   Gradleiste
     Quiz         1391    245    38           64
     Kaderbau     1343    238    38           64
     Flugroute    1204    187    84            0
     Die Elf      1101    187    84            0
     Rangfolge     987    211    84            0

   Der Kopf allein kostet also 187 bis 245 px, dazu 60 px Spielleiste — rund
   ein Drittel des Schirms, bevor das Spiel anfaengt. Und bei vier Spielen
   BRICHT DIE MODUSREIHE UM: 84 px statt 38, weil drei Knoepfe mit
   "Rätsel des Tages #58" bei 375 px nicht in eine Zeile passen.

   Was hier schrumpft, ist ausschliesslich Beiwerk:

     - Die Tagline faellt weg. Sie beschreibt das Spiel, das man gerade
       geoeffnet hat; der Titel darueber sagt dasselbe kuerzer.
     - Der Titel wird kleiner. Er bleibt die groesste Schrift auf dem
       Schirm, nur eben nicht mehr 2,4 rem.
     - Die Modusreihe scrollt seitlich, statt umzubrechen. Sie behaelt alle
       drei Knoepfe und ihre Groesse — was sich aendert, ist, dass die
       zweite Zeile entfaellt.

   Was NICHT schrumpft, sind die Knoepfe selbst: Die Modus- und Gradwahl
   bleibt in Fingergroesse. Ein Spiel auf einen Schirm zu bekommen, indem
   man seine Bedienung verkleinert, waere der falsche Handel. */
@media (max-width: 559px) {
  #game-view .spiel-tagline { display: none; }

  #game-view .spiel-titel {
    margin: 6px 0 2px;
    font-size: 1.55rem;
  }

  /* Seitlich scrollen statt umbrechen. `scrollbar-width: none` blendet die
     Leiste aus — auf dem Telefon gibt es ohnehin keine sichtbare —, und
     das negative Randmass laesst die Knoepfe bis an den Bildschirmrand
     laufen, statt in der Kartenpolsterung zu enden. */
  #game-view .modus-reihe {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin-bottom: 8px;
    padding-inline: 16px;
    margin-inline: -16px;
  }
  #game-view .modus-reihe::-webkit-scrollbar { display: none; }
  #game-view .modus-btn { flex: 0 0 auto; }

  #game-view .grad-reihe { margin: 6px 0 0; gap: 5px; }
  #game-view .modus-hinweis { margin-top: 4px; }
}
/* Die Schwierigkeitswahl. Nur im freien Spiel sichtbar — im Tagesmodus gibt
   es nichts zu waehlen, und ein Regler ohne Wirkung ist ein gebrochenes
   Versprechen. Kleiner als die Modus-Knoepfe: Der Modus entscheidet, WAS man
   spielt, der Grad nur WIE schwer. */
#game-view .grad-reihe {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin: 10px 0 2px;
}
#game-view .grad-titel {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted); margin-right: 4px;
}
#game-view .grad-btn {
  padding: 4px 11px; border-radius: 999px; border: 1px solid var(--line);
  background: transparent; color: var(--muted);
  font-family: inherit; font-weight: 600; font-size: 0.76rem; cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
#game-view .grad-btn:hover { color: var(--ink); border-color: var(--ink); }
/* Lime-Tint statt --card: In diesem Thema ist --card DUNKLER als --panel, ein
   aktiver Zustand daraus reisst ein Loch statt etwas hervorzuheben. Steht so
   auch in CLAUDE.md unter "Zum Design". */
#game-view .grad-btn.active {
  background: rgba(var(--marke-rgb), 0.14); border-color: var(--violet); color: var(--ink);
}
/* Dieselbe Leiste ueber der laufenden Runde von Kopf an Kopf.

   Dort steht sie in einer Karte, die ohnehin voll ist, und auf 375 px brach
   sie um: "SCHWIERIGKEIT Leicht Medium" in der ersten Zeile, "Experte"
   allein in der zweiten. Eine Auswahl, die aussieht, als waere die letzte
   Moeglichkeit abgefallen.

   Das Wort davor faellt deshalb auf schmalen Schirmen weg, nicht eine der
   drei Stufen: Leicht · Medium · Experte erklaeren sich nebeneinander von
   selbst, und welche gerade laeuft, steht ausserdem in der Fusszeile. Der
   Wegfall ist nur sichtbar, nicht hoerbar — aria-label bleibt an der Leiste,
   also sagt ein Screenreader weiterhin, worum es hier geht. */
@media (max-width: 460px) {
  #game-view .cmp-card-wrap .grad-titel { display: none; }
  #game-view .cmp-card-wrap .grad-reihe { justify-content: center; }
}

#game-view .spiel-serie {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  font-size: 0.9rem;
  color: var(--ink);
}
#game-view .spiel-serie b { color: var(--orange-text); font-weight: 800; }
/* Ein Archivlauf sagt es selbst. Ohne die Zeile saehe er aus wie die heutige
   Aufgabe, und niemand verstuende, warum die Serie sich nicht ruehrt. */
/* Der Aufgeben-Weg. Zurueckhaltend: Er ist ein Ausweg, keine Spielaktion —
   und er darf nie so aussehen, als waere er der naechste Schritt. */
#game-view .cp-aufgeben { margin-top: 14px; }
#game-view .rank-aktionen { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

#game-view .spiel-archivnote {
  margin: 8px 0 0;
  font-size: 0.8rem;
  color: var(--muted);
  border-left: 2px solid var(--line);
  padding-left: 10px;
}

/* ==========================================================================
   Abschnitt "Heute"

   Eine grosse Tageskarte, daneben die uebrigen Challenges als Zeilen mit
   Zustand, darunter der Fortschritt. Vorher lagen hier drei gleich breite
   Pillen von 62 Pixeln Hoehe — eine duenne Leiste, unter der der Abschnitt
   leer auslief, und drei gleichrangige Kacheln, die weder eine Reihenfolge
   vorgaben noch sich vom Katalog darunter unterschieden.

   Die grosse Karte benutzt dieselbe .cover-Mechanik wie die Katalogkacheln
   (Familienverlauf + Szene aus game-art.js + Scrim). Dadurch gehoert der
   Abschnitt sichtbar zum selben System, ohne ihn zu wiederholen: dort ein
   Raster gleicher Kacheln, hier eine Hauptsache mit Anhang.
   ========================================================================== */
/* Drei gleich breite Blöcke: die zwei Challenges des Tages und der eigene
   Stand. Gleiche Breite ist hier richtig — die beiden Aufgaben sind
   gleichrangig, es gibt keine "erste". */
.today__grid {
  list-style: none; margin: 22px 0 0; padding: 0;
  display: grid; gap: 16px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
}
/* Sollte der Topf je auf eine Challenge am Tag schrumpfen: Kachel und Stand
   nebeneinander statt einer halbleeren Reihe. */
.today__grid--solo { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Die schmale Ansicht steht am Ende des Abschnitts, nicht hier: Die Regeln
   für Kachelinhalt und Knopf haben dieselbe Spezifität wie ihre Grundregeln
   weiter unten, und bei Gleichstand gewinnt die spätere. An dieser Stelle
   wären sie wirkungslos gewesen. */

.versus__grid {
  list-style: none; margin: 18px 0 0; padding: 0;
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.today__timer { font-size: 0.85rem; font-weight: 700; color: var(--color-fg-muted); font-variant-numeric: tabular-nums; }

/* ---- Die Challenge-Kacheln ----------------------------------------------- */
.today__cell { display: flex; min-width: 0; }
.today__card {
  position: relative; display: flex; flex-direction: column; justify-content: space-between;
  min-height: 244px; width: 100%;
  border-radius: var(--radius-lg); overflow: hidden;
  text-decoration: none; color: var(--ink-0);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
/* .cover bringt Verlauf, Szene und Scrim mit — hier nur noch aufspannen. */
.today__cardArt { position: absolute; inset: 0; display: block; z-index: 0; }
.today__cardTop,
.today__cardBody { position: relative; z-index: 2; }

.today__cardTop { display: flex; gap: 8px; flex-wrap: wrap; padding: 14px 16px 0; }
.today__badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: var(--radius-full);
  background: rgba(15, 22, 19, 0.55);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  color: var(--ink-0); font-size: 0.7rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.08em;
}
/* DIE OFFENE CHALLENGE TRAEGT GOLD.

   outline statt border: Die Kachel hat overflow:hidden und einen eigenen
   Radius; eine Umrandung wuerde die Innenmasse verschieben und das Bild um
   zwei Pixel beschneiden. outline-offset:-2px legt den Strich auf die Kante,
   ohne im Fluss zu liegen. Der zweite Schatten ist der Schein darum — 12 %,
   nicht mehr: Er soll die Kachel heben, nicht zum Leuchtkasten machen. */
.today__card.is-offen {
  outline: 2px solid var(--color-accent); outline-offset: -2px;
  box-shadow: var(--shadow-sm), 0 0 0 5px rgba(255, 197, 61, 0.12);
}
/* Hier stand .today__badge--challenge — die goldene Marke auf jeder offenen
   Kachel. Sie ist weg, weil sie auf beiden Kacheln an jedem Tag stand und
   damit nichts unterschied; der Satz steht jetzt in der Unterzeile von
   "Heute". Der goldene RAHMEN oben bleibt: Der unterscheidet offen von
   erledigt, und das tut er weiterhin. */
.today__badge--done { background: var(--color-primary); color: var(--color-on-primary); }
.today__badge svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2.6; }

.today__cardBody { display: flex; flex-direction: column; gap: 5px; padding: 16px; }
.today__cardName {
  font-family: var(--font-display);
  font-size: var(--text-xl); font-weight: 800;
  letter-spacing: var(--tracking-tight); line-height: var(--leading-tight);
}
/* Und hier stand .today__cardDesc. Die Beschreibung ist von der Kachel
   verschwunden — auf dem Telefon war sie ohnehin schon ausgeblendet, mit
   derselben Begruendung, die jetzt ueberall gilt: Name und Knopf sagen hier
   genug, was ein Spiel ist steht im Katalog. */
.today__cta {
  align-self: flex-start; margin-top: 8px;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px; border-radius: var(--radius-full);
  background: var(--ink-0); color: var(--ink-900);
  font-weight: 800; font-size: 0.82rem;
  transition: gap var(--dur-fast) var(--ease-out);
}
.today__cta svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.4; }
/* Erledigt: die Karte tritt zurueck, bleibt aber anspielbar. Ausgrauen waere
   falsch — man darf jederzeit nochmal spielen, es zaehlt nur nicht doppelt. */
.today__card.is-done .today__cardArt { filter: saturate(0.6); }

/* ---- Dritter Block: der eigene Stand ------------------------------------- */
/* Keine Kachel mit Bild, sondern eine ruhige Flaeche — sonst konkurriert sie
   mit den beiden Spielen daneben um denselben Blick. */
.today__stats {
  display: flex; flex-direction: column; gap: 14px; width: 100%;
  padding: 16px; border-radius: var(--radius-lg);
  border: 1px solid var(--color-border); background: var(--color-surface);
  /* Er ist seit dem 11.09.2026 ein <button>, der ins Profil fuehrt. Die drei
     Zeilen nehmen ihm zurueck, was ein Knopf mitbringt und was hier stoert:
     zentrierter Text, eigene Schrift, eigene Ausrichtung. */
  font: inherit; color: inherit; text-align: left; cursor: pointer;
  transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.today__stats:hover { border-color: var(--color-accent); }
.today__stats:active { transform: translateY(1px); }

/* ---- Die Serie ----------------------------------------------------------
   Eine Zahl, nicht zwei. Die Serie ist das Einzige auf dieser Seite, das man
   verliert, indem man nichts tut — die Quote ist daneben eine Auskunft und
   steht deshalb klein darunter. */
.today__streak {
  display: grid; grid-template-columns: auto 1fr; align-items: center;
  column-gap: 10px; row-gap: 2px;
}
.today__streakFlame { font-size: 1.6rem; line-height: 1; color: var(--color-fg-muted); }
.today__streakBig {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 7vw, 3.4rem); font-weight: 800; line-height: 0.9;
  letter-spacing: var(--tracking-tight); color: var(--color-fg);
  font-variant-numeric: tabular-nums;
}
.today__streakLabel {
  grid-column: 2; font-size: 0.78rem; line-height: var(--leading-snug);
  color: var(--color-fg-muted);
}
.today__streak.is-hot .today__streakBig { color: var(--color-accent-text); }

/* ---- Der Wochenstreifen -------------------------------------------------
   Sieben Punkte, links der aelteste, rechts heute. Vier Zustaende, und die
   Farben sagen dasselbe wie ueberall sonst im Haus: gold = Challenge
   erledigt, halbgold = angefangen, leer = nichts, Ring = heute und noch
   offen. "unbekannt" bleibt fast unsichtbar — ein leerer Punkt waere eine
   Behauptung ueber einen Tag, von dem wir nichts wissen. */
.today__week { display: flex; gap: 6px; }
.today__weekDot {
  flex: 1 1 0; height: 8px; border-radius: var(--radius-full);
  background: var(--color-border);
}
/* --color-accent-text und NICHT --color-accent, und das ist gemessen: Das
   helle Gold der Marke steht mit 1,55 gegen eine weisse Karte — auf einem
   Foto richtig, auf Papier fast unsichtbar. Die Textfassung des Tokens
   flippt mit dem Thema (gold-300 im Dunkeln, gold-800 im Hellen) und traegt
   in beiden. Der Rahmen der Kachel oben bleibt beim hellen Gold: Der liegt
   auf dem Bild, nicht auf der Karte. */
.today__weekDot.is-voll { background: var(--color-accent-text); }
.today__weekDot.is-teil {
  background: linear-gradient(90deg, var(--color-accent-text) 0 50%, var(--color-border) 50% 100%);
}
.today__weekDot.is-unbekannt { background: none; box-shadow: inset 0 0 0 1px var(--color-border); }
.today__weekDot.is-today {
  box-shadow: 0 0 0 2px var(--color-surface), 0 0 0 3px var(--color-accent-text);
}

.today__statLine {
  font-size: 0.78rem; line-height: var(--leading-snug); color: var(--color-fg-muted);
}
.today__statLine b {
  font-weight: 800; color: var(--color-fg); font-variant-numeric: tabular-nums;
}
.today__statsHead {
  font-size: 0.72rem; font-weight: 800; color: var(--color-fg-muted);
  text-transform: uppercase; letter-spacing: 0.09em;
}
/* .today__stat, .today__statBig und .today__statLabel sind weg (11.09.2026):
   Serie und Quote standen als zwei gleich grosse Zahlen nebeneinander. Die
   Serie traegt die grosse Zahl jetzt allein (.today__streak*), die Quote
   steht klein darunter (.today__statLine). */
/* Ohne gespielte Challenge steht hier ein Satz statt einer Zahl. Eine 0 %
   waere an dieser Stelle schlicht falsch. */
.today__statNone { font-size: 0.82rem; color: var(--color-fg-muted); }

/* ---- Fortschritt des Tages ---------------------------------------------- */
/* Sitzt am Fuss des Stand-Blocks und schiebt sich nach unten, damit alle drei
   Bloecke auf dieselbe Hoehe kommen. */
.today__progress {
  margin-top: auto; padding: 12px 14px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border); background: var(--color-bg-inset);
  display: flex; flex-direction: column; gap: 8px;
}
.today__progressText {
  font-size: 0.76rem; font-weight: 800; color: var(--color-fg-muted);
  text-transform: uppercase; letter-spacing: 0.07em;
}
.today__progressTrack {
  display: block; height: 5px; border-radius: var(--radius-full);
  background: var(--color-border); overflow: hidden;
}
.today__progressTrack i {
  display: block; height: 100%; border-radius: inherit;
  background: var(--color-primary);
  transition: width var(--dur-slow) var(--ease-out);
}
.today__progress.is-full .today__progressText { color: var(--color-primary-text); }

/* ---- Schmale Ansicht ----------------------------------------------------- */
/* Am Handy bleiben die beiden Spiele nebeneinander — sie sind der Zweck des
   Abschnitts. Der Stand-Block legt sich quer darunter.

   Bei zwei Spalten auf 375 Pixeln bleiben je Kachel rund 150 Pixel. Darin
   passt kein Beschreibungstext mehr: Er brach nach zwei Wortteilen ab
   ("Zwei Karrierestatione…"), und die Schaltflaeche daneben lief aus der
   Kachel heraus. Also faellt die Beschreibung weg und der Knopf wird kleiner
   — Name und Knopf sagen hier genug, der vollstaendige Text steht im
   Katalog. */
@media (max-width: 720px) {
  .today__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .today__grid .today__cell:last-child { grid-column: 1 / -1; }
  .today__grid--solo { grid-template-columns: minmax(0, 1fr); }

  .today__card { min-height: 196px; }
  .today__cardTop { padding: 11px 11px 0; }
  .today__cardBody { padding: 11px; gap: 4px; }
  .today__cardName { font-size: 1.02rem; }
  /* Der Pfeil faellt weg: "Nochmal spielen" plus Pfeil ist breiter als die
     Kachel, und der Knopf lief rechts heraus. Ohne ihn passt die Zeile. */
  .today__cta { padding: 7px 11px; font-size: 0.72rem; white-space: nowrap; gap: 0; }
  .today__cta svg { display: none; }
  .today__badge { padding: 4px 8px; font-size: 0.6rem; letter-spacing: 0.05em; }
}

/* Hier standen die Regeln des Datenbands (Weltkarte der Vereinsstandorte).
   Der Block ist von der Startseite verschwunden — er beantwortete eine Frage,
   die dort niemand stellt, und nahm nach dem Wegfall der "Zahl des Tages"
   daneben die volle Breite ein. */

/* Die Empfehlungskacheln (.podium--tipp) fuer den leeren Zustand sind am
   16.09.2026 weggefallen: Das Podest zeigt immer drei Spiele, notfalls mit 0
   Starts. Siehe renderPodium() in app.js. */

/* "Gegeneinander" bewusst ruhiger als "Heute" — es ist das Angebot daneben,
   nicht der Grund des Tages. */
.versus__card {
  display: block; padding: 18px; border-radius: var(--radius-md);
  border: 1px solid var(--color-border); background: var(--color-surface);
  color: var(--color-fg); text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.versus__icon { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
  background: var(--color-bg-inset); color: var(--color-primary-text); margin-bottom: 10px; }
.versus__icon svg { width: 20px; height: 20px; }
.versus__name { display: block; font-weight: 800; font-size: 1.05rem; margin-bottom: 4px; }
.versus__desc { display: block; font-size: 0.86rem; color: var(--color-fg-muted); line-height: 1.4; }

@media (hover: hover) and (pointer: fine) {
  .today__card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md, var(--shadow-sm)); }
  .today__card:hover .cover__szene { transform: scale(1.05); }
  .today__card:hover .today__cta { gap: 12px; }
  .versus__card:hover { border-color: var(--color-primary); transform: translateY(-3px); }
}

/* Schalter unter dem Katalog: zeigt die restlichen Kacheln. */
.cardgrid__more { display: flex; justify-content: center; margin-top: 18px; }
.cardgrid__more button[hidden] { display: none; }

/* Anmelde-Dialog */
#game-view .auth-modal, .auth-modal { max-width: 380px; }
/* Einstellungsfenster. Global, weil es wie alle Modals an document.body haengt. */
.settings-modal { max-width: 420px; text-align: left; }
.settings-modal h3 { text-align: center; margin-bottom: 18px; }
.set-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 0; border-bottom: 1px solid var(--line); }
.set-row:last-of-type { border-bottom: none; }
.set-label { font-size: 0.78rem; font-weight: 800; color: var(--muted);
  letter-spacing: 0.04em; text-transform: uppercase; flex: 0 0 auto; min-width: 108px; }
.set-value { flex: 1 1 auto; font-weight: 700; overflow-wrap: anywhere; }
.set-group { display: flex; gap: 6px; margin-left: auto; }
.modal button.set-btn { margin-left: 0; padding: 7px 14px; font-size: 0.82rem; }
/* Aktiver Zustand als Lime-Toenung. "background: var(--card)" waere hier ein
   Loch statt einer Hervorhebung — --card ist dunkler als die Flaeche.
   Der Selektor braucht "button.secondary"-Gewicht, sonst gewinnt dessen
   "background: transparent" und der aktive Zustand bleibt unsichtbar. */
.modal button.set-btn.is-on { background: rgba(var(--marke-rgb), 0.14);
  border-color: var(--correct-text); color: var(--ink); }
.set-hint { margin: -4px 0 0; font-size: 0.78rem; color: var(--muted); line-height: 1.45; }
/* Konto loeschen: dieselbe Knopfform wie daneben, aber in der Fehlerfarbe —
   es ist der einzige Knopf in diesem Fenster, der etwas unwiderruflich tut.
   --rot-text traegt in beiden Themen AA (siehe die Token oben). */
.modal button.set-btn--gefahr { color: var(--rot-text); border-color: var(--rot-text); margin-left: auto; }
.set-hint:empty { display: none; }
/* HIER STAND EINE LISTE VON DREI KLASSEN, die [hidden] nachtrug:
   .header__login, .header__cta, #cta-band. Sie standen auf
   display:inline-flex, und "knopf.hidden = true" blieb deshalb wirkungslos —
   [hidden] bringt nur ein display:none aus dem Browser-Standard mit, und jede
   Autorenregel schlaegt das.

   Die Liste ist weg, weil sie das getan hat, was Listen tun: Beim vierten
   Fall (.liga-geld im Liga-Formular) fehlte der Eintrag, und die Geldfelder
   standen bei "Nur zum Spass" trotzdem da. Die Regel gilt jetzt einmal
   global in rivalz-base.css, wo auch die Begruendung steht. */
/* Der Name wird einmal vergeben — das muss man sehen, bevor man tippt, nicht
   danach. Deshalb abgesetzt statt als weiterer grauer Hinweissatz. */
.fr-warnung { margin: 0 0 16px; padding: 10px 12px; border-radius: 12px;
  background: rgba(var(--orange-rgb), 0.1); border: 1px solid rgba(var(--orange-rgb), 0.35);
  font-size: 0.84rem; line-height: 1.5; color: var(--ink); text-align: left; }
.auth-modal .auth-hint { font-size: 0.86rem; color: var(--muted); margin: 0 0 14px; line-height: 1.5; }
.auth-field { display: block; margin-bottom: 12px; }
.auth-field span { display: block; font-size: 0.78rem; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 5px; }
.auth-field input { width: 100%; }
.auth-error { margin: 0 0 12px; font-size: 0.85rem; color: var(--rot-text); line-height: 1.45; }
.auth-error[hidden] { display: none; }
.auth-switch { display: block; width: 100%; margin-top: 12px; padding: 8px;
  background: none; border: none; color: var(--muted); font-size: 0.84rem;
  text-decoration: underline; cursor: pointer; }
.auth-switch:hover { color: var(--ink); }

/* ==========================================================================
   Missing XI
   ----------
   Elf Positionsplätze auf einem Spielfeld. Die Formation ist eine
   Darstellung, keine Behauptung — der Datensatz kennt keine Aufstellungen,
   nur wer in dem Jahr im Kader stand (siehe Spiel 7 in server.js). Deshalb
   steht über dem Feld auch "wer stand im Kader" und nicht "die Startelf".

   Gebaut mit Grid statt mit absoluten Positionen: Die Reihen sind
   unterschiedlich lang (2 / 4 / 4 / 1), und jede soll ihre Trikots gleich
   verteilen. Mit `repeat(auto-fit, …)` und `justify-content: center` fällt
   das von selbst richtig aus, auch am Handy.
   ========================================================================== */
#game-view .m11-aufgabe {
  margin: 18px 0 4px;
  font-size: var(--text-xl);
  font-weight: 800;
  line-height: 1.25;
}

/* Der Rasen. Zwei Grüntöne als Streifen wie ein gemähtes Feld, dazu die
   Mittellinie. Bewusst nicht als Bild: Ein Rasenfoto wäre urheberrechtlich
   belastet, und ein Verlauf tut es genauso. */
#game-view .m11-feld {
  /* Hochformat und gedeckelt. Ohne die Breitenbegrenzung lief das Feld ueber
     die volle Kartenbreite, und die elf Trikots klumpten in der Mitte
     zusammen — es sah aus wie eine Liste auf grünem Grund, nicht wie eine
     Aufstellung. */
  max-width: 460px;
  margin: 16px auto;
  padding: 18px 12px 12px;
  border-radius: 16px;
  border: 1px solid rgba(var(--marke-rgb), 0.22);
  background:
    linear-gradient(180deg, rgba(var(--marke-rgb), 0.05) 0%, rgba(var(--marke-rgb), 0.11) 100%),
    repeating-linear-gradient(180deg,
      rgba(255, 255, 255, 0.022) 0 42px,
      rgba(255, 255, 255, 0) 42px 84px),
    var(--card);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Jede Reihe verteilt ihre Trikots gleichmaessig ueber die Feldbreite —
   zwei Stuermer stehen also weiter auseinander als vier Verteidiger, wie auf
   einer echten Aufstellung. Deshalb 1fr-Spalten und kein festes Rastermass. */
#game-view .m11-reihe {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 8px;
  padding: 0 6px;
}
/* Der Torwart steht allein und soll nicht ueber die ganze Breite gehen.
   Ueber eine eigene Klasse und nicht ueber :last-of-type — darunter steht
   noch die Fusszeile, die waere der letzte div und die Regel liefe ins
   Leere. */
#game-view .m11-reihe--tor { grid-auto-flow: row; grid-auto-columns: auto; justify-items: center; }
#game-view .m11-reihe--tor .m11-slot { width: 100px; }
/* Zwei Stuermer ueber die volle Breite sahen aus wie zwei Aussenbahnen. Die
   Sturmreihe steht deshalb schmaler und mittiger als die Viererketten. */
#game-view .m11-reihe--sturm { width: 66%; margin: 0 auto; }

/* Ein Platz. Leer = gestrichelter Umriss, besetzt = Lime-Tönung.
   Die Tönung ist rgba(0,229,122,.14) und nicht var(--card): --card ist in
   diesem Theme DUNKLER als der Rasen darüber, ein besetzter Platz sähe damit
   aus wie ein Loch statt wie eine Hervorhebung. Steht so auch in CLAUDE.md. */
/* Breite gedeckelt und mittig: Ohne das zog jeder Platz seine Rasterspalte
   voll auf und die Trikots sassen als flache Balken darin. */
#game-view .m11-slot {
  width: 100%;
  max-width: 92px;
  justify-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 8px 4px 6px;
  border-radius: 10px;
  border: 1px dashed rgba(255, 255, 255, 0.16);
  /* Die leere Position ist eine MULDE, und der Wert dafuer gehoert dem Thema,
     nicht dieser Zeile. Als rohes rgba(0,0,0,0.20) war er fuer Dunkel gemessen:
     auf einer fast weissen hellen Karte blieb er knapp lesbar (4.74), und
     sobald unter ihm noch eine Flaeche liegt — im Glas tut sie das — fielen
     die Punkte der leeren Position auf 3.94. --color-bg-inset kennt alle vier
     Faelle und ist genau dieses Feld. */
  background: var(--color-bg-inset);
  transition: background 0.18s ease, border-color 0.18s ease;
}
#game-view .m11-slot.is-set {
  border-style: solid;
  border-color: rgba(var(--marke-rgb), 0.45);
  background: rgba(var(--marke-rgb), 0.14);
}
/* Der Torwart trägt eine andere Farbe — wie auf dem Platz auch. */
#game-view .m11-slot--tor.is-set {
  border-color: rgba(255, 197, 61, 0.5);
  background: rgba(255, 197, 61, 0.14);
}

#game-view .m11-shirt svg { width: 26px; height: 26px; display: block; color: var(--muted); }
#game-view .m11-slot.is-set .m11-shirt svg { color: var(--lime-400); }
#game-view .m11-slot--tor.is-set .m11-shirt svg { color: var(--gold-400); }

/* Namen brechen um statt abzuschneiden: "Zlatan Ibrahimović" in ein
   84-px-Feld zu kürzen, machte aus dem Treffer ein Rätsel. */
#game-view .m11-name {
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  color: var(--ink);
  overflow-wrap: anywhere;
  hyphens: auto;
}
#game-view .m11-slot:not(.is-set) .m11-name { color: var(--muted); letter-spacing: 0.14em; font-weight: 500; }

#game-view .m11-fuss {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 4px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
#game-view .m11-zaehler { font-size: 1.35rem; font-weight: 800; color: var(--muted); }
#game-view .m11-zaehler b { color: var(--ink); }
#game-view .m11-versuche { font-size: 0.76rem; color: var(--muted); flex: 1; }
#game-view .m11-aufgeben {
  padding: 7px 14px; border: none; border-radius: 8px; cursor: pointer;
  background: var(--orange, #EA4F23); color: var(--ink-0);
  font: inherit; font-size: 0.78rem; font-weight: 700;
}
#game-view .m11-aufgeben:hover { filter: brightness(1.1); }

/* Nach dem Aufgeben: wer noch infrage kam, nach Gruppen. Bewusst keine
   "richtige Elf" — die gibt es nicht, die Lösungsmenge ist der ganze Kader. */
#game-view .m11-rest { margin-top: 14px; }
#game-view .m11-restgruppe {
  display: flex; gap: 10px; align-items: baseline;
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
#game-view .m11-restlabel {
  flex: 0 0 84px;
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .m11-restnamen { font-size: 0.86rem; line-height: 1.5; }

/* Archiv */
/* Vergangene Tage — dieselbe Leiste unter jedem Spiel mit Tagesraetsel.

   Die Regeln hiessen bis zum Vereinheitlichen .m11-archiv*: Die Aufstellung
   hatte die Ansicht als einziges Spiel. Umbenannt statt kopiert, aus demselben
   Grund wie beim Spiel-Kopf — wer hier etwas aendert, aendert es fuer alle
   fuenf.

   Sieben Kacheln passen ohne Rollbalken; max-height bleibt trotzdem stehen,
   falls die Zahl je steigt. */
#game-view .archiv { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--line); }
#game-view .archiv .hint { display: block; margin: 6px 0 0; font-size: 0.76rem; }
#game-view .archivliste {
  list-style: none; margin: 12px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px;
  max-height: 260px; overflow-y: auto;
}
#game-view .archivliste[hidden] { display: none; }
#game-view .archivtag {
  position: relative;              /* traegt den Haken oben rechts */
  width: 100%; display: flex; flex-direction: column; gap: 2px;
  padding: 8px 10px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: inherit;
  font: inherit; text-align: left;
}

/* ---- Schon gespielt ------------------------------------------------------
   Zwei Merkmale, nicht eines. Die Toenung allein reicht auf sieben kleinen
   Kacheln nicht — sie ist schwach, damit sie "heute" nicht ueberstrahlt, und
   damit ist sie fuer sich zu wenig Unterschied. Der Haken traegt die Aussage,
   die Farbe unterstuetzt sie.

   Warum so zurueckhaltend: "heute" ist die Aufforderung, "gespielt" nur eine
   Auskunft. Waeren beide gleich laut, ginge der Unterschied verloren, den die
   Leiste ueberhaupt hat. Eine Kachel kann beides sein. */
#game-view .archivtag.is-gespielt {
  border-color: rgba(var(--marke-rgb), 0.3);
  background: rgba(var(--marke-rgb), 0.07);
}
#game-view .archivtag.is-gespielt .archivwas { color: var(--correct-text); }

#game-view .archivhaken {
  position: absolute;
  top: 6px;
  right: 8px;
  font-size: 0.7rem;
  font-weight: 900;
  line-height: 1;
  color: var(--correct-text);
}

/* Bei "heute" hat die Kachel schon eine kraeftigere Toenung. Der Haken bleibt,
   die zweite Faerbung waere doppelt. */
#game-view .archivtag.is-heute.is-gespielt { background: rgba(var(--marke-rgb), 0.14); }
#game-view .archivtag:hover { border-color: rgba(var(--marke-rgb), 0.4); }
#game-view .archivtag.is-heute { border-color: rgba(var(--marke-rgb), 0.45); background: rgba(var(--marke-rgb), 0.14); }
#game-view .archivwann { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted); }
#game-view .archivwas { font-size: 0.82rem; font-weight: 700; }

/* Läuft gerade ein Archiv-Tag, sagt das Band das — und bietet den Rückweg.

   Es hiess .m11-archivband, solange nur die Aufstellung ein Archiv hatte.
   Jetzt steht es im gemeinsamen Spiel-Kopf und gilt fuer alle fuenf. Der
   Rueckweg ist noetig, obwohl die Modus-Leiste darueber auch nach heute
   fuehrt: Dort steht "Tages-Challenge", und dass das der Weg zurueck ist,
   sieht man erst, wenn man es probiert hat. */
#game-view .spiel-archivband {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 12px 0 0; padding: 9px 12px; border-radius: 10px;
  background: var(--panel); border: 1px solid var(--line);
  font-size: 0.8rem; color: var(--muted);
}

/* Das Liga-Duell-Band, ueber allem anderen im Spielkopf (27.09.2026).

   Ein Liga-Duell laeuft ueber SPIEL_MODI[id].ligaTag(n) und sah im Spiel aus
   wie ein Archiv-Tagesraetsel: kein Gegner, kein Stand, kein Weg zurueck in
   die Liga. Deshalb OBEN und nicht unten wie das Archivband — es beantwortet
   die Frage, in welchem Zusammenhang diese Runde ueberhaupt steht, und die
   kommt vor allem anderen.

   Die Markenfarbe als Rand, weil das Band eine LAUFENDE Verpflichtung
   anzeigt; der Fehlerfall wechselt auf --rot-text, den das Projekt fuer
   genau solche Saetze haelt. */
#game-view .liga-duellband {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 0 0 12px; padding: 9px 12px; border-radius: 10px;
  background: var(--panel); border: 1px solid var(--violet-text);
  font-size: 0.82rem; color: var(--text);
}
#game-view .liga-duellband--fehler {
  border-color: var(--rot-text);
  color: var(--rot-text);
}
#game-view .liga-duellband button { flex: 0 0 auto; }

@media (max-width: 560px) {
  #game-view .m11-reihe { grid-template-columns: repeat(auto-fit, minmax(0, 68px)); gap: 6px; }
  #game-view .m11-feld { padding: 14px 8px 10px; }
  #game-view .m11-name { font-size: 0.62rem; }
  #game-view .m11-restlabel { flex-basis: 68px; }
}

/* ==========================================================================
   Duell-Serie (duell.js)
   ----------------------
   Der Rahmen um die Runden: Punktestand, Übergabebildschirm, Rundenergebnis,
   Endstand. Bewusst spielneutral — hier steht nichts, was nur zu Missing XI
   oder nur zum Karriereweg passt.

   Der Karriereweg bringt eine eigene, ältere Fassung mit (.duel-* unter
   #game-view, aus renderDuel in careerpath.js). Die Klassen heißen hier
   .duell-* und beißen sich deshalb nicht mit ihr.
   ========================================================================== */
#game-view .duell-setup { display: flex; flex-direction: column; gap: 14px; margin-top: 18px; }
#game-view .duell-feld { display: flex; flex-direction: column; gap: 6px; }
#game-view .duell-feld > span {
  font-size: 0.72rem; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .duell-feld input {
  padding: 11px 13px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel); color: var(--ink);
  font: inherit;
}
#game-view .duell-bo-wahl { display: flex; gap: 8px; }
#game-view .duell-bo-btn {
  flex: 1; padding: 11px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  font: inherit; font-weight: 700;
}
/* Lime-Tönung für den aktiven Zustand, nicht var(--card): --card ist dunkler
   als --panel, ein aktiver Knopf sähe damit aus wie ein Loch. */
#game-view .duell-bo-btn.is-on {
  background: rgba(var(--marke-rgb), 0.14);
  border-color: rgba(var(--marke-rgb), 0.45);
  color: var(--ink);
}

/* Punktestand — steht auf jedem Bildschirm der Serie. */
#game-view .duell-stand {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px 12px;
  margin: 16px 0;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
}
#game-view .duell-name { font-size: 0.86rem; font-weight: 700; color: var(--muted); min-width: 0; overflow-wrap: anywhere; }
#game-view .duell-name.fuehrt { color: var(--ink); }
#game-view .duell-name:last-of-type { text-align: right; }
#game-view .duell-zahl { font-size: 1.5rem; font-weight: 800; letter-spacing: 0.02em; }
#game-view .duell-doppel { color: var(--muted); margin: 0 4px; }
#game-view .duell-balken {
  grid-column: 1 / -1; height: 5px; border-radius: 3px; overflow: hidden;
  background: rgba(255, 255, 255, 0.09);
}
#game-view .duell-balken-fuell { height: 100%; background: var(--lime-400); border-radius: 3px; transition: width 0.3s ease; }
#game-view .duell-bo {
  grid-column: 1 / -1; text-align: center;
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted);
}

/* Übergabe: zwei Keile laufen aufeinander zu. */
#game-view .duell-buehne {
  position: relative; display: flex; align-items: stretch;
  height: 76px; margin: 18px 0; border-radius: 12px; overflow: hidden;
}
#game-view .duell-keil {
  flex: 1; display: flex; align-items: center;
  padding: 0 16px; font-weight: 800; font-size: 0.9rem;
  overflow: hidden;
}
#game-view .duell-keil.links {
  animation: wedgeIn-l 0.55s var(--ease-kinetic) both;
  background: linear-gradient(100deg, rgba(var(--marke-rgb), 0.24), rgba(var(--marke-rgb), 0.06));
  clip-path: polygon(0 0, 100% 0, calc(100% - 26px) 100%, 0 100%);
}
#game-view .duell-keil.rechts {
  animation: wedgeIn-r 0.55s var(--ease-kinetic) both;
  background: linear-gradient(260deg, rgba(120, 92, 255, 0.26), rgba(120, 92, 255, 0.06));
  clip-path: polygon(26px 0, 100% 0, 100% 100%, 0 100%);
  justify-content: flex-end; text-align: right;
}
#game-view .duell-keil span { min-width: 0; overflow-wrap: anywhere; }
#game-view .duell-vs {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  padding: 5px 11px; border-radius: 999px;
  background: var(--bg); border: 1px solid var(--line);
  font-size: 0.72rem; font-weight: 800; letter-spacing: 0.1em;
}

#game-view .duell-ansage { text-align: center; padding: 6px 0 4px; }
#game-view .duell-rundenmarke {
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .duell-dran { font-size: var(--text-2xl); font-weight: 800; margin: 6px 0 10px; }
#game-view .duell-wegschauen { margin: 0 auto 18px; max-width: 34ch; font-size: 0.86rem; color: var(--muted); line-height: 1.5; }

/* Wer gerade rät — Band über der laufenden Runde. */
#game-view .duell-dranband {
  margin: 0 0 12px; padding: 8px 12px; border-radius: 9px;
  background: rgba(var(--marke-rgb), 0.12); border: 1px solid rgba(var(--marke-rgb), 0.3);
  font-size: 0.8rem;
}

/* Rundenergebnis */
#game-view .duell-rundenres { margin-top: 4px; }
#game-view .duell-reszeile {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 11px 12px; margin-top: 8px; border-radius: 10px;
  background: var(--panel); border: 1px solid var(--line);
}
#game-view .duell-reszeile.gewonnen { border-color: rgba(var(--marke-rgb), 0.45); background: rgba(var(--marke-rgb), 0.13); }
#game-view .duell-resname { font-weight: 800; min-width: 0; overflow-wrap: anywhere; }
#game-view .duell-resdetail { font-size: 0.82rem; color: var(--muted); text-align: right; }
#game-view .duell-siegzeile { margin: 14px 0 4px; text-align: center; font-weight: 800; font-size: var(--text-lg); }
#game-view .duell-aufloesung { text-align: center; font-size: 0.8rem; color: var(--muted); margin-bottom: 14px; }

/* Endstand */
#game-view .duell-finale { text-align: center; padding: 10px 0; }
#game-view .duell-finmarke {
  font-size: 0.7rem; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .duell-finname { font-size: var(--text-3xl); font-weight: 800; margin: 8px 0; line-height: 1.15; }
#game-view .duell-finstand { font-size: 1rem; color: var(--muted); }
#game-view .duell-finstand b { color: var(--ink); font-size: 1.2rem; }
/* Der Rundenverlauf als Punktreihe: auf einen Blick, wie die Serie lief. */
#game-view .duell-verlauf { display: flex; justify-content: center; gap: 6px; margin: 16px 0 20px; }
#game-view .duell-verlaufpunkt {
  width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 0.72rem; font-weight: 800;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted);
}
#game-view .duell-verlaufpunkt.a { background: rgba(var(--marke-rgb), 0.2); border-color: rgba(var(--marke-rgb), 0.45); color: var(--ink); }
#game-view .duell-verlaufpunkt.b { background: rgba(120, 92, 255, 0.22); border-color: rgba(120, 92, 255, 0.5); color: var(--ink); }
#game-view .duell-finaktionen { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

@media (max-width: 560px) {
  #game-view .duell-stand { grid-template-columns: 1fr auto 1fr; gap: 8px; padding: 10px; }
  #game-view .duell-name { font-size: 0.76rem; }
  #game-view .duell-zahl { font-size: 1.25rem; }
  #game-view .duell-dran { font-size: var(--text-xl); }
}

/* Tagesserie in der Leiste über einem Spiel und auf der Katalogkachel.
   Zwei Ebenen, zwei Zähler: Die App-Streak zählt Tage, an denen ALLE
   Challenges gespielt wurden; diese hier zählt Tage, an denen DIESES Spiel
   gespielt wurde — unabhängig davon, ob es in der Rotation stand. */
#game-view .tages-serie {
  margin-left: 10px;
  font-weight: 700;
  color: var(--lime-400);
  white-space: nowrap;
}
#game-view .tages-marke {
  color: var(--gold-400);
  font-weight: 800;
  letter-spacing: 0.04em;
}

/* ==========================================================================
   Wer wird Weltmeister?

   Links die Frage mit vier Antworten, rechts die Ligaleiter. Die Leiter
   laeuft von oben nach unten, Champions League zuoberst — so wie man sie
   erklimmt und wie man sie aus dem Fernsehen kennt.

   Alles unter #game-view, wie im Kopf dieser Datei verlangt.
   ========================================================================== */
#game-view .quiz-raum {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 230px;
  gap: 22px;
  align-items: start;
}
#game-view .quiz-spiel { min-width: 0; }

/* ---- Kopf: fuer welche Liga geht es gerade ---- */
#game-view .quiz-kopf {
  display: flex; flex-direction: column-reverse; gap: 2px;
  margin-bottom: 14px;
}
#game-view .quiz-liga {
  font-family: "Archivo", sans-serif;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.1rem);
  font-weight: 900; font-style: italic;
  letter-spacing: -0.03em;
  color: var(--violet-text);
}
#game-view .quiz-fuer {
  font-size: 0.74rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--muted);
}

#game-view .quiz-frage {
  font-size: clamp(1.05rem, 0.95rem + 0.6vw, 1.35rem);
  font-weight: 700; line-height: 1.35;
  margin: 0 0 18px;
}

/* ---- Die vier Antworten ---- */
#game-view .quiz-antworten { display: grid; gap: 10px; }
#game-view .quiz-antwort {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 14px 16px;
  border-radius: 12px;
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--text);
  font: inherit; font-weight: 600; text-align: left;
  cursor: pointer;
  transition: transform .16s var(--ease-kinetic), border-color .16s ease, background .16s ease;
}
#game-view .quiz-antwort:hover:not(:disabled) { transform: translateX(3px); border-color: var(--violet-text); }
#game-view .quiz-antwort:disabled { cursor: default; }
/* Vom 50:50 aussortiert: Platz bleibt stehen, damit die Liste nicht springt. */
#game-view .quiz-antwort.weg { opacity: 0.22; }
#game-view .quiz-antwort.weg .quiz-text { text-decoration: line-through; }

#game-view .quiz-buchstabe {
  display: grid; place-items: center;
  width: 30px; height: 30px; flex: none;
  border-radius: 50%;
  background: var(--panel); border: 1px solid var(--line);
  font-weight: 900; font-size: 0.85rem; color: var(--violet-text);
}
#game-view .quiz-text { flex: 1; min-width: 0; }

#game-view .quiz-antwort.richtig { border-color: var(--correct-text); background: rgba(0, 201, 107, 0.16); }
#game-view .quiz-antwort.falsch  { border-color: #FF2D4B; background: rgba(255, 45, 75, 0.14); }
/* Videobeweis: gepruefte Antwort bekommt eine eigene Auszeichnung — nicht
   dieselbe wie eine aufgeloeste, sonst waere die Runde vorzeitig verraten. */
#game-view .quiz-antwort.var-ok   { border-color: var(--present-text); }
#game-view .quiz-antwort.var-nein { border-color: var(--absent); opacity: 0.55; }
#game-view .quiz-var-marke {
  flex: none; font-size: 0.66rem; font-weight: 900;
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted);
}

#game-view .quiz-meldung {
  margin: 14px 0 0; padding: 11px 14px;
  border-radius: 10px;
  background: var(--panel); border: 1px solid var(--line);
  font-size: 0.88rem; line-height: 1.45; color: var(--text);
}

/* ---- Joker ---- */
#game-view .quiz-joker-reihe {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px; margin-top: 18px;
}
#game-view .quiz-joker {
  padding: 10px 6px;
  border-radius: 10px;
  border: 1.5px solid var(--line);
  background: transparent; color: var(--text);
  font: inherit; font-size: 0.76rem; font-weight: 800;
  cursor: pointer;
  transition: border-color .16s ease, background .16s ease, opacity .16s ease;
}
#game-view .quiz-joker:hover:not(:disabled) { border-color: var(--violet-text); }
#game-view .quiz-joker:disabled { opacity: 0.32; cursor: default; }
/* Scharf gestellter Videobeweis: Der naechste Tipp prueft, statt zu
   antworten — das muss man sehen, sonst verliert man eine Antwort. */
#game-view .quiz-joker.scharf {
  border-color: var(--present-text);
  background: rgba(255, 197, 61, 0.14);
  color: var(--present-text);
}

#game-view .quiz-fuss {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 16px;
  padding-top: 12px; border-top: 1px solid var(--line);
}
#game-view .quiz-sicher-hinweis { font-size: 0.76rem; color: var(--muted); }

/* ---- Die Ligaleiter ---- */
#game-view .quiz-leiter {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 3px;
}
#game-view .quiz-stufe {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px;
  border-radius: 8px;
  font-size: 0.8rem; font-weight: 700;
  color: var(--muted);
}
#game-view .quiz-stufe-nr {
  width: 20px; flex: none; text-align: right;
  font-variant-numeric: tabular-nums; font-weight: 900;
  color: var(--absent);
}
#game-view .quiz-stufe-liga { flex: 1; min-width: 0; }
#game-view .quiz-stufe-marke { flex: none; color: var(--present-text); font-size: 0.7rem; }

/* Sicherheitsstufe: dauerhaft hervorgehoben, auch wenn man noch weit davon
   entfernt ist — sie ist das Ziel, auf das man zuspielt. */
#game-view .quiz-stufe.sicher { color: var(--text); }
#game-view .quiz-stufe.erledigt { color: var(--correct-text); }
#game-view .quiz-stufe.erledigt .quiz-stufe-nr { color: var(--correct-text); }
#game-view .quiz-stufe.aktuell {
  background: rgba(var(--marke-rgb), 0.14);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px rgba(var(--marke-rgb), 0.4);
}
#game-view .quiz-stufe.aktuell .quiz-stufe-nr { color: var(--violet-text); }

/* ---- Endbildschirm ---- */
#game-view .quiz-ende-kopf {
  font-family: "Archivo", sans-serif;
  font-size: clamp(1.4rem, 1.1rem + 1.4vw, 2rem);
  font-weight: 900; font-style: italic; letter-spacing: -0.03em;
  margin: 6px 0 4px;
}
#game-view .quiz-ende.gewonnen .quiz-ende-kopf { color: var(--correct-text); }
#game-view .quiz-ende-liga { font-size: 1.05rem; font-weight: 700; margin: 0 0 10px; }
#game-view .quiz-ende-loesung,
#game-view .quiz-ende-punkte { font-size: 0.9rem; color: var(--muted); margin: 0 0 6px; }

/* ---- Schmal: Leiter unter das Spiel, zweispaltig ---- */
@media (max-width: 760px) {
  #game-view .quiz-raum { grid-template-columns: minmax(0, 1fr); gap: 18px; }
  /* Dreizehn Stufen untereinander waeren am Handy eine eigene Bildschirmseite.
     Zwei Spalten halbieren das, die Reihenfolge bleibt lesbar. */
  /* Drei Spalten statt zwei: Seit auf dem Telefon nur noch fuenf Stufen
     stehen (die aktuelle, ihre Nachbarn und die Netze), sind zwei Spalten
     drei Zeilen und drei Spalten zwei. */
  #game-view .quiz-leiter {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px 8px;
  }
  #game-view .quiz-stufe { padding: 6px 8px; font-size: 0.74rem; }
  /* Die Joker in EINER Zeile, seitlich scrollbar statt in zwei Reihen.
     Gemessen kostete der Umbruch 92 px statt 46 — und die vier Knoepfe
     behalten so ihre Breite, statt "Videobeweis" umbrechen zu lassen.
     Dieselbe Loesung wie bei der Modusreihe im Spielkopf. */
  #game-view .quiz-joker-reihe {
    display: flex; gap: 8px; margin-top: 12px;
    overflow-x: auto; scrollbar-width: none;
    padding-inline: 16px; margin-inline: -16px;
  }
  #game-view .quiz-joker-reihe::-webkit-scrollbar { display: none; }
  #game-view .quiz-joker { flex: 0 0 auto; min-width: 88px; }

  #game-view .quiz-antwort { padding: 12px 13px; }
  #game-view .quiz-kopf { margin-bottom: 8px; }
}

/* ==========================================================================
   Datenherkunft — das ⓘ neben einer Statistik und die Karte dahinter

   Bewusst GLOBAL und nicht unter #game-view: Das Overlay haengt an
   document.body, genau wie Konfetti und Trophaeenregen. Unter #game-view
   deklariert wuerde keine dieser Regeln je greifen. Der Dateikopf warnt
   davor, und es ist hier schon einmal passiert.
   ========================================================================== */

.herkunft-symbol {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  margin-left: 6px;
  padding: 0;
  vertical-align: middle;
  border: 1px solid rgba(var(--violet-rgb), 0.45);
  border-radius: 999px;
  background: rgba(var(--violet-rgb), 0.10);
  color: var(--violet-text);
  font: 700 11px/1 "Inter", system-ui, sans-serif;
  font-style: italic;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.herkunft-symbol:hover,
.herkunft-symbol:focus-visible {
  background: rgba(var(--violet-rgb), 0.22);
  border-color: var(--violet-text);
  transform: scale(1.12);
}

.herkunft-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.62);
  animation: herkunftAuf 0.16s ease;
}
@keyframes herkunftAuf { from { opacity: 0; } to { opacity: 1; } }

.herkunft-karte {
  width: min(520px, 100%);
  max-height: 82vh;
  overflow-y: auto;
  padding: 18px 20px 16px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--card);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.herkunft-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.herkunft-titel {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--violet-text);
}
.herkunft-zu {
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.herkunft-zu:hover { color: var(--ink); }

.herkunft-liste { margin: 0; }
.herkunft-liste dt {
  margin-top: 12px;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.herkunft-liste dt:first-child { margin-top: 0; }
.herkunft-liste dd {
  margin: 4px 0 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink);
}
.herkunft-prop {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 6px;
  background: rgba(var(--violet-rgb), 0.14);
  color: var(--violet-text);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.82rem;
  font-weight: 700;
}
.herkunft-quelle {
  margin: 16px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 0.78rem;
  color: var(--muted);
}
.herkunft-zeile { margin: 0; font-size: 0.9rem; color: var(--ink); }

/* ==========================================================================
   Meine Karriere — Verlauf über alle Spiele

   Unter #game-view, weil die Ansicht wie ein Spielbildschirm in den Rahmen
   gezeichnet wird (dieselbe Stelle wie das Profil).
   ========================================================================== */

#game-view .kar-kopf { margin-bottom: 18px; }
#game-view .kar-titel {
  margin: 0;
  font-size: clamp(1.6rem, 5vw, 2.1rem);
  font-weight: 900;
  letter-spacing: -0.03em;
  color: var(--ink);
}
#game-view .kar-unterzeile { margin: 6px 0 0; font-size: 0.9rem; color: var(--muted); }
#game-view .kar-leerhinweis { margin: 24px 0; }

#game-view .kar-kennzahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin-bottom: 26px;
}
#game-view .kar-kennzahl {
  padding: 14px 12px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  text-align: center;
}
#game-view .kar-kennzahl b {
  display: block;
  font-size: 1.25rem;
  font-weight: 900;
  letter-spacing: -0.02em;
  color: var(--violet-text);
}
#game-view .kar-kennzahl span {
  display: block;
  margin-top: 3px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

#game-view .kar-abschnitt {
  margin: 0 0 10px;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Die Tabelle scrollt in ihrem eigenen Kasten. Ohne das schiebt die dritte
   Spalte auf schmalen Geräten die ganze Seite seitlich weg. */
#game-view .kar-tabellenrahmen {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
}
#game-view .kar-tabelle { width: 100%; border-collapse: collapse; }
#game-view .kar-tabelle thead th {
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: left;
  white-space: nowrap;
}
#game-view .kar-tabelle tbody tr + tr th,
#game-view .kar-tabelle tbody tr + tr td { border-top: 1px solid var(--line); }
#game-view .kar-tabelle th[scope="row"] { padding: 12px 14px; text-align: left; font-weight: 400; }
#game-view .kar-tabelle td { padding: 12px 14px; vertical-align: top; white-space: nowrap; }

#game-view .kar-spiel { display: block; font-weight: 800; color: var(--ink); }
#game-view .kar-unter { display: block; margin-top: 2px; font-size: 0.76rem; color: var(--muted); }
#game-view .kar-serie b, #game-view .kar-best b {
  display: block; font-weight: 800; color: var(--ink); font-size: 0.92rem;
}
#game-view .kar-serie span, #game-view .kar-best span {
  display: block; margin-top: 2px; font-size: 0.72rem; color: var(--muted);
}
#game-view .kar-serie b { color: var(--violet-text); }
#game-view .kar-leer { color: var(--absent); }
/* Nie gespielte Modi bleiben lesbar, treten aber zurück — sie stehen als
   Einladung da, nicht als Lücke. */
#game-view .kar-nie th[scope="row"] .kar-spiel { color: var(--muted); font-weight: 700; }

@media (max-width: 520px) {
  #game-view .kar-tabelle thead th,
  #game-view .kar-tabelle th[scope="row"],
  #game-view .kar-tabelle td { padding: 10px; }
}

/* ==========================================================================
   Spielerbild samt Bildnachweis

   Der Zuschnitt liegt hier und nicht in der Datei: object-fit schneidet nur
   die Darstellung zu. Ein wirklich beschnittenes Bild wäre eine Bearbeitung,
   und bei CC BY-SA zöge das Pflichten nach sich. Die Commons-Bilder sind
   wild — Halbfigur, Mannschaftsfoto, Denkmal —, deshalb der Kreis: Er zeigt
   die Mitte und verbirgt, wie unterschiedlich die Ausschnitte sind.
   ========================================================================== */

#game-view .medienbild {
  margin: 14px 0 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}
#game-view .medienbild img {
  object-fit: cover;
  border: 2px solid rgba(var(--violet-rgb), 0.35);
  background: var(--panel);
}
/* Gesichter: rund, und der Ausschnitt sitzt hoeher — Koepfe stehen selten in
   der Bildmitte. */
#game-view .medienbild--rund img {
  width: 132px;
  height: 132px;
  border-radius: 999px;
  object-position: center 22%;
}
/* Stadien: quer. Ein Stadionfoto im 132-px-Kreis waere ein Ausschnitt vom
   oberen Tribuenenrand. Die Mitte ist hier die richtige Stelle, und 16:9
   entspricht dem, was auf Commons ueberwiegend liegt. */
#game-view .medienbild--breit img {
  width: 100%;
  max-width: 420px;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  object-position: center;
}
/* Der Nachweis ist klein, aber nicht versteckt: Er muss lesbar sein, sonst
   erfüllt er die Lizenzbedingung nicht.

   Auf drei Zeilen begrenzt, und zwar in der DARSTELLUNG, nicht im Text: Der
   vollständige Urhebervermerk steht im HTML und ist verlinkt, er wird nur
   nicht ausgeklappt. Der Median liegt bei 13 Zeichen, aber 3 % der Angaben
   sind Archivmetadaten — die längste hat 4243 Zeichen und würde die Karte
   sonst vollständig zudecken. Gekürzt würde der Vermerk seinen Zweck
   verlieren; abgeschnitten dargestellt tut er das nicht. */
#game-view .medienbild figcaption {
  font-size: 0.68rem;
  line-height: 1.35;
  color: var(--muted);
  text-align: center;
  max-width: 260px;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  line-clamp: 3;
  overflow: hidden;
}
#game-view .medienbild figcaption a { color: var(--muted); text-decoration: underline; }
#game-view .medienbild figcaption a:hover { color: var(--violet-text); }

/* ==========================================================================
   Gesicht auf der Vergleichskarte

   Der Platz steht immer, das Bild kommt erst mit der Auflösung. Ohne den
   festen Platz springt die Karte im Moment des Aufdeckens nach unten —
   ausgerechnet dann, wenn der Blick auf der Zahl liegt.
   ========================================================================== */

#game-view .cmp-portraet {
  width: 76px;
  height: 76px;
  margin: 0 auto 8px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: rgba(var(--violet-rgb), 0.08);
  border: 2px solid var(--line);
  transition: border-color 0.25s ease, transform 0.25s ease;
}
/* ABSOLUT, nicht als Grid-Kind (29.09.2026). Im Grid mit auto-Zeile loeste
   sich height: 100% nicht auf — das Bild nahm seine natuerliche Hoehe
   (gemessen 71 px im 58-px-Kreis), wurde mittig abgeschnitten, und das
   object-position fuer den Kopf griff nie: Koepfe waren oben gekappt. */
#game-view .cmp-portraet { position: relative; }
#game-view .cmp-portraet img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  /* Gesichter sitzen selten in der Bildmitte. Zuschnitt nur in der
     Darstellung — ein wirklich beschnittenes Bild wäre eine Bearbeitung. */
  object-position: center 22%;
  display: block;
}
/* Ohne Bild: die Flagge groß. Kein Loch, sondern das, was die Karte vorher
   schon zeigte — 6 % der Spieler haben kein Foto, Vereine grundsätzlich keins. */
#game-view .cmp-portraet-flagge { font-size: 2rem; line-height: 1; }

/* Beim Aufdecken kurz betonen: Das Gesicht ist die Auflösung, nicht Deko. */
#game-view .cmp-portraet.ist-auf {
  border-color: rgba(var(--violet-rgb), 0.55);
  transform: scale(1.04);
}
#game-view .cmp-card.cmp-wrong .cmp-portraet.ist-auf { border-color: rgba(255, 197, 61, 0.5); }

/* Ist das Gesicht da, ist die Flagge im Kopf doppelt. */
#game-view .cmp-portraet.ist-auf:has(img) + .cmp-card-head .cmp-flag { display: none; }

#game-view .cmp-bildnachweis {
  margin-top: 6px;
  font-size: 0.6rem;
  line-height: 1.3;
  color: var(--muted);
  opacity: 0.75;
  /* Zwei Zeilen reichen; der vollständige Vermerk steht im title und auf der
     Nachweisseite. Kürzen würde ihn entwerten, abschneiden nicht. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
  overflow: hidden;
}
#game-view .cmp-bildnachweis a { color: inherit; text-decoration: underline; }

@media (max-width: 520px) {
  #game-view .cmp-portraet { width: 60px; height: 60px; }
  #game-view .cmp-portraet-flagge { font-size: 1.6rem; }
}

/* Gesicht statt Trikot auf einem besetzten Platz. Das Trikot bleibt für
   leere Plätze und für die 6 % ohne Bild — beides sieht dann aus wie vorher,
   statt ein Loch zu lassen. */
#game-view .m11-kopf {
  display: block;
  width: 34px;
  height: 34px;
  margin: 0 auto;
  border-radius: 999px;
  overflow: hidden;
  border: 1.5px solid rgba(var(--violet-rgb), 0.45);
  background: var(--panel);
}
#game-view .m11-kopf img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 20%;
  display: block;
}
/* Gesammelt statt elfmal einzeln: Elf Vermerke auf dem Spielfeld wären
   unleserlich, weglassen geht wegen CC BY nicht. */
#game-view .m11-nachweise {
  margin: 8px 0 0;
  font-size: 0.62rem;
  line-height: 1.4;
  color: var(--muted);
  opacity: 0.7;
  text-align: center;
}
#game-view .m11-nachweise a { color: inherit; text-decoration: underline; }

/* Impressum und Datenschutz. Nutzen den Rahmen von "Meine Karriere" weiter —
   dieselbe Machart: eine ruhige Seite im Spielrahmen mit eigener Adresse. */
#game-view .recht-view { max-width: 720px; }
#game-view .recht-text {
  margin: 0 0 14px;
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--ink);
}
#game-view .recht-text a { color: var(--violet-text); }
#game-view .recht-leise { font-size: 0.82rem; color: var(--muted); }
#game-view .recht-liste { margin: 0 0 18px; }
#game-view .recht-zeile {
  display: grid;
  grid-template-columns: minmax(0, 200px) 1fr;
  gap: 4px 16px;
  padding: 7px 0;
  border-top: 1px solid var(--line);
}
#game-view .recht-zeile:first-child { border-top: 0; }
#game-view .recht-zeile dt {
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
#game-view .recht-zeile dd { margin: 0; font-size: 0.92rem; color: var(--ink); }
/* Ein noch nicht gefüllter Platzhalter wird deutlich markiert — eine
   Rechtsseite, die so tut als wäre sie fertig, ist schlimmer als ein toter
   Link. */
#game-view .recht-offen {
  color: var(--orange-text);
  font-style: italic;
}
#game-view .recht-warnung {
  margin: 0 0 20px;
  padding: 12px 14px;
  border: 1px solid rgba(var(--orange-rgb), 0.4);
  border-radius: 12px;
  background: rgba(var(--orange-rgb), 0.1);
  color: var(--ink);
  font-size: 0.88rem;
  line-height: 1.5;
}
@media (max-width: 560px) {
  #game-view .recht-zeile { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Erfolge
   ========================================================================== */

#game-view .erf-liste {
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 10px;
}
#game-view .erf-karte {
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  /* Offene Erfolge treten zurück, verschwinden aber nicht: Sie sind die
     Einladung, nicht die Lücke. Wer sie ausgraut, macht aus einer Liste von
     Zielen eine Liste von Versäumnissen. */
  opacity: 0.72;
  transition: opacity 0.2s ease, border-color 0.2s ease;
}
#game-view .erf-karte.ist-da {
  opacity: 1;
  border-color: rgba(var(--violet-rgb), 0.45);
  background: rgba(var(--violet-rgb), 0.08);
}
#game-view .erf-kopf {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
#game-view .erf-titel { font-weight: 800; font-size: 0.96rem; color: var(--ink); }
#game-view .erf-karte.ist-da .erf-titel { color: var(--violet-text); }
#game-view .erf-haken { color: var(--violet-text); font-weight: 900; }
#game-view .erf-text {
  margin: 4px 0 0;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--muted);
}
#game-view .erf-balken {
  margin-top: 9px;
  height: 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}
#game-view .erf-balken span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--violet);
}
#game-view .erf-stand {
  margin-top: 5px;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--muted);
}

/* Die Erfolgsmeldung. Global, weil sie an document.body hängt — unter
   #game-view deklariert würde sie nie greifen (siehe Dateikopf). */
.erfolg-toast b {
  color: var(--violet-text);
  margin-right: 5px;
  text-transform: uppercase;
  font-size: 0.68rem;
  letter-spacing: 0.1em;
}

/* ==========================================================================
   Kaderbau — Karten auf der Hand, Anzeigetafel, Rundenbalken

   Alles auf #game-view begrenzt (siehe Dateikopf). Nichts davon hängt an
   document.body, also gibt es hier keine Ausnahme.

   Die Auswahl ist als Lime-Tönung markiert, nicht mit var(--card): --card ist
   dunkler als --panel, eine aktive Karte auf Panel-Grund wäre damit ein Loch
   statt einer Hervorhebung. Dieselbe Falle steht in CLAUDE.md.
   ========================================================================== */

#game-view .kb-kopfzeile {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 8px;
  font-size: 0.85rem;
  color: var(--muted);
}
#game-view .kb-runde { font-weight: 700; color: var(--text); }
#game-view .kb-gesamt b { color: var(--violet-text); font-variant-numeric: tabular-nums; }

/* Fortschritt zum Rundenziel. Die Höhe ist bewusst klein: Der Balken sagt
   "wie weit", die Zahl darunter sagt "wie viel" — zwei laute Elemente für
   dieselbe Auskunft wären eins zu viel. */
#game-view .kb-balken {
  height: 8px;
  border-radius: 999px;
  background: var(--panel);
  overflow: hidden;
}
#game-view .kb-balken-fuell {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--violet);
  transition: width 0.35s var(--ease-kinetic);
}
#game-view .kb-ziel {
  margin: 6px 0 14px;
  font-size: 0.8rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* ---- Anzeigetafel ---- */

#game-view .kb-tafel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 14px;
}
#game-view .kb-kombo { min-width: 140px; text-align: right; }
#game-view .kb-kombo strong {
  display: block;
  font-size: 1.1rem;
  font-weight: 800;
  color: var(--orange-text);
}
#game-view .kb-kombo span { font-size: 0.72rem; color: var(--muted); }
#game-view .kb-kombo.leer strong { color: var(--absent); }

#game-view .kb-rechnung { display: flex; align-items: center; gap: 8px; }
#game-view .kb-wert {
  font-variant-numeric: tabular-nums;
  font-size: 1.45rem;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 9px;
  min-width: 62px;
  text-align: center;
}
#game-view .kb-chips { background: rgba(var(--violet-rgb), 0.14); color: var(--violet-text); }
#game-view .kb-mult { background: rgba(var(--orange-rgb), 0.14); color: var(--orange-text); }
#game-view .kb-mal { color: var(--muted); }

#game-view .kb-ergebnis { min-width: 110px; }
#game-view .kb-ergebnis strong {
  font-size: 1.45rem;
  font-weight: 800;
  color: var(--violet-text);
  font-variant-numeric: tabular-nums;
}
#game-view .kb-ergebnis small {
  display: block;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Kurzes Aufleuchten nach dem Aufstellen. */
@keyframes kbPuls {
  0% { transform: scale(1); }
  40% { transform: scale(1.08); }
  100% { transform: scale(1); }
}
#game-view .kb-puls { animation: kbPuls 0.4s ease-out; }

/* ---- Leiste ---- */

#game-view .kb-leiste {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  font-size: 0.8rem;
  color: var(--muted);
}
#game-view .kb-leiste b { color: var(--text); font-variant-numeric: tabular-nums; }

/* ---- Hand ---- */

#game-view .kb-hand {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: 9px;
}

#game-view .kb-karte {
  position: relative;
  display: block;
  width: 100%;
  text-align: left;
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: 11px;
  padding: 10px 10px 9px;
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: transform 0.12s var(--ease-kinetic), border-color 0.12s ease, background 0.12s ease;
}
#game-view .kb-karte:hover:not(:disabled) { transform: translateY(-3px); border-color: var(--muted); }
#game-view .kb-karte[aria-pressed="true"] {
  background: rgba(var(--violet-rgb), 0.14);
  border-color: var(--violet-text);
  transform: translateY(-6px);
}
/* Nicht mehr wählbar, weil die Aufstellung voll ist — kein Fehler, nur voll. */
#game-view .kb-karte:disabled { opacity: 0.38; cursor: not-allowed; transform: none; }

/* NUR NAME UND STAERKE. Positionsabzeichen, Vereinszeile und Land stehen
   nicht mehr auf der Karte — der Spieler soll wissen, wer wohin gehoert.

   Die Staerke sitzt oben rechts und nicht mehr in einer Kopfzeile neben dem
   Positionsabzeichen: die Kopfzeile hatte zwei Kinder, jetzt haette sie
   eines und waere eine Zeile, die nichts mehr ausrichtet. Absolut gesetzt
   steht die Zahl an derselben Stelle wie vorher, und der Name laeuft nicht
   dagegen — er bekommt rechts Platz frei.

   Die Karte ist dadurch flacher (drei Zeilen weniger). Die Mindesthoehe
   haelt die Reihe gleichmaessig, auch wenn ein Name umbricht und der
   naechste nicht. */
#game-view .kb-karte { min-height: 76px; padding-right: 40px; }
#game-view .kb-staerke {
  position: absolute;
  top: 9px; right: 11px;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
#game-view .kb-name {
  display: block;
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* Platznummer in der Aufstellung — sagt, in welcher Reihenfolge geklickt
   wurde. Bei den Kombos spielt die Reihenfolge keine Rolle, für die
   Nachvollziehbarkeit der eigenen Auswahl schon. */
#game-view .kb-nummer {
  position: absolute;
  top: -7px;
  left: -7px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--violet);
  color: var(--on-solid);
  font-size: 0.68rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ---- Knöpfe, Regeln, Kombo-Tabelle ---- */

#game-view .kb-knoepfe { display: flex; gap: 9px; flex-wrap: wrap; margin-top: 14px; }
#game-view .kb-knoepfe .action { flex: 1; min-width: 150px; margin-top: 0; }

#game-view .kb-regeln {
  margin: 12px 0;
  padding-left: 18px;
  font-size: 0.85rem;
  color: var(--muted);
}
#game-view .kb-regeln li { margin-bottom: 5px; }

#game-view .kb-ziele { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 14px; }
#game-view .kb-zielchip {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 5px 9px;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}
#game-view .kb-zielchip b { color: var(--violet-text); font-size: 0.68rem; }

/* ---- Die Kombotabelle, offen und neben dem Spiel ----------------------

   Sie lag in einem <details> unter den Knoepfen. Seit die Karten nur noch
   Name und Staerke tragen, ist sie nicht mehr Nachschlagewerk, sondern
   Anleitung — und eine Anleitung, die man aufklappen muss, liest niemand
   waehrend er ueberlegt.

   .kb-buehne ist ein Raster, das erst ab 1040 px zwei Spalten hat. Darunter
   bleibt es eine — auf einem Telefon gibt es kein Nebeneinander, und mit
   340 px Tabelle neben 340 px Karte waere beides zu schmal. Die Schwelle
   ist gemessen: 620 px Karte + 300 px Tabelle + 24 px Luecke + zweimal
   Seitenrand.

   sticky, damit die Tabelle stehen bleibt, waehrend man durch die Hand und
   die Knoepfe scrollt. Sie beantwortet eine Frage, die waehrend des ganzen
   Zuges offen ist. */
#game-view .kb-buehne { display: grid; gap: 20px; align-items: start; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1040px) {
  #game-view .kb-buehne { grid-template-columns: minmax(0, 1fr) 300px; }
  #game-view .kb-kombos { position: sticky; top: 78px; }
}

#game-view .kb-kombos {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 12px 14px 10px;
}
#game-view .kb-kombos__titel {
  margin: 0;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
/* KEINE TABELLE MEHR, sondern eine Liste. Vier Spalten (Kombo, Bedingung,
   Chips, Mult) brauchen Breite; gemessen bei 1280 px stand die Spalte auf
   300 px und "Vereins-Block" lief ueber drei Zeilen — acht Zeilen wurden
   683 px hoch. Als Liste sind es zwei Zeilen je Kombo und rund 350 px.

   Die getroffene Kombo ist hervorgehoben. Das ist der eigentliche Gewinn
   dieser Spalte, seit die Karten ihre Angaben verloren haben: Man waehlt
   zwei Namen und sieht, welche Zeile aufleuchtet — die Rueckmeldung, die aus
   Raten ein Probieren macht. */
#game-view .kb-komboliste { list-style: none; margin: 8px 0 0; padding: 0; }
#game-view .kb-kombozeile {
  padding: 7px 8px;
  border-radius: 8px;
  border: 1px solid transparent;
  font-size: 0.8rem;
}
#game-view .kb-kombozeile + .kb-kombozeile { margin-top: 2px; }
#game-view .kb-kombozeile__kopf {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
}
#game-view .kb-kombozeile__wert {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-size: 0.74rem;
}
#game-view .kb-kombozeile__wert i { font-style: normal; margin-left: 5px; color: var(--gold-text); }
#game-view .kb-kombozeile__bed {
  display: block;
  color: var(--muted);
  font-size: 0.72rem;
  line-height: 1.35;
  margin-top: 1px;
}
#game-view .kb-kombozeile.ist-aktiv {
  background: rgba(var(--violet-rgb), 0.14);
  border-color: var(--violet-text);
}
#game-view .kb-kombozeile.ist-aktiv .kb-kombozeile__bed { color: var(--text); }

#game-view .kb-gross { font-size: 1.25rem; font-weight: 800; margin: 0 0 6px; }
#game-view .kb-naechstes { margin: 12px 0 0; font-size: 0.85rem; color: var(--muted); }

/* ==========================================================================
   Spielinfo — das ⓘ in der Spielleiste, die Kacheln auf der Startseite
   und die Karte hinter beidem

   GLOBAL und bewusst nicht unter #game-view. Zwei Gründe, und beide sind
   hier schon einmal schiefgegangen:

     1. Das Overlay hängt an document.body, genau wie Konfetti und der
        Trophäenregen. Unter #game-view deklariert griffe keine Regel.
     2. Die Kacheln stehen auf der Startseite, also in #catalog-view.

   Aufbau und Maße folgen dem Herkunfts-Overlay darüber — es ist dieselbe
   Sorte Element, und zwei Karten, die verschieden aussehen, ohne dass es
   dafür einen Grund gibt, wirken wie ein Fehler.
   ========================================================================== */

.spielinfo-symbol {
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  margin-left: 6px;
  padding: 0;
  vertical-align: middle;
  border: 1px solid rgba(var(--violet-rgb), 0.45);
  border-radius: 999px;
  background: rgba(var(--violet-rgb), 0.10);
  /* --violet-text statt --violet: Die Marke ist in beiden Themen dasselbe
     Lime, und als FLAECHE stimmt das. Als SCHRIFT auf hellem Grund ist sie
     unlesbar — gemessen Kontrast 1,5. Im dunklen Thema ist --violet-text
     schlicht --violet, dort aendert sich also nichts. */
  color: var(--violet-text);
  font: 700 11px/1 "Inter", system-ui, sans-serif;
  font-style: italic;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.spielinfo-symbol:hover,
.spielinfo-symbol:focus-visible {
  background: rgba(var(--violet-rgb), 0.22);
  border-color: var(--violet-text);
  transform: scale(1.12);
}

/* In der Spielleiste ist es ein eigenständiger Knopf und kein Zusatz an
   einer Beschriftung: größer, fingergerecht, ohne linken Abstand. */
.spielinfo-symbol--leiste {
  width: 30px;
  height: 30px;
  margin-left: 0;
  margin-inline-start: auto;
  flex: 0 0 auto;
  font-size: 14px;
}
.spielinfo-symbol--leiste[hidden] { display: none; }

/* Der Name stand mittig, weil rechts 5.5rem Luft gegen den Zurück-Knopf
   standen. Jetzt steht dort das ⓘ — die Luft wird um dessen Breite kleiner,
   sonst rutscht der Name nach links. */
#game-view .spielleiste__name { padding-right: calc(5.5rem - 38px); }
@media (max-width: 520px) {
  #game-view .spielleiste__name { padding-right: 0; }
}

/* ---- Die Karte ---------------------------------------------------------- */

.spielinfo-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.62);
  animation: spielinfoAuf 0.16s ease;
}
@keyframes spielinfoAuf { from { opacity: 0; } to { opacity: 1; } }

.spielinfo-karte {
  width: min(560px, 100%);
  max-height: 82vh;
  overflow-y: auto;
  padding: 18px 20px 18px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--card);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.spielinfo-kopf {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.spielinfo-label {
  display: block;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--violet-text);
}
.spielinfo-name {
  display: block;
  margin-top: 2px;
  font-family: var(--font-display, inherit);
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--ink);
}
.spielinfo-zu {
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.spielinfo-zu:hover { color: var(--ink); }

.spielinfo-was {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--ink);
}

.spielinfo-liste { margin: 14px 0 0; }
.spielinfo-liste dt {
  margin-top: 14px;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.spielinfo-liste dd {
  margin: 5px 0 0;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--ink);
}

.spielinfo-schritte {
  margin: 0;
  padding-left: 1.2em;
  display: grid;
  gap: 6px;
}
.spielinfo-schritte li { padding-left: 2px; }

.spielinfo-bald {
  margin: 16px 0 0;
  padding: 8px 12px;
  border: 1px dashed var(--line);
  border-radius: 10px;
  font-size: 0.8rem;
  color: var(--muted);
  text-align: center;
}

/* ---- Der Überblick auf der Startseite ----------------------------------- */

.spielinfo-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

/* Die ganze Kachel ist der Knopf. Ein kleiner ⓘ daneben wäre auf dem Handy
   ein 18-px-Ziel neben einer 260 px breiten Fläche, die nichts tut. */
.spielinfo-kachel {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 15px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--card);
  color: inherit;
  text-align: left;
  font: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.15s ease, background 0.15s ease;
}
@media (hover: hover) and (pointer: fine) {
  .spielinfo-kachel:hover {
    border-color: rgba(var(--violet-rgb), 0.55);
    background: rgba(var(--violet-rgb), 0.06);
    transform: translateY(-2px);
  }
}
.spielinfo-kachel:focus-visible {
  outline: 2px solid var(--violet);
  outline-offset: 2px;
}

.spielinfo-kachel__kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.spielinfo-kachel__name {
  font-family: var(--font-display, inherit);
  font-size: 1rem;
  font-weight: 800;
  color: var(--ink);
}
.spielinfo-kachel__i {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border: 1px solid rgba(var(--violet-rgb), 0.45);
  border-radius: 999px;
  background: rgba(var(--violet-rgb), 0.10);
  color: var(--violet-text);
  font: italic 700 11px/1 "Inter", system-ui, sans-serif;
}
.spielinfo-kachel__was {
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--muted);
}

/* Noch nicht gebaut: gedämpft, aber lesbar — die Kachel erklärt ja, was
   kommen soll. Ausgegraut sähe nach kaputt aus. */
.spielinfo-kachel--bald { border-style: dashed; }
.spielinfo-kachel__bald {
  align-self: flex-start;
  margin-top: 2px;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ==========================================================================
   Platzhalter für Spieler ohne Foto

   Wikidata führt zu einem Teil der Spieler keine Bilddatei. Statt drei
   verschiedener Antworten auf dieselbe Lücke (nichts / Flagge / Trikot)
   steht dort jetzt überall dieselbe gezeichnete Silhouette.

   Sie sitzt in genau demselben Rahmen wie ein Foto — gleiche Größe, gleicher
   Rand, gleicher Kreis. Nur so bleibt die Karte ruhig: eine Kachel, die bei
   fehlendem Bild anders aussieht, liest sich als Fehler, nicht als Lücke.

   Die Farbe kommt aus currentColor, deshalb reicht ein Satz Regeln für beide
   Themes. Gedämpft, weil der Platzhalter den Platz hält und nicht auffallen
   soll — er ist die stillste Stelle der Karte, nicht die lauteste.
   ========================================================================== */

#game-view .platzhalter {
  width: 62%;
  height: 62%;
  display: block;
  color: var(--muted);
  opacity: 0.55;
}

/* Steckbrief und Kulisse: derselbe Kreis wie ein Foto, nur gezeichnet. */
#game-view .medienbild--leer {
  /* Der Nachweis fällt weg, also auch sein Abstand — sonst stünde unter dem
     Platzhalter eine leere Zeile, wo sonst der Urheber steht. */
  gap: 0;
}
#game-view .medienbild--leer::before {
  content: "";
  display: grid;
  place-items: center;
  border: 2px dashed rgba(var(--violet-rgb), 0.28);
  background: var(--panel);
}
#game-view .medienbild--rund.medienbild--leer::before {
  width: 132px;
  height: 132px;
  border-radius: 999px;
}
#game-view .medienbild--breit.medienbild--leer::before {
  width: min(320px, 100%);
  aspect-ratio: 16 / 9;
  border-radius: 14px;
}
/* Das SVG liegt im ::before-Kreis — dafür muss es absolut sitzen. */
#game-view .medienbild--leer {
  position: relative;
}
#game-view .medienbild--leer .platzhalter {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 74px;
  height: 74px;
  transform: translate(-50%, -50%);
}

/* Kopf an Kopf: nur nach der Auflösung, siehe app.js. */
#game-view .cmp-portraet-leer {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
}
#game-view .cmp-portraet-leer .platzhalter {
  width: 60%;
  height: 60%;
}

/* Aufstellung: besetzter Platz ohne Foto. Der Rand bleibt durchgezogen wie
   beim Foto — der Platz IST besetzt, nur das Gesicht fehlt. */
#game-view .m11-kopf--leer {
  display: grid;
  place-items: center;
  background: var(--panel);
}
#game-view .m11-kopf--leer .platzhalter {
  width: 68%;
  height: 68%;
}

/* ==========================================================================
   Avatar — das Gesicht im Profil und sein Editor

   GLOBAL, nicht unter #game-view: Das Overlay hängt an document.body, und
   der Avatar steht ausserdem in der Profilkachel der Startseite.

   Der Satz hier lautete frueher, das Profil laufe ueber #catalog-view. Das
   stimmt nicht — gemessen liegt es in #game-view, und deshalb hat die
   Groesse unten (132 px) jahrelang gegen eine aeltere #game-view-Regel mit
   84 px verloren. Siehe dort.
   ========================================================================== */

/* svg.avatar-bild, NICHT .avatar-bild — und das ist der Grund, warum die
   Vorschau im Editor leer aussah.

   rivalz-components.css setzt `svg:not(.sprite) { width: 1em; height: 1em }`
   als Grundgroesse fuer Symbole. Dieser Selektor hat die Spezifitaet (0,1,1),
   weil :not() die seines Arguments uebernimmt — eine blosse Klasse (0,1,0)
   verliert dagegen. Das SVG war deshalb 16 px gross und im 244-px-Kreis
   praktisch unsichtbar, obwohl alle 19 Elemente darin standen.

   Mit dem Elementnamen davor sind es ebenfalls (0,1,1), und styles.css wird
   nach rivalz-components.css geladen — also gewinnt diese Regel. Genau
   dasselbe Verfahren steht dort schon bei svg.cover__szene, mit derselben
   Begruendung.

   GEMESSEN, nicht vermutet: vorher 16x16 im Browser, danach 244x244.
   Meiner Testseite ist es nie aufgefallen, weil sie rivalz-components.css
   gar nicht geladen hat — eine Attrappe, die nachsichtiger ist als die
   Wirklichkeit, kann den Unterschied nicht zeigen. */
svg.avatar-bild {
  display: block;
  width: 100%;
  height: 100%;
  /* Die Symbolregel setzt ausserdem fill:none und stroke:currentColor. Die
     Flaechen des Avatars tragen eigene fill-Attribute, aber der Strich muss
     hier ausdruecklich weg — sonst bekaeme jede Flaeche eine Kontur. */
  fill: none;
  stroke: none;
}

/* Der Avatar im Profilkopf. Er ist jetzt ein Knopf — also muss er sich auch
   wie einer verhalten: Fingergröße, sichtbarer Fokus, Stift beim Darüberfahren. */
.profile-hero-avatar {
  position: relative;
  display: block;
  /* Von 96 auf 132 — dieselbe Groesse wie ein Spielerfoto in Steckbrief und
     Kulisse. Der Avatar ist das einzige Bild auf der Profilseite; kleiner als
     ein Spielerportraet zu sein waere die falsche Rangfolge. */
  width: 132px;
  height: 132px;
  padding: 0;
  margin: 0 auto 10px;
  border: 2px solid rgba(var(--violet-rgb), 0.45);
  border-radius: 999px;
  overflow: hidden;
  background: var(--panel);
  cursor: pointer;
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.profile-hero-avatar:hover { border-color: var(--violet-text); transform: scale(1.03); }
.profile-hero-avatar:focus-visible { outline: 2px solid var(--violet); outline-offset: 3px; }
/* Weiter nach innen gerueckt als die ueblichen 6 px: Der Kreis schneidet mit
   overflow:hidden alles ab, was ausserhalb seiner Rundung liegt, und in einer
   ECKE liegt bei einem Kreis fast alles ausserhalb. Bei 6 px blieb vom
   30er-Knopf eine Sichel stehen. Gerechnet statt geschaetzt: Mittelpunkt des
   Knopfes 48 px vom Kreismittelpunkt, der Rand liegt bei 66 − 15 = 51 — bei
   132 px wie bei 112 px am Handy passt er damit ganz hinein. */
.profile-hero-avatar__stift {
  position: absolute;
  right: 16px;
  bottom: 14px;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: var(--violet);
  color: var(--on-solid);
  font-size: 15px;
  line-height: 1;
  /* Ein Ring in Kartenfarbe, kein Rahmen: box-shadow braucht keinen Platz und
     schiebt den Stift deshalb nicht aus der Ecke. Noetig, seit der gezeichnete
     Avatar den Kreis ausfuellt — vorher sass der Knopf auf dunklem Panel, jetzt
     auf dem Trikot, und ein limefarbener Punkt auf einem limefarbenen Trikot
     ist keiner. Dieselbe Loesung wie beim Level-Abzeichen daneben. */
  box-shadow: 0 0 0 2px var(--card);
}
.profile-avatar-cta { margin-bottom: 6px; }

/* Der Verein steht als Text unter dem Namen. Kein Wappen — Marken, siehe
   docs/BILDRECHTE.md. */
.profile-verein {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-top: 2px;
}

/* Der Avatar in der Profilkachel auf der Startseite.

   Er war 58 px groß und stand auf derselben Grundlinie wie die sechs
   Schussfiguren daneben — gleich hoch, gleich rund, gleiche Zeile. Damit las
   er sich als siebte Figur der Reihe und nicht als das eigene Gesicht. Jetzt
   104 px und über die ganze Zeilenhöhe zentriert: Die Zeile ist 116 px hoch
   (Levelzahl, XP-Zeile, Figurenreihe), der Kreis passt also hinein, ohne dass
   die Kachel wächst — gemessen, die Kachel bleibt bei 244 px.

   align-self, weil die Zeile selbst unten ausgerichtet ist: flex-end hätte den
   größeren Kreis unter die Levelzahl geschoben statt neben sie. */
.hub__avatar {
  flex: 0 0 auto;
  align-self: center;
  display: block;
  width: 104px;
  height: 104px;
  border: 3px solid rgba(var(--violet-rgb), 0.45);
  border-radius: 999px;
  overflow: hidden;
  background: radial-gradient(circle at 50% 35%,
              rgba(var(--violet-rgb), 0.16), var(--panel) 72%);
}
.hub__avatar:empty { display: none; }
.hub__avatar .avatar-bild { width: 100%; height: 100%; }

/* Dieselbe Grenze wie der Zeilenumbruch der Profilkachel in
   rivalz-layout.css. Zwei verschiedene Breakpoints hätten einen Streifen
   dazwischen ergeben, in dem der große Kreis in der noch ungebrochenen Zeile
   steht — und genau dort ist am wenigsten Platz. */
@media (max-width: 560px) {
  .hub__avatar { width: 84px; height: 84px; }
}

/* ---- Editor ------------------------------------------------------------- */

.avatar-overlay {
  position: fixed;
  inset: 0;
  /* --z-modal und nicht eine Zahl aus dem Kopf: Kopfleiste und Spielleiste
     liegen auf 200, die Tab-Leiste auf 210, das Ladebild auf 240. Jede Zahl
     darunter bedeutet, dass die Leiste ueber dem Dialog steht — bei diesem
     hier lag genau der Titel samt Schliesskreuz darunter. Der Ebenenplan
     steht seit jeher in rivalz-tokens.css und wurde von keinem einzigen
     Dialog benutzt. */
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  padding: 18px;
  background: rgba(0, 0, 0, 0.66);
  animation: avatarAuf 0.16s ease;
}
@keyframes avatarAuf { from { opacity: 0; } to { opacity: 1; } }

/* Spalte statt eines einzigen Scrollbereichs: Kopf und Vorschau stehen fest,
   nur die Auswahl darunter scrollt. Vorher lag die Vorschau oben im selben
   Block und war aus dem Bild, sobald man bei den Trikotfarben ankam — also
   genau dann, wenn man sie braucht. */
.avatar-karte {
  width: min(760px, 100%);
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  padding: 16px 18px 18px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--card);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.avatar-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.avatar-titel {
  font-family: var(--font-display, inherit);
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--ink);
}
/* .avatar-zu ist der VERHALTENS-Haken, nicht das Aussehen.

   Beides in einer Klasse war der Fehler: Sie trug das Aussehen des ×
   (1,5 rem, randlos, ohne Flaeche) und haengt gleichzeitig am Schliessen
   (siehe der Klick-Fanger in avatar.js). Der Abbrechen-Knopf braucht den
   Haken — und bekam damit auch die Schriftgroesse des ×. Nebeneinander
   standen dann "Speichern" und ein anderthalbmal so grosses "Abbrechen".

   Das Aussehen sitzt jetzt auf einer eigenen Klasse, die nur das Zeichen
   traegt. Wer einen weiteren Knopf zum Schliessen ergaenzt, erbt kein
   Aussehen mehr mit. */
.avatar-zu { cursor: pointer; }

.avatar-zu--zeichen {
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 1.5rem;
  line-height: 1;
  padding: 0 4px;
}
.avatar-zu--zeichen:hover { color: var(--ink); }

.avatar-vorschau {
  flex: 0 0 auto;
  width: 210px;
  height: 210px;
  margin: 2px auto 14px;
  border: 3px solid rgba(var(--violet-rgb), 0.45);
  border-radius: 999px;
  overflow: hidden;
  /* Ein leichter Verlauf statt einer flachen Flaeche — sonst schwimmt ein
     helles Gesicht auf hellem Grund und ein dunkles auf dunklem. */
  background: radial-gradient(circle at 50% 35%,
              rgba(var(--violet-rgb), 0.14), var(--panel) 70%);
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.35);
}

/* Der scrollende Teil. min-height:0 ist noetig, sonst waechst ein
   Flex-Element ueber seinen Container hinaus statt zu scrollen. */
/* Der Rumpf des Editors — Vorschau und Auswahl.

   WICHTIG, HIER WAR EIN FEHLER: Diese Regel gab es nur ab 640 px. Darunter
   war .avatar-koerper ein gewoehnlicher Block, und damit liefen die
   Flex-Angaben an .avatar-optionen ins Leere: kein min-height, keine
   Scrollflaeche. Die Auswahlliste nahm ihre volle natuerliche Hoehe ein und
   lief unten aus der Karte heraus — auf dem Handy war der Editor unbenutzbar,
   und die Vorschau wurde beim Blaettern nach oben weggeschoben.

   Jetzt ist die Spalte der GRUNDZUSTAND fuer alle Breiten. Ab 640 px wird
   daraus zwei Spalten (siehe unten); die Vorschau bleibt in beiden Faellen
   stehen, waehrend nur die Auswahl scrollt. */
.avatar-koerper {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.avatar-optionen {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}

/* Kurzes Aufleuchten nach jeder Wahl.

   Die Vorschau steht zwar immer im Bild, aber der Blick liegt beim Klicken
   auf den Knoepfen — eine Aenderung an einem 244-px-Bild daneben kann man
   uebersehen. Der Puls ist die Antwort darauf: er zieht das Auge einmal
   hinueber, ohne den Ablauf zu unterbrechen. */
@keyframes avatarPuls {
  0%   { box-shadow: 0 8px 26px rgba(0, 0, 0, 0.35), 0 0 0 0 rgba(var(--violet-rgb), 0.55); }
  100% { box-shadow: 0 8px 26px rgba(0, 0, 0, 0.35), 0 0 0 14px rgba(var(--violet-rgb), 0); }
}
.avatar-vorschau.ist-neu {
  animation: avatarPuls 0.45s var(--ease-out, ease-out);
  border-color: var(--violet-text);
}
@media (prefers-reduced-motion: reduce) {
  .avatar-vorschau.ist-neu { animation: none; }
}

.avatar-reihe { margin-top: 12px; }
.avatar-reihe--paar { display: flex; gap: 12px; }
.avatar-reihe__label {
  display: block;
  margin-bottom: 5px;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.avatar-wahl { display: flex; flex-wrap: wrap; gap: 6px; }

.avatar-knopf {
  padding: 7px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  color: var(--ink);
  font: 650 0.78rem/1 var(--font-body, inherit);
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
}
.avatar-knopf:hover { border-color: rgba(var(--violet-rgb), 0.5); }
/* Ausgewählt wird mit dem Limeschimmer markiert, nicht mit --card: --card ist
   in diesem Theme DUNKLER als --panel, ein Loch statt einer Hervorhebung. */
.avatar-knopf.ist-an {
  background: rgba(var(--violet-rgb), 0.14);
  border-color: var(--violet-text);
  color: var(--violet-text);
}
.avatar-knopf:focus-visible,
.avatar-farbe:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }

.avatar-wahl--farben { gap: 7px; }
.avatar-farbe {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 2px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: transform 0.14s ease, border-color 0.14s ease;
}
.avatar-farbe:hover { transform: scale(1.1); }
.avatar-farbe.ist-an {
  border-color: var(--violet-text);
  transform: scale(1.12);
  box-shadow: 0 0 0 2px rgba(var(--violet-rgb), 0.25);
}
/* Hauttoene sind fuenf statt zehn und tragen mehr Gewicht — sie duerfen
   groesser sein und stehen dann trotzdem in einer Reihe. */
.avatar-farbe--gross { width: 38px; height: 38px; }

.avatar-trenner {
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--violet-text);
}

.avatar-feld { display: block; flex: 1 1 0; }
.avatar-feld--breit { width: 100%; }
.avatar-feld input[type="text"] {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  color: var(--ink);
  font: 400 0.88rem/1.3 var(--font-body, inherit);
}
.avatar-feld input[type="text"]:focus-visible {
  outline: none;
  border-color: var(--violet-text);
}

.avatar-hinweis {
  margin: 8px 0 0;
  font-size: 0.74rem;
  line-height: 1.45;
  color: var(--muted);
}

.avatar-aktionen {
  flex: 0 0 auto;
  display: flex;
  gap: 10px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.avatar-aktionen .action { flex: 1 1 0; }

/* Ab 640 px stehen Bild und Auswahl NEBENEINANDER.

   Untereinander muss die Vorschau klein bleiben, damit unter ihr noch etwas
   zu sehen ist — und klein war ja der Vorwurf. Nebeneinander darf sie so
   gross sein, wie sie sein soll: Sie nimmt die linke Spalte ein, bleibt beim
   Blaettern stehen, und rechts laeuft die Auswahl durch. Man sieht die
   Aenderung, waehrend man sie trifft, statt danach nach oben zu scrollen. */
@media (min-width: 640px) {
  .avatar-koerper {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 20px;
    align-items: start;
    min-height: 0;
    flex: 1 1 auto;
  }
  .avatar-vorschau {
    position: sticky;
    top: 0;
    width: 244px;
    height: 244px;
    margin: 0;
  }
  .avatar-optionen { max-height: 62vh; }
}

@media (max-width: 420px) {
  .avatar-reihe--paar { flex-direction: column; gap: 10px; }
  .avatar-vorschau { width: 168px; height: 168px; }
  .profile-hero-avatar { width: 112px; height: 112px; }
}

/* ==========================================================================
   Kalender — Woche, Wochenziel und Monat auf der Profilseite

   GLOBAL, nicht unter #game-view: Die Profilseite läuft zwar durch dieselbe
   Ansicht, aber sie ist kein Spiel — und derselbe Kalender soll später ohne
   Umbau auch anderswo stehen können.

   Die vier Füllstufen sind Abstufungen EINER Farbe, nicht vier Farben. Vier
   Farben hießen vier Bedeutungen; hier gibt es nur eine, nämlich "wie viel".
   ========================================================================== */

.kal {
  margin: 22px 0 8px;
  padding: 16px 16px 14px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
}
/* Der Kalender konnte nicht geladen werden. Sieht aus wie der Kasten selbst
   (gleicher Rahmen, gleicher Grund), damit die Stelle nicht leer wirkt —
   aber ohne Ueberschrift, weil hier kein Kalender steht, sondern der Grund,
   warum keiner da ist. Nicht auf #game-view begrenzt: Das Profil laeuft zwar
   darin, aber die Regel gehoert zum Kalender und der wird auch anderswo
   eingesetzt werden. */
.kal-fehlt {
  margin: 22px 0 8px;
  padding: 16px;
  border: 1px dashed var(--line);
  border-radius: 16px;
  background: var(--card);
  color: var(--muted);
  font-size: 0.9rem;
}
.kal-fehlt p { margin: 0; }
.kal-fehlt p + p { margin-top: 4px; font-size: 0.82rem; opacity: 0.85; }

.kal-titel {
  margin: 0 0 14px;
  font-family: var(--font-display, inherit);
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--ink);
}
.kal-abschnitt {
  display: block;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---- Füllstufen ---------------------------------------------------------- */
.kal-s0 { background: rgba(255, 255, 255, 0.055); }
.kal-s1 { background: rgba(var(--violet-rgb), 0.28); }
.kal-s2 { background: rgba(var(--violet-rgb), 0.55); }
.kal-s3 { background: rgba(var(--violet-rgb), 0.88); }
.kal-s2 .kal-zelle__zahl,
.kal-s3 .kal-zelle__zahl,
.kal-s3 { color: var(--on-solid); }

/* Der Rekordpunkt. Klein und in der Zweitfarbe — er soll auffallen, ohne mit
   der Füllstufe um dieselbe Aussage zu konkurrieren. */
.kal-rekord {
  position: absolute;
  right: 3px;
  top: 3px;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--orange);
}
.kal-rekord--legende { position: static; display: inline-block; vertical-align: middle; }

/* ---- Wochenband ---------------------------------------------------------- */
.kal-wband {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin: 8px 0 6px;
}
.kal-wtag { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.kal-wtag__name { font-size: 0.62rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }
.kal-wtag__feld {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 10px;
  font-size: 0.82rem;
  font-weight: 800;
  color: var(--ink);
}
.kal-wtag__zahl { font-size: 0.62rem; color: var(--muted); }
.kal-wtag.ist-heute .kal-wtag__feld { box-shadow: 0 0 0 2px var(--violet); }
.kal-wtag.ist-kommend { opacity: 0.42; }
.kal-summe { margin: 0; font-size: 0.8rem; color: var(--muted); }

/* ---- Wochenziel ---------------------------------------------------------- */
.kal-ziel {
  margin: 16px 0;
  padding: 12px 13px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}
.kal-ziel__kopf { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.kal-ziel__label {
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--violet-text);
}
.kal-ziel__wert { font-size: 0.82rem; font-weight: 700; color: var(--ink); }
.kal-stufen { display: grid; gap: 6px; margin-top: 10px; }
.kal-stufe {
  display: grid;
  grid-template-columns: 26px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.03);
  opacity: 0.55;
}
.kal-stufe.ist-an {
  opacity: 1;
  background: rgba(var(--violet-rgb), 0.12);
}
.kal-stufe__punkt {
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  font-size: 0.75rem; font-weight: 800; color: var(--muted);
}
.kal-stufe.ist-an .kal-stufe__punkt { background: var(--violet); color: var(--on-solid); }
.kal-stufe__name { font-size: 0.85rem; font-weight: 700; color: var(--ink); }
.kal-stufe__xp { font-size: 0.74rem; font-weight: 700; color: var(--muted); }
.kal-stufe.ist-an .kal-stufe__xp { color: var(--violet-text); }
.kal-ziel__rest { margin: 9px 0 0; font-size: 0.78rem; color: var(--muted); }

/* ---- Monatsraster -------------------------------------------------------- */
.kal-monat__kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 8px;
}
.kal-pfeil {
  width: 30px; height: 30px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: transparent;
  color: var(--ink);
  font-size: 1.05rem; line-height: 1; cursor: pointer;
}
.kal-pfeil:disabled { opacity: 0.3; cursor: default; }
.kal-pfeil:not(:disabled):hover { border-color: var(--violet-text); color: var(--violet-text); }

.kal-wochentage, .kal-raster {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
}
.kal-wochentage span {
  text-align: center; font-size: 0.6rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em; padding-bottom: 4px;
}
.kal-zelle {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-radius: 8px;
  font-size: 0.72rem;
  color: var(--ink);
}
.kal-zelle.ist-leer { background: none; }
.kal-zelle.ist-heute { box-shadow: 0 0 0 2px var(--violet); }
.kal-zelle.ist-kommend { opacity: 0.32; }
/* Ausserhalb der 60 Tage: Da liegen keine Daten mehr, also darf die Zelle
   auch nicht wie ein ungespielter Tag aussehen. */
.kal-zelle.ist-alt { opacity: 0.22; }
.kal-leer { margin: 10px 0 0; font-size: 0.8rem; color: var(--muted); text-align: center; }

.kal-legende {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin: 12px 0 0; font-size: 0.7rem; color: var(--muted);
}
.kal-legende__skala { display: inline-flex; gap: 3px; }
.kal-legende__skala i { width: 12px; height: 12px; border-radius: 3px; }

@media (max-width: 420px) {
  .kal { padding: 13px 12px 12px; }
  .kal-stufe { grid-template-columns: 24px 1fr auto; gap: 8px; }
}

/* ---------- Kaderbau: der Laden ----------------------------------------
   Unter #game-view, weil alles hier zur Spielflaeche gehoert — siehe den
   Dateikopf. Farben aus der Palette, damit der Laden den Hellmodus
   mitmacht. */
#game-view .kb-kasse {
  display: flex; flex-direction: column; gap: 2px;
  margin: 14px 0 4px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--panel);
}
#game-view .kb-kasse__zeile { color: var(--muted); font-size: 0.92rem; }
#game-view .kb-kasse__summe { margin-top: 6px; font-size: 1.1rem; color: var(--text); }
#game-view .kb-ladenTitel { margin: 18px 0 8px; font-size: 1rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
#game-view .kb-angebot { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
#game-view .kb-posten {
  padding: 12px 14px; border: 1px solid var(--line);
  border-radius: 14px; background: var(--card);
}
/* Zu teuer heisst blass, nicht weg: Man soll sehen, worauf man sparen kann. */
#game-view .kb-posten--teuer { opacity: 0.55; }
#game-view .kb-posten__kopf { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
#game-view .kb-posten__name { font-weight: 700; }
#game-view .kb-posten__preis { color: var(--violet-text); font-weight: 700; font-variant-numeric: tabular-nums; }
#game-view .kb-posten__text { margin: 4px 0 10px; color: var(--muted); font-size: 0.92rem; }
#game-view .kb-kaufen, #game-view .kb-entfernen {
  min-height: 44px; padding: 0 16px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--violet-text); background: rgba(var(--violet-rgb), 0.12);
  color: var(--violet-text); font-weight: 700; font-family: inherit;
}
#game-view .kb-kaufen[disabled], #game-view .kb-entfernen[disabled] {
  cursor: default; border-color: var(--line);
  background: transparent; color: var(--muted);
}
#game-view .kb-deckzeile {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap; margin-top: 14px; color: var(--muted); font-size: 0.92rem;
}


/* ==========================================================================
   Handy: Bereiche, zwei Infokacheln, kompaktere Masse

   Gemessen bei 390x844 vor dem Umbau: die Startseite war 6900 Pixel hoch,
   also 8,2 Bildschirme. Davon Katalog 2,1 · Spielinfo 1,6 · How 0,8. Die
   Tableiste sprang darin herum, statt Ansichten zu wechseln.
   ========================================================================== */

/* OHNE MEDIENABFRAGE, seit die zwei Kacheln ueberall gelten (6. September
   2026). Beide Regelbloecke standen unter @media (max-width: 899px), weil die
   kompakte Form nur dort galt. Haetten sie dort bleiben duerfen, waere das
   Ergebnis am Rechner zweimal falsch gewesen: "So funktioniert's" stuende
   als Kachel UND als eigener Abschnitt da, und die zwei Kacheln lagen in
   einem Raster, das fuer zehn gebaut ist (auto-fill ab 260 px) — zwei
   Kacheln nebeneinander und rechts daneben die halbe Zeile leer. */

/* "So funktioniert's" steht als Kachel neben der Spielerklaerung
   (spielinfo.js). Der eigene Abschnitt mit drei nummerierten Schritten
   kostete 702 Pixel fuer drei Saetze. */

/* Zwei Kacheln nebeneinander statt zehn untereinander.

   DIE WERTE SIND GEWACHSEN (7. September 2026), weil sich der Ort geaendert
   hat. Sie standen erst unter dem Katalog, am Ende einer langen Liste, und
   waren dort bewusst KLEINER als eine normale Kachel: Polster 12/12/14 statt
   14/15, Titel 0,92 statt 1 rem, Text 0,76 statt 0,85. Als Fussnote unter
   einer Kachelwand war das richtig.

   Auf der Startseite, direkt hinter "Heute", ist es falsch. Gemessen bei
   1280 px: die Kachel war 591 x 77 px — ein Streifen im Verhaeltnis 7,7:1,
   neben "Heute"-Karten von 251 px und Katalogkacheln von 342 px. Sie sah
   nicht kompakt aus, sondern uebriggeblieben.

   Jetzt 589 x 111 px, Verhaeltnis 5,3:1. Groesser als der Grundwert und
   nicht kleiner, weil die Kachel hier 590 px breit ist statt der 260 px, fuer
   die das Grundraster gebaut wurde — bei knapp der dreifachen Breite traegt
   sie auch mehr Polster. Wer daran dreht, misst hinterher nach. */
.spielinfo-grid--schmal { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.spielinfo-grid--schmal .spielinfo-kachel { padding: 16px 16px 18px; gap: 10px; }
.spielinfo-grid--schmal .spielinfo-kachel__name { font-size: 1rem; }
.spielinfo-grid--schmal .spielinfo-kachel__was { font-size: 0.82rem; }
.spielinfo-grid--schmal .spielinfo-kachel__i { width: 22px; height: 22px; }

/* DIE GROSSE FASSUNG ERST AB 700 PIXELN, und die Grenze ist gemessen.

   Ein Polster kann nicht beiden Breiten dienen: Die Kachel ist bei 1280 px
   590 breit und bei 375 px nur 164 — knapp ein Drittel. Mit 24/26 Polster
   ueberall stand auf dem Handy eine 164 x 209 grosse Kachel, deren Titel
   "Alle Spiele erklärt" auf DREI Zeilen umbrach. Aus "ein bisschen groesser"
   war dort ein Kloben geworden.

   Gemessen bricht der Titel ab etwa 310 px Kachelbreite nicht mehr um; bei
   zwei Spalten ist das kurz vor 700 px Fensterbreite erreicht. 700 ist also
   die sichere Schwelle, nicht der genaue Kipppunkt — bei 690 px steht die
   Kachel auf 314 x 90, bei 720 px auf 328 x 132. */
@media (min-width: 700px) {
  .spielinfo-grid--schmal { gap: 14px; }
  .spielinfo-grid--schmal .spielinfo-kachel { padding: 24px 26px; gap: 12px; }
  .spielinfo-grid--schmal .spielinfo-kachel__name { font-size: 1.12rem; }
  .spielinfo-grid--schmal .spielinfo-kachel__was { font-size: 0.88rem; }
  .spielinfo-grid--schmal .spielinfo-kachel__i { width: 26px; height: 26px; font-size: 13px; }
}

/* IM HUB sehen die beiden Kacheln aus wie alles andere dort: dunkles Glas auf
   dem Foto. Seit dem 11. September 2026 stehen sie nicht mehr als eigener
   Abschnitt unter der Buehne, sondern als Zeile im Hub — siehe den Kommentar
   im index.html.

   Die Angaben sind nicht abgeschrieben, sondern dieselben Token wie bei
   .hub__tile in rivalz-layout.css. Waere es eine Kopie mit eigenen Werten,
   liefe sie beim naechsten Anfassen der Buehne auseinander.

   DREI Klassen tief, und das ist kein Versehen: .spielinfo-grid--schmal
   .spielinfo-kachel setzt Polster mit derselben Staerke wie .hub
   .spielinfo-kachel, und dann entschiede die Reihenfolge im Blatt. Eine
   Stufe mehr gewinnt unabhaengig davon, wo der Block steht. */
/* Auch UNTEREINANDER derselbe Abstand wie im Raster. Die eigene Regel der
   Kacheln steht auf 14 px — das war richtig, solange sie ein eigener Abschnitt
   waren, und faellt hier aus der Reihe. */
.hub .spielinfo-grid { gap: var(--space-xs); }

.hub .spielinfo-grid .spielinfo-kachel {
  padding: var(--space-sm);
  gap: var(--space-xs);
  border-radius: var(--radius-lg);
  border: 1px solid var(--hub-linie);
  background: var(--hub-glas);
  box-shadow: var(--hub-glas-schatten);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  backdrop-filter: blur(14px) saturate(1.3);
}

/* Auf dem Handy wird die Kachel im Raster kleiner — dieselbe Grenze, dieselben
   Masse. Ohne das sassen hier 22 px Radius neben 14 px. */
@media (max-width: 860px) {
  .hub .spielinfo-grid .spielinfo-kachel {
    padding: var(--space-xs);
    border-radius: var(--radius-md);
  }
}

/* Die Schrift laeuft ueber die Hub-Token statt ueber --ink und --muted. Die
   gehoeren zur Seitenflaeche; hier liegt die Kachel auf einem Foto, und im
   hellen Modus stuende sonst Fast-Schwarz auf fast schwarzem Glas. Genau die
   Falle, die der Kommentar bei .hub beschreibt. */
.hub .spielinfo-kachel__name { color: var(--color-fg); }
.hub .spielinfo-kachel__was  { color: var(--color-fg-muted); }
.hub .spielinfo-kachel__i {
  border-color: var(--hub-umriss);
  background: rgba(255, 255, 255, 0.10);
  color: var(--color-fg);
}

@media (hover: hover) and (pointer: fine) {
  /* Derselbe Hub, dasselbe Anheben. Der lila Schimmer der Seitenflaeche
     waere hier ein zweiter Akzent auf einem Foto, das schon einen hat. */
  .hub .spielinfo-grid .spielinfo-kachel:hover {
    transform: translateY(-3px);
    border-color: rgba(255, 255, 255, 0.3);
    background: var(--hub-glas);
  }
  :root[data-theme='light'] .hub .spielinfo-grid .spielinfo-kachel:hover {
    border-color: rgba(38, 33, 25, 0.28);
  }
}

/* Die Auswahlliste "Welches Spiel?" — eine Frage, eine Liste, danach weg. */
.spielinfo-wahl { list-style: none; margin: 4px 0 0; padding: 0; }
.spielinfo-wahl li + li { border-top: 1px solid var(--line); }
.spielinfo-wahl button {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 48px;
  padding: 12px 4px;
  border: 0;
  background: none;
  color: var(--ink);
  font: 600 0.95rem/1.3 inherit;
  text-align: left;
  cursor: pointer;
}
.spielinfo-wahl__pfeil { color: var(--muted); font-size: 1.3rem; line-height: 1; }
@media (hover: hover) and (pointer: fine) {
  .spielinfo-wahl button:hover { color: var(--violet-text); }
}
.spielinfo-wahl button:focus-visible { outline: 2px solid var(--violet); outline-offset: -2px; }

/* Die drei Schritte im Overlay. Nummern brauchen sie hier nicht mehr: In
   einer kurzen Liste ist die Reihenfolge die Reihenfolge. */
.spielinfo-schritte--how { padding-left: 1.1em; }
.spielinfo-schritte--how li { margin-top: 10px; font-size: 0.88rem; line-height: 1.5; }
.spielinfo-schritte--how strong { color: var(--ink); }

@media (max-width: 899px) {
  /* ---- Was auf dem Handy nichts beiträgt ---------------------------------
     Gemessen im Bereich "Start": Fusszeile 606 px, CTA-Band 414, Laufband 52
     — zusammen 1072 der 3021 Pixel, also gut ein Drittel, ohne dass eines
     davon eine Frage beantwortet.

     Die FUSSZEILE ist auf dem Handy doppelt: Sie wiederholt die Tableiste
     und haengt darunter noch Rechtliches. Bleibt eine Zeile mit genau dem,
     was sie allein traegt — Impressum, Datenschutz, Bildnachweise.

     Das LAUFBAND ist Zierde. Auf dem Rechner traegt es die Breite; auf dem
     Handy ist es eine Zeile, die scrollt, waehrend man scrollt. */
  .marquee { display: none; }

  .footer__inner { gap: 12px; }
  .footer__col:not(:last-child) { display: none; }
  .footer__col:last-child { display: flex; flex-direction: row; flex-wrap: wrap; gap: 6px 16px; }
  .footer__col:last-child .footer__h { display: none; }
  .footer__brand, .footer__tag { display: none; }

  /* ---- Kompaktere Abschnitte -------------------------------------------- */
  .sectionhead { margin-bottom: 12px; }
  .sectionhead__title { font-size: 1.35rem; }
  .sectionhead__sub { font-size: 0.82rem; }
  /* Der ABSTAND SELBST wird kleiner, nicht das Polster eines einzelnen
     Blocks. Hier stand `.section { padding-block: 20px }`, und damit galt der
     schmalere Wert nur fuer Abschnitte — die Buehne rechnete weiter mit
     --space-section und stand als Einzige 48 statt 40 Pixel von ihrem
     Nachbarn ab. Am Token gedreht folgen ihr Buehne und Laufband von selbst;
     wer den Wert aendert, aendert genau eine Zahl. */
  :root { --space-section: 40px; }

  /* Die Kachelbilder waren 172x107 — auf zwei Spalten die groesste Flaeche
     der Seite, und sie zeigen ein Brett, keine Information. Flacher heisst
     mehr Kacheln je Bildschirm, ohne dass das Motiv verschwindet. */
  /* Bis zum 27.09.2026 stand hier 16/7 — ein flacher Streifen, damit mehr
     Kacheln auf einen Bildschirm passen. Auf Ansage des Eigentuemers traegt
     das Bild jetzt rund 65 % der Kachel; Platz spart stattdessen der Koerper:
     drei Schlagwoerter statt zwei Zeilen Beschreibung. */
  .card__body { padding: 8px 9px 9px; gap: 5px; }
  .card__title { font-size: 0.92rem; min-height: 0; }
  .card__tagline { font-size: 0.76rem; -webkit-line-clamp: 2; }
  .card__tags { font-size: 0.62rem; }
  .card__tags span + span::before { margin: 0 0.3em; }
  .card__flags { top: 7px; left: 7px; right: 7px; gap: 4px; }
  .card__flags .badge { font-size: 0.56rem; padding: 3px 7px; letter-spacing: 0.04em; }
  .card__info { width: 20px; height: 20px; font-size: 0.72rem; }
  .card__foot { margin-top: 0; }

  /* Der Hub: die beiden grossen Kacheln tragen den Bildschirm, der Rest
     darf schmaler werden. */
  .hub__tile--heute { min-height: 0; }
  .hub__big { font-size: 1.5rem; }
}

/* Die Liste "Deine Ligen" auf der Liga-Startseite. Sie erscheint nur, wenn
   der Server Mitgliedschaften kennt, die dieser Browser nicht kannte. */
#game-view .liga-meine { list-style: none; margin: 6px 0 0; padding: 0; }
#game-view .liga-meine li + li { border-top: 1px solid var(--line); }
#game-view .liga-meine__eintrag {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 48px;
  padding: 10px 2px;
  border: 0;
  background: none;
  color: var(--ink);
  font: 700 0.95rem/1.3 inherit;
  text-align: left;
  cursor: pointer;
}
#game-view .liga-meine__pfeil { color: var(--muted); font-size: 1.3rem; line-height: 1; }
#game-view .liga-meine__eintrag:focus-visible { outline: 2px solid var(--violet); outline-offset: -2px; }
@media (hover: hover) and (pointer: fine) {
  #game-view .liga-meine__eintrag:hover { color: var(--violet-text); }
}

/* Das hidden-Attribut setzt nur `display: none` im Browser-Standard — jede
   Klassenregel mit eigenem display schlaegt es. .stage traegt display:flex,
   .marquee ebenso; beide blieben deshalb sichtbar, obwohl zeigeBereich() sie
   ausgeblendet hatte. Gemessen: Nach dem Tippen auf "Spiele" stand der Hero
   weiter ueber dem Katalog.

   !important ist hier richtig und nicht Faulheit: "ausgeblendet" ist keine
   Gestaltungsfrage, ueber die eine spaetere Regel entscheiden darf. */
[data-bereich][hidden] { display: none !important; }

/* ==========================================================================
   Rückmeldung (public/rueckmeldung.js)

   GLOBAL und NICHT unter #game-view: Knopf und Fläche hängen an
   document.body, genau wie Konfetti und die Trophäenregen. Unter #game-view
   deklariert würden sie nie greifen — das ist hier schon einmal passiert.
   ========================================================================== */
.rm-knopf {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 60;
  padding: 9px 15px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  font: 600 0.82rem/1 inherit;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
}
.rm-knopf:hover { border-color: var(--violet-text); color: var(--violet-text); }
.rm-knopf:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }
/* Über der Tab-Leiste auf dem Handy, sonst verdeckt sie ihn. */
@media (max-width: 720px) {
  .rm-knopf { bottom: calc(var(--tabbar-h, 62px) + 12px); right: 12px; }
}

.rm-flaeche {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: end center;
  padding: 16px;
  background: rgba(2, 6, 4, 0.6);
}
@media (min-width: 560px) { .rm-flaeche { place-items: center; } }

.rm-karte {
  width: min(440px, 100%);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.rm-titel { margin: 0; font-size: 1.05rem; }
.rm-hinweis { margin: 0; color: var(--muted); font-size: 0.82rem; line-height: 1.45; }
/* Die drei Einstiege. Global wie der Rest von .rm-*, weil die Flaeche an
   document.body haengt und nicht unter #game-view — das ist hier schon einmal
   schiefgegangen. */
.rm-einstiege {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 10px;
}
.rm-einstieg {
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  border-radius: 999px;
  padding: 6px 12px;
  font: 600 13px/1 inherit;
  cursor: pointer;
}
.rm-einstieg:hover { color: var(--text); border-color: var(--muted); }
.rm-einstieg.an {
  background: rgba(var(--marke-rgb), 0.14);
  border-color: var(--violet-text);
  color: var(--text);
}

.rm-text {
  width: 100%;
  resize: vertical;
  min-height: 92px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: 0.92rem;
}
.rm-text:focus-visible { outline: 2px solid var(--violet); outline-offset: 1px; }
.rm-fehler { margin: 0; color: var(--rot-text); font-size: 0.82rem; }
.rm-knoepfe { display: flex; gap: 8px; justify-content: flex-end; }
.rm-ab, .rm-los {
  padding: 9px 16px;
  border-radius: 999px;
  font: 600 0.85rem/1 inherit;
  cursor: pointer;
  border: 1px solid var(--line);
}
.rm-ab  { background: transparent; color: var(--muted); }
.rm-los { background: var(--violet); color: var(--on-solid, #06120c); border-color: transparent; }
.rm-ab:focus-visible, .rm-los:focus-visible { outline: 2px solid var(--violet); outline-offset: 2px; }

.rm-danke {
  position: fixed;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 0.85rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}

/* ==========================================================================
   Abschluss-Bildschirm der Tages-Challenge (tagesAbschlussHtml in app.js)

   Eigene Klassen statt der cp-* von Flugroute: Die gehoeren dorthin. Ein
   gemeinsamer Baustein unter fremdem Namen ist der Fehler, den .m11-archiv*
   schon einmal gemacht hat. Wenn alle sechs Spiele umgestellt sind, kann
   Flugroute hierher wechseln und seine eigenen Regeln loeschen.
   ========================================================================== */
#game-view .tagesabschluss { text-align: center; }

#game-view .ta-marke {
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
}
#game-view .ta-titel {
  margin: 6px 0 8px;
  font-family: var(--font-display, inherit);
  font-size: clamp(1.6rem, 5vw, 2.6rem);
  font-weight: 900; letter-spacing: -0.03em; color: var(--ink);
}
#game-view .ta-unterzeile { margin: 0 auto 10px; max-width: 46ch; color: var(--muted); font-size: 0.92rem; }
#game-view .ta-ergebnis { margin: 0 0 18px; color: var(--muted); font-size: 0.9rem; }

#game-view .ta-block {
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 16px; margin: 0 0 14px; text-align: left;
}
#game-view .ta-blocktitel {
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); text-align: center;
}
#game-view .ta-blockhinweis { margin: 4px 0 10px; font-size: 0.8rem; color: var(--muted); }

/* Die sieben Felder der Woche. Vier Zustaende — "unklar" gibt es fuer
   Eintraege aus der ersten Fassung des Speichers, die kein Ergebnis kennen.
   Es als verfehlt zu zeichnen waere geraten. */
#game-view .ta-felder { display: flex; gap: 8px; justify-content: center; margin: 10px 0 12px; }
#game-view .ta-feld { width: 20px; height: 20px; border-radius: 6px; background: var(--line); }
#game-view .ta-feld--treffer { background: var(--correct); }
#game-view .ta-feld--daneben { background: var(--orange); }
#game-view .ta-feld--unklar  { background: var(--muted); opacity: 0.45; }

#game-view .ta-zahlen {
  display: flex; flex-wrap: wrap; gap: 6px 16px; justify-content: center;
  font-size: 0.82rem; color: var(--muted);
}
#game-view .ta-zahlen b { color: var(--ink); font-weight: 800; }

#game-view .ta-tage { display: grid; grid-template-columns: repeat(auto-fit, minmax(86px, 1fr)); gap: 8px; }
#game-view .ta-tag {
  display: flex; flex-direction: column; gap: 3px; align-items: center;
  padding: 10px 6px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card);
  cursor: pointer; font: inherit;
  transition: border-color 0.15s, transform 0.15s;
}
#game-view .ta-tag b { font-size: 0.88rem; font-weight: 800; color: var(--ink); }
#game-view .ta-tag span { font-size: 0.68rem; font-weight: 700; color: var(--violet-text); }
#game-view .ta-tag:hover:not([disabled]) { border-color: var(--violet-text); transform: translateY(-2px); }
#game-view .ta-tag[disabled] { cursor: default; opacity: 0.6; }
#game-view .ta-tag--geloest { border-color: var(--correct-text); background: rgba(23, 166, 90, 0.08); }
#game-view .ta-tag--geloest span { color: var(--correct-text); }
#game-view .ta-tag--daneben { border-color: var(--orange-text); background: rgba(var(--orange-rgb), 0.07); }
#game-view .ta-tag--daneben span { color: var(--orange-text); }

/* Die Aufgabe auf der Kachel — nur bei der Aufstellung, wo Verein und Jahr
   die AUFGABE sind und nicht die Loesung (siehe TA_AUFGABE_SICHTBAR).

   KEINE reservierte Hoehe. Sie war noetig, solange die Namen NACHGETRAGEN
   wurden: Gemessen wuchsen die Kacheln um 6 px, sobald die Antwort eintraf.
   Dagegen half nur, Platz fuer die laengste Zeile vorzuhalten — und der
   machte die Kacheln so breit, dass am Telefon nur noch eine je Reihe passte
   und der Block 665 px hoch wurde.

   Seit die Namen VOR dem Zeichnen geholt werden, gibt es keinen leeren
   Zustand mehr, aus dem heraus etwas springen koennte. Ohne Reservierung
   bleiben die Kacheln schmal, und zwei passen wieder nebeneinander. */
#game-view .ta-tag__aufgabe {
  font-size: 0.72rem;
  font-style: normal;
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
  text-align: center;
  overflow-wrap: anywhere;
}

/* Mit Vereinsnamen brauchen die Kacheln etwas mehr Grundbreite als die blossen
   Tagesnummern — bei 86 px stuende fast jeder Name dreizeilig. */
#game-view .ta-tage:has(.ta-tag__aufgabe) { grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); }

/* ---------------------------------------------------------------------------
   Die Absturzkarte (spielAbsturzZeigen() in app.js)

   GLOBAL UND NICHT UNTER #game-view: Sie steht zwar im Spielcontainer — aber
   der Anlass ist ein Fehler, und wer hier eine Regel scopet, die spaeter
   woanders gebraucht wird, hat den Fehler zweimal. Das ist in diesem Projekt
   schon zweimal passiert.

   Sie sieht bewusst nicht nach Alarm aus. Rot waere die Farbe der verlorenen
   Runde, und das hier ist keine verlorene Runde — es ist ein Fehler auf
   unserer Seite. */
.game-card.absturz { text-align: center; padding: 32px 20px; }
.absturz__titel { font-weight: 800; font-size: 1.05rem; color: var(--text); margin: 0 0 8px; }
.absturz__text  { color: var(--muted); font-size: 0.9rem; line-height: 1.55; margin: 0 auto 20px; max-width: 34em; }
.absturz__wege  { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.absturz__wege .action { min-width: 200px; }

/* Ueberschrift ohne Symbol — nur Kaderbau (siehe kbUeberschrift() in app.js).
   Die Vorlage setzt den Abstand zum Text ueber eine Luecke im Flex-Kasten;
   ohne Symbol bleibt davon nichts uebrig, was zu korrigieren waere. Die
   Regel steht trotzdem hier, damit die Absicht sichtbar ist und niemand das
   Symbol "vergessen" wieder einbaut. */
#game-view .game-h2--nackt { gap: 0; }

/* AUF DEM TELEFON GIBT ES KEIN NEBENEINANDER — dort steht die Liste unter
   dem Spiel, und offen war sie damit 567 px hoch (gemessen bei 375 px, hinter
   einer 917 px hohen Karte). Das ist schlechter als der Ausklapper vorher:
   der war zwar auch unten, aber als eine Zeile sichtbar.

   Also kurz statt zu: nur Name und Wert, je eine Zeile — die Liste sagt
   dann, WELCHE Kombos es gibt, und das ist die Frage, die man im Vorbeigehen
   stellt. Die Bedingung der GETROFFENEN Kombo steht ohnehin gross in der
   Tafel ueber der Hand, deshalb bleibt sie in der hervorgehobenen Zeile
   stehen. Gemessen danach: 224 statt 567 px. */
@media (max-width: 1039px) {
  #game-view .kb-kombozeile__bed { display: none; }
  #game-view .kb-kombozeile.ist-aktiv .kb-kombozeile__bed { display: block; }
  #game-view .kb-kombozeile { padding: 5px 8px; }
}

/* ---- Kaderbau auf EINEN Bildschirm --------------------------------------

   So gewuenscht am 13. September 2026: waehrend eines Spiels soll man nicht
   scrollen muessen. Kaderbau war das teuerste Spiel dabei — gemessen bei
   375x812 waehrend einer Runde 1414 px Dokument gegen 812 px Sichtfeld, also
   602 px zu viel. Die Teile, gemessen statt geschaetzt:

     Ueberschrift 37 · Kopfzeile 29 · Balken 8 · Ziel 40 · Tafel 195
     Leiste 30 · Hand 331 · Knoepfe 117 · Abbruch 47 · Kombos 403

   Nichts davon faellt weg. Was sich aendert, ist die Anordnung — und jede
   der sechs Aenderungen unten steht fuer sich:

   DIE UEBERSCHRIFT steht zweimal. Die Spielleiste 60 px darueber sagt
   bereits "Kaderbau"; darunter noch einmal derselbe Name in 36 px ist auf
   einem Telefon der teuerste Doppelte, den diese Seite hat. Auf dem
   Schreibtisch bleibt er, da kostet die Zeile nichts.

   DIE KOMBOLISTE ZWEISPALTIG. Acht Zeilen untereinander sind 269 px fuer
   Inhalte, die je aus zwei kurzen Wortgruppen bestehen ("Vereins-Block" und
   "50x7"). Nebeneinander sind es vier Zeilen. Die Leseordnung bleibt
   zeilenweise, also weiter absteigend nach Rang — nur umgebrochen.

   DIE TAFEL ZWEIZEILIG statt dreizeilig. Sie brach bei 375 px in drei
   Zeilen um, weil Kombo (140) + Rechnung (160) + Ergebnis (110) nicht
   nebeneinander passen. Der Kombo-Name bekommt die erste Zeile ganz,
   Rechnung und Ergebnis teilen sich die zweite.

   DIE KARTEN FLACHER. 76 px Mindesthoehe fuer eine Zeile Name und eine
   Zahl; 58 reichen, und bei vier Reihen sind das 72 px.

   DIE ZWEI KNOEPFE NEBENEINANDER. `min-width: 150px` liess sie bei 293 px
   Innenbreite untereinander rutschen — zweimal 285 px breit, wo zweimal 143
   genuegen.

   Gemessen danach: siehe CLAUDE.md. */
@media (max-width: 899px) {
  /* Die Spielleiste darueber nennt das Spiel bereits. */
  #game-view .game-h2--nackt { display: none; }

  #game-view .kb-kopfzeile { margin-bottom: 5px; font-size: 0.78rem; }
  #game-view .kb-ziel { margin: 5px 0 9px; font-size: 0.78rem; }
  #game-view .kb-leiste { gap: 10px; margin-bottom: 8px; font-size: 0.75rem; }

  #game-view .kb-tafel { gap: 6px 12px; padding: 10px 12px; margin-bottom: 10px; }
  /* Volle Zeile: dadurch rutschen Rechnung und Ergebnis zusammen in die
     zweite, statt jede fuer sich eine eigene zu bekommen. */
  #game-view .kb-kombo { flex: 1 0 100%; min-width: 0; text-align: center; }
  #game-view .kb-kombo strong { font-size: 1rem; }
  #game-view .kb-wert { font-size: 1.25rem; min-width: 52px; padding: 3px 9px; }
  #game-view .kb-ergebnis { min-width: 0; }
  #game-view .kb-ergebnis strong { font-size: 1.25rem; }

  #game-view .kb-hand { gap: 7px; }
  #game-view .kb-karte { min-height: 50px; padding: 7px 32px 7px 9px; }
  #game-view .kb-staerke { top: 7px; right: 9px; }

  #game-view .kb-knoepfe { gap: 7px; margin-top: 10px; }
  #game-view .kb-knoepfe .action { min-width: 0; flex: 1 1 0; }

  #game-view .kb-kombos { padding: 10px 11px 9px; }
  #game-view .kb-komboliste {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2px 6px;
    margin-top: 6px;
  }
  /* Der Nachbarabstand oben gilt im Raster nicht mehr — `gap` macht das. */
  #game-view .kb-kombozeile + .kb-kombozeile { margin-top: 0; }
  #game-view .kb-kombozeile { padding: 4px 7px; font-size: 0.75rem; line-height: 1.3; }
  #game-view .kb-kombozeile__wert { font-size: 0.68rem; }
  /* AUCH IN DER GETROFFENEN ZEILE NICHT. Die Regel bei 1039 px laesst die
     Bedingung dort stehen und begruendet es damit, dass sie ohnehin gross in
     der Tafel ueber der Hand steht — was genau der Grund ist, sie hier
     wegzulassen. Zweispaltig kommt dazu, dass die eine hohe Zelle ihre ganze
     Rasterzeile mitzieht: 15 px fuer einen Satz, der 400 px weiter oben
     schon einmal dasteht. */
  #game-view .kb-kombozeile.ist-aktiv .kb-kombozeile__bed { display: none; }
}

/* DER RAHMEN UM JEDES SPIEL, und der gilt fuer alle zehn. 32 px oben und
   unten plus 24 px an den Seiten sind auf einem 375 px breiten Geraet 64 px
   Hoehe und 48 px Breite, die kein Spiel benutzt — auf dem Schreibtisch ist
   das Luft um eine 960 px breite Spalte, auf dem Telefon ist es der Rand des
   Bildschirms selbst, und den hat die Huelle schon. Gemessen bringt es jedem
   Spiel 28 px Hoehe und 16 px Breite; bei Kaderbau ist es der Unterschied
   zwischen "passt knapp nicht" und "passt". */
@media (max-width: 899px) {
  #game-view { padding: 18px 16px; }

  /* ERKLAERTEXT IST AUF EINEM TELEFON TEURER ALS ANDERSWO. `.hint` traegt
     0,95 rem bei 20 px Abstand — auf 375 px sind das drei bis fuenf Zeilen,
     gemessen 71 px bei der Elf, 94 px im Abseits. Der Satz bleibt stehen, er
     wird nur so gross gesetzt, wie ein Nebensatz sein muss. */
  #game-view .hint { font-size: 0.85rem; line-height: 1.45; margin-bottom: 14px; }

  /* "button.secondary" ist noetig: Die Grundregel traegt dieses Gewicht
     (Zeile 1179), und ohne das Element im Selektor gewinnt sie mit ihren
     10px/20px. Derselbe Stolperstein steht bei Zeile 3318 beschrieben.
     Betrifft jedes "Aufgeben" und "Abbrechen" — gemessen 47 statt 37 px. */
  #game-view button.secondary { padding: 7px 12px; font-size: 0.85rem; }

  /* Die Modus-Erklaerzeile sagt in einem Satz, was der gewaehlte Modus
     bedeutet. Der Knopf darueber sagt es in zwei Woertern, und auf 375 px
     braucht der Satz drei Zeilen: gemessen 35 px fuer eine Fussnote zu einer
     Beschriftung, die man gerade gelesen hat. Er bleibt, nur kleiner. */
  #game-view .modus-hinweis { font-size: 0.76rem; margin-top: 4px; }

  /* "SCHWIERIGKEIT" vor den drei Knoepfen zwingt die Reihe bei 375 px in zwei
     Zeilen — gemessen 64 statt 35 px. Kopf an Kopf laesst das Wort seit
     laengerem weg (Regel bei 460 px), und die Begruendung dort gilt hier
     genauso: Leicht · Medium · Experte erklaeren sich nebeneinander von
     selbst. Der Wegfall ist nur sichtbar, nicht hoerbar — aria-label bleibt
     an der Leiste. */
  #game-view .grad-titel { display: none; }
}

/* ---- Abseits: der Aufbauschirm ------------------------------------------

   Fuenf Felder, zwei Erklaerabsaetze und ein Knopf standen bei 375 px auf
   1131 px — 319 px zu viel. Der teuerste Posten war ein Satz, den die Seite
   schon kennt: "Ein Handy wandert reihum. Alle sehen denselben Namen …" ist
   bis auf die Wortwahl `SPIELINFO.impostor.was`, und das ⓘ dafuer steht
   60 px darueber in der Spielleiste. Gemessen 94 px, also zwoelf Prozent des
   Schirms fuer einen Satz, der einen Fingertipp entfernt vollstaendiger
   dasteht.

   Auf dem Schreibtisch bleibt er: Dort kostet er nichts und richtet den, der
   das Spiel zum ersten Mal oeffnet. Das ist der einzige Ort in diesem Block,
   an dem Telefon und Schreibtisch unterschiedlich viel Text zeigen — und der
   Grund dafuer ist eine gemessene Zahl, keine Vorliebe.

   Die Erklaerung UNTER "Spielart" bleibt auf beiden: Sie unterscheidet die
   zwei Varianten voneinander, und das steht sonst nirgends. */
@media (max-width: 899px) {
  /* Dieselbe Doppelung wie bei Kaderbau: Die Spielleiste darueber nennt das
     Spiel bereits, hier stuenden Symbol und Name ein zweites Mal — gemessen
     40 px. Der Modifikator kommt aus gameH2() in app.js; die Liga-Seite, die
     dieselbe Vorlage benutzt, bleibt davon unberuehrt. */
  #game-view .game-h2--impostor { display: none; }

  #game-view .impo-einleitung { display: none; }
  #game-view .impo-feld { margin-bottom: 8px; }
  #game-view .impo-stepper { gap: 8px; padding: 3px; }
  /* 40 statt 46 px. Die Grenze fuer einen Daumen liegt bei 44 — der Knopf
     sitzt in einer 46 px hohen Zeile und behaelt damit sein Ziel; kleiner
     wird nur der Kreis, nicht die Flaeche, die auf einen Tipp reagiert. */
  #game-view .impo-step { width: 40px; height: 40px; font-size: 1.15rem; }
  #game-view .impo-wert { font-size: 1.35rem; }
  #game-view .impo-chip { min-height: 38px; padding: 7px 12px; font-size: 0.85rem; }
  #game-view .impo-feld .hint { margin-bottom: 0; }
}

/* ---- Die Elf: das Feld und seine Fusszeile -------------------------------

   Vier Reihen zu 58 px, die Torwartreihe 78, darunter eine 78 px hohe
   Fusszeile — zusammen 415 px von 812. Die Reihen selbst sind das Spiel und
   bleiben antippbar; was sie flacher macht, ist der Rand um sie herum.

   Die Fusszeile traegt drei Dinge nebeneinander (Zaehler, Versuche,
   Aufgeben) und brach bei 375 px um. Kleiner gesetzt passt sie auf eine
   Zeile. */
@media (max-width: 899px) {
  #game-view .m11-feld { padding: 10px 6px 8px; }
  #game-view .m11-reihe { gap: 5px; padding: 0 3px; }
  #game-view .m11-fuss { gap: 8px; margin-top: 2px; padding-top: 7px; }
  #game-view .m11-zaehler { font-size: 1.1rem; }
  #game-view .m11-versuche { font-size: 0.72rem; }
  #game-view .m11-aufgabe { font-size: 0.95rem; }
}

/* ---- Flugroute: die Stationsliste waechst mit dem Spiel ------------------

   Hier ist die Hoehe nicht fest, sie ist ein Spielzug: Am Anfang liegen je
   nach Grad ein bis drei Stationen offen, jede weitere kauft man. Eine Reihe
   war gemessen 97 px, mit umbrechender Zwischenzeile 116 — bei acht
   Stationen sind das ueber 800 px, und dagegen hilft keine Regel.

   Was hilft, ist die Reihe selbst: Sie bestand aus vier Zeilen (Verein,
   Zwischenzeile, Tore, Balken), und die Zwischenzeile brach nur um, weil die
   zweite Rasterspalte 251 px breit war. Schmalere Nummer, engerer Abstand
   und ein Viertel weniger Schriftgroesse halten sie auf einer Zeile.

   Der Balken bleibt. Er ist der einzige Teil der Reihe, den man sieht statt
   liest, und er ist 6 px hoch. */
@media (max-width: 899px) {
  /* Drei Spalten statt zwei: Die Tore standen auf einer eigenen Zeile, weil
     die dritte Spalte bei 375 px nicht mehr passte. Mit `auto` passt sie —
     "0 Tore" ist 45 px breit, der Vereinsname braucht 180 von 265. Eine
     Zeile weniger je Station, und Stationen kommen im Laufe der Runde
     dazu. */
  #game-view .cp-station-row { padding: 6px 9px; gap: 2px 8px; grid-template-columns: 18px minmax(0, 1fr) auto; }
  #game-view .cp-station-num { font-size: 0.72rem; }
  #game-view .cp-station-club { font-size: 0.92rem; }
  #game-view .cp-station-meta { font-size: 0.72rem; }
  /* DIE TORE BLEIBEN AUF EIGENER ZEILE, und das ist gemessen statt
     entschieden. Die Regel bei 600 px schickt sie dorthin, weil die dritte
     Spalte nicht mehr passt — der Versuch, sie mit `auto` zurueckzuholen,
     nahm der Zwischenzeile die Breite: Reihe 88 px statt 90, weil "2018–2020
     · Bordeaux, Frankreich · 25 Spiele" dafuer umbrach. Zwei Pixel fuer eine
     zweite umbrechende Zeile ist kein Tausch. */
  #game-view .cp-station-stats { font-size: 0.72rem; }
  #game-view .cp-stations { gap: 5px; }
  /* Der Knopf trug seine Beschriftung ueber zwei Zeilen und war damit 72 px
     hoch — mehr als eine Stationsreihe, fuer einen Knopf. */
  #game-view .cp-aufdecken .action { padding: 10px 12px; font-size: 0.88rem; }
  #game-view .cp-aufdecken { margin-block: 8px; }
  /* Die Karte ist das Spiel und bleibt. 147 px sind bei 812 px Schirm aber
     ein Fuenftel fuer zwei Punkte und eine Linie; 118 zeigen dieselbe Reise. */
  #game-view .cp-map-wrap { margin: 9px 0; }
  #game-view .cp-map { max-height: 118px; object-fit: cover; }
  #game-view .cp-lives-bar { padding: 6px 14px; gap: 9px; }
  #game-view .cp-shop-hint { margin-top: 7px; font-size: 0.74rem; }
  /* Der Knopf traegt "· −10 Punkte" bereits in seiner Beschriftung; die
     Zeile darunter sagt dasselbe noch einmal in einem Satz. */
  #game-view .cp-aufdecken-preis { display: none; }
  #game-view .cp-map { max-height: 100px; }
  #game-view .cp-stations { margin-bottom: 10px; }
  #game-view .cp-lives-bar { margin-block: 8px; }
  #game-view .cp-question { font-size: 1.05rem; margin-bottom: 8px; }
  #game-view .cp-km { font-size: 0.78rem; }
  #game-view .cp-stations-head { font-size: 0.78rem; }
}

/* ---- Der Weg nach oben: vier Antworten sind die halbe Karte --------------

   Gemessen bei 375 px: Kopf 58, Frage 47, Antworten 258, Joker 42, Fuss 32,
   Leiter 100 — die Seite stand auf 923 px. Die vier Antwortkacheln waren mit
   je 57 px der groesste Posten, und davon ist die Haelfte Polster: Der
   Buchstabe steht in einem 30 px hohen Kreis neben einer 25 px hohen Zeile.

   Sie bleiben Kacheln und bleiben antippbar — 46 px ist ueber der Grenze von
   44, an der ein Ziel fuer einen Daumen zu klein wird. */
@media (max-width: 899px) {
  #game-view .quiz-antwort { padding: 9px 12px; gap: 10px; }
  #game-view .quiz-buchstabe { width: 26px; height: 26px; font-size: 0.8rem; }
  #game-view .quiz-antworten { gap: 7px; }
  #game-view .quiz-frage { font-size: 1.02rem; }
}

/* Hier stand der Tipp-Knopf der Aufstellung — absolut gesetzt rechts neben
   der Reihe, damit er im Raster mit gleich breiten Spalten keine eigene
   Spalte bekommt und die Viererkette nicht aus der Mitte schiebt. Die Tipps
   sind am 13. September 2026 entfallen; die Begruendung steht in server.js.

   `.m11-reihe { position: relative }` bleibt: Es traegt jetzt nichts mehr,
   kostet aber auch nichts, und es ist der Bezug, auf den das Feld sonst
   gebaut ist. */
#game-view .m11-reihe { position: relative; }

/* ---- Die Karrieretabelle auf dem Telefon -------------------------------

   Drei Spalten in 328 px: Spiel 114, Serie 57, Bestleistung 157 — gemessen
   bei 375 px. Darin bricht "4 Runden · 1 h 7 min" um und "1/5 richtig
   platziert" ebenfalls, jede Zeile wird 85 px hoch, und die Kopfzeile sagt
   ueber der schmalsten Spalte "BESTLEISTUNG".

   Der Rahmen kann seitwaerts scrollen (overflow-x), aber eine Tabelle, die
   man schieben muss, um die dritte Spalte zu sehen, ist auf einem Telefon
   keine Tabelle. Unter 560 px wird deshalb jede Zeile zu einem Block: Name
   und Rundenzahl oben, Serie und Bestleistung darunter mit ihrer eigenen
   Beschriftung — die traegt die Zeile dann selbst, weil ueber ihr kein Kopf
   mehr steht.

   Die Beschriftungen kommen aus data-label im Markup, nicht aus content:
   "Serie" — sie sind uebersetzt, und CSS kennt die Sprache nicht. */
@media (max-width: 559px) {
  #game-view .kar-tabelle thead { display: none; }
  #game-view .kar-tabelle,
  #game-view .kar-tabelle tbody,
  #game-view .kar-tabelle tr { display: block; }
  #game-view .kar-tabelle tr + tr { border-top: 1px solid var(--line); }
  #game-view .kar-tabelle tbody tr + tr th,
  #game-view .kar-tabelle tbody tr + tr td { border-top: none; }
  #game-view .kar-tabelle th[scope="row"] { display: block; padding: 12px 14px 6px; }
  #game-view .kar-tabelle td {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 3px 14px;
    white-space: normal;
  }
  #game-view .kar-tabelle td:last-child { padding-bottom: 12px; }
  /* EINE LEERE ZEILE FAELLT WEG, statt 30 px zu brauchen, um "—" zu sagen.
     Im Raster daneben war der Gedankenstrich noetig — dort stand ueber ihm
     eine Kopfzeile, und eine leere Zelle haette wie ein Fehler ausgesehen.
     Als Block traegt jede Zeile ihre Beschriftung selbst; keine Zeile heisst
     dann schlicht "dazu gibt es nichts". Bei zehn Spielen, von denen die
     meisten noch nie gespielt sind, spart das die halbe Seite. */
  #game-view .kar-tabelle td.kar-ohne { display: none; }
  #game-view .kar-tabelle tr:has(td.kar-ohne + td.kar-ohne) th[scope="row"] { padding-bottom: 12px; }
  #game-view .kar-tabelle td::before {
    content: attr(data-label);
    flex: 0 0 82px;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
  }
  /* Im Block stehen Wert und Zusatz nebeneinander statt untereinander —
     sonst haette jede Zeile wieder vier Zeilen Hoehe. */
  #game-view .kar-tabelle .kar-serie b, #game-view .kar-tabelle .kar-best b,
  #game-view .kar-tabelle .kar-serie span, #game-view .kar-tabelle .kar-best span {
    display: inline; margin: 0;
  }
  /* Der Trenner nur NACH einem Wert — b + span, nicht span allein. Wo nichts
     steht, traegt die Zelle nur ein <span> mit dem Gedankenstrich, und daraus
     wurde sonst "· —". */
  #game-view .kar-tabelle .kar-serie b + span::before,
  #game-view .kar-tabelle .kar-best b + span::before { content: " · "; }
}

/* ==========================================================================
   Liga: der Umbau vom 10. September 2026

   Die Spalten haben sich geaendert. Vorher: Platz, Spieler, Punkte, Duelle,
   Siege, Quote — sechs Zahlen fuer typisch drei bis fuenf Zeilen. Jetzt:
   Platz, Spieler, Punkte, Siege, Form, Aktion. "Duelle" und "Quote" sind weg
   (60 Prozent aus drei von fuenf ist eine Zahl mit zu vielen Stellen fuer
   ihre Grundlage), die Form der letzten drei ist dazugekommen, und ganz
   rechts steht der Knopf, mit dem man diese Person fordert.

   EIGENE KLASSE statt Umbau von .liga-zeile: Die Gastansicht zeigt vier
   Spalten, und die Kopfzeile teilt sich das Raster mit den Datenzeilen. Drei
   Raster nebeneinander, jedes fuer sich benannt, ist lesbarer als ein Raster
   mit zwei Ausnahmen. */
/* DIE LETZTE SPALTE IST FEST, UND DAS IST DER GANZE FEHLER GEWESEN.

   Hier stand `auto`. Jede Zeile ist ein EIGENES Raster — die Kopfzeile
   genauso wie jede Datenzeile —, und `auto` misst je Raster den eigenen
   Inhalt: leer in der Kopfzeile, "du" in der eigenen Zeile, ein Knopf
   "Fordern" in allen anderen. Drei verschiedene Breiten, und weil die
   Namensspalte mit `1fr` den Rest schluckt, standen PKT, S und FORM in
   jeder Zeile an einer anderen Stelle. Genau so gemeldet, mit Bild.

   88 px, gemessen am breitesten Inhalt: der Knopf "Fordern" (englisch
   "Challenge") bei 0,72 rem und 8 px Innenabstand. Steht er einmal enger,
   bleibt trotzdem alles in einer Flucht.

   Und die Zahlenspalten sind rechtsbuendig, Kopf wie Zelle: Bei zwei- und
   dreistelligen Punktzahlen wandert eine linksbuendige Zahl unter der
   Ueberschrift weg, sobald jemand ueber 99 kommt. */
/* SIEBEN SPALTEN seit dem 27.09.2026, nicht sechs — "Sp" (ausgetragene
   Duelle) sitzt zwischen Punkten und Siegen. Vorher stand PKT ohne seine
   Grundlage daneben: "6 Punkte" sagt wenig, ohne zu wissen, aus wie vielen
   Duellen sie kommen. Der Wert lag am Server schon bereit (`z.duelle`,
   `ligaTabelle()` in server.js) — nur der Client zeigte ihn nirgends. */
#game-view .liga-tabelle--form .liga-zeile {
  grid-template-columns: 30px minmax(0, 1fr) 44px 36px 34px 62px 88px;
}
#game-view .liga-tabelle--form .liga-zeile > :nth-child(3),
#game-view .liga-tabelle--form .liga-zeile > :nth-child(5) { text-align: right; }
/* "Sp" ist eine Kachel, keine Zahl am rechten Spaltenrand — die Ueberschrift
   sitzt deshalb mittig ueber ihr statt rechtsbuendig wie PKT und S daneben. */
#game-view .liga-tabelle--form .liga-zeile > :nth-child(4) { text-align: center; }
/* Zahlenspalten fest verankert statt am Inhalt gemessen — derselbe Fehler,
   den der Kommentar bei der letzten Spalte oben schon einmal beschreibt,
   trifft jede Spalte mit `auto`-Breite: Sie misst sich je Zeile neu, und die
   Kopfzeile (leerer Inhalt) misst sich anders als eine Datenzeile. Zusaetzlich
   `tabular-nums`, damit eine "1" nicht schmaler ist als eine "8" und eine
   rechtsbuendige Spalte dadurch minimal wandert. */
#game-view .liga-tabelle--form .liga-zeile > :nth-child(3),
#game-view .liga-tabelle--form .liga-zeile > :nth-child(4),
#game-view .liga-tabelle--form .liga-zeile > :nth-child(5) { font-variant-numeric: tabular-nums; }
#game-view .liga-tabelle--gast .liga-zeile {
  grid-template-columns: 30px minmax(0, 1fr) 44px 34px;
}
/* Tages-Liga: Platz, Spieler, Sp (Spieltage), Verpasst, Pkt — feste Breiten
   und tabular-nums aus demselben Grund wie bei .liga-tabelle--form: eine
   Spalte, die sich am Inhalt misst, wandert, sobald jemand zweistellig
   wird. */
#game-view .liga-tabelle--tage .liga-zeile {
  grid-template-columns: 30px minmax(0, 1fr) 40px 68px 44px;
}
#game-view .liga-tabelle--tage .liga-zeile > :nth-child(3),
#game-view .liga-tabelle--tage .liga-zeile > :nth-child(4),
#game-view .liga-tabelle--tage .liga-zeile > :nth-child(5) {
  text-align: right; font-variant-numeric: tabular-nums;
}
#game-view .liga-tabelle--tage .liga-zeile > :nth-child(3) { text-align: center; }

/* Die heutige Aufgabe der Tages-Liga, als Karte ueber der Tabelle — dieselbe
   Rolle wie die Duell-Zeilen unter "Du bist dran" bei einer Duell-Liga. */
#game-view .liga-heute-karte {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 12px 14px; margin-bottom: 4px;
}
#game-view .liga-heute-karte.ist-erledigt { border-color: rgba(var(--marke-rgb), 0.4); }
#game-view .liga-heute-sport { font-size: 0.78rem; color: var(--muted); }
#game-view .liga-heute-spiel { font-weight: 800; color: var(--ink); flex: 1 1 auto; }
#game-view .liga-heute-status.ist-erledigt {
  color: var(--violet-text); font-weight: 700; font-size: 0.86rem;
}
#game-view .liga-heute-karte .action { flex: none; margin: 0; min-height: 36px; padding: 6px 16px; }
/* Mehrere Aufgaben am Tag (1 bis 3, beim Gruenden gewaehlt): untereinander,
   jede mit ihrer Nummer vorn. */
#game-view .liga-heute-liste { display: flex; flex-direction: column; gap: 6px; margin-bottom: 4px; }
#game-view .liga-heute-liste .liga-heute-karte { margin-bottom: 0; }
#game-view .liga-heute-nr {
  font-size: 0.72rem; font-weight: 800; color: var(--muted);
  font-variant-numeric: tabular-nums; min-width: 24px;
}

/* Sportarten der Liga, nur als Anzeige (keine Checkbox, kein Klick) — die
   gleiche Chip-Optik wie beim Gruenden, damit eine Auswahl auch spaeter so
   aussieht, wie sie getroffen wurde. */
#game-view .liga-sportarten-liste--anzeige .liga-sportart-chip {
  cursor: default; background: var(--panel);
}

/* Die Form: drei Zeichen, aelteste links. Sie stehen nebeneinander und nicht
   als Text, weil man eine Reihe erkennt, bevor man sie liest. */
#game-view .liga-form { display: flex; gap: 3px; justify-content: flex-start; }
#game-view .liga-form__x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; border-radius: 5px;
  font-style: normal; font-size: 0.7rem; font-weight: 800; line-height: 1;
}
#game-view .liga-form--s { background: rgba(var(--marke-rgb), 0.18); color: var(--violet-text); }
#game-view .liga-form--n { background: rgba(255, 77, 109, 0.16); color: var(--rot-text); }
#game-view .liga-form--u { background: var(--line); color: var(--muted); }
#game-view .liga-form--leer { color: var(--muted); opacity: 0.5; }

#game-view .liga-zeilenaktion { display: flex; justify-content: flex-end; min-width: 0; }
#game-view .liga-zeilenaktion .fr-mini {
  /* Der Knopf darf in seine 88 px hineinschrumpfen, statt die Spalte zu
     sprengen — die Spaltenbreite ist hier die Zusage, nicht der Knopf. */
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#game-view .liga-du { font-size: 0.72rem; color: var(--muted); }

/* DIE LAUFENDE FRIST.

   Ziffern mit fester Breite, sonst zappelt die Zeile im Sekundentakt: In
   einer Proportionalschrift ist die 1 schmaler als die 8, und "6:12:45"
   waere bei jedem Tick ein paar Pixel breiter oder schmaler. Genau das
   Wackeln, das man an anderer Stelle in dieser Datei gemeldet bekommt. */
#game-view .liga-frist, .fr-frist {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
#game-view .liga-frist.ist-knapp, .fr-frist.ist-knapp { color: var(--present, #E9A23B); font-weight: 700; }
#game-view .liga-frist.ist-aus, .fr-frist.ist-aus { color: var(--rot-text); }
#game-view .liga-zahl {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px; margin-left: 6px;
  border-radius: 999px; background: var(--violet); color: var(--on-solid);
  font-size: 0.7rem; font-weight: 800;
}

/* Das Duell, auf das man wartet, steht kleiner als das, das man spielen
   soll — sonst waeren beide gleich laut, und die Seite fuehrt gerade mit
   dem Unterschied. */
#game-view .liga-dran { margin-bottom: 8px; }
#game-view .liga-duell--gross { padding: 14px 14px; }
#game-view .liga-duell--gross .liga-duell-gegner { font-size: 1rem; font-weight: 800; }

/* Das Forderformular unter der Tabellenzeile — dieselbe Bewegung wie in der
   Freundesliste. */
#game-view .liga-fordern-form {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px;
  padding: 12px; margin: 2px 0 4px;
  background: var(--panel); border: 1px dashed var(--line); border-radius: 12px;
}
#game-view .liga-fordern-form .cp-filter { margin: 0; }
#game-view .liga-fehler { color: var(--rot-text); font-size: 0.85rem; margin: 0; flex: 1 0 100%; }

/* Auf dem Telefon ist fuer sechs Spalten kein Platz. Der Knopf rutscht unter
   die Zeile, statt Name und Form gegeneinander zu druecken. */
@media (max-width: 559px) {
  /* Die Duellzeile hat fuenf Spalten; bei 375 px passen sie nicht
     nebeneinander, und das Raster verteilte sie auf vier Zeilen. Zwei
     genuegen: oben wer und was, unten der Stand und der Knopf. */
  #game-view .liga-duell {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 6px;
  }
  #game-view .liga-duell-modus { grid-column: 2; text-align: right; }
  #game-view .liga-duell-stand { grid-column: 1; }
  #game-view .liga-duell-status { grid-column: 2; text-align: right; }
  #game-view .liga-duell-aktionen { grid-column: 1 / -1; justify-self: stretch; }
  #game-view .liga-duell-aktionen .action,
  #game-view .liga-duell-aktionen .secondary { flex: 1 1 0; }

  /* Sechs Spalten passen bei 375 px oben noch nebeneinander — knapp, aber
     "Sp" ist eine schmale Kachel und braucht nicht mehr als ihr Ziffernwert.
     Form und der Knopf rutschen weiter unter die Zeile. */
  #game-view .liga-tabelle--form .liga-zeile {
    grid-template-columns: 24px minmax(0, 1fr) 36px 28px 22px;
    row-gap: 8px;
    gap: 6px;
  }
  #game-view .liga-tabelle--form .liga-form { grid-column: 2 / -1; }
  #game-view .liga-zeilenaktion { grid-column: 1 / -1; justify-content: flex-start; }
  #game-view .liga-tabelle--form .liga-kopfzeile span:nth-child(6),
  #game-view .liga-tabelle--form .liga-kopfzeile span:nth-child(7) { display: none; }
}

/* ---- Die Kulisse hinter dem Liga-Einstieg -------------------------------

   DREI SCHICHTEN, und jede hat genau eine Aufgabe:

     ::before   das Foto, verwischt
     ::after    der Schleier, der es in den Grund zurueckdraengt
     __svg      die gezeichnete Menge davor

   Warum getrennt und nicht ein `filter` auf dem Ganzen: Ein Filter auf dem
   Elternteil erfasst auch den Schleier und die Menge, und an den Kanten
   entstuende ein Unschaerfesaum. Jede Schicht traegt ihr eigenes.

   DAS FOTO IST DAS HERO-BILD der Startseite — eine Datei, die das Projekt
   ohnehin ausliefert und die geklaert ist. Die Vorlage aus der Bildersuche
   war ein Getty-Foto mit Wasserzeichen; Presse- und Agenturbilder sind hier
   ausgeschlossen, siehe die Datenregeln. --hero-bild entscheidet, welche
   Fassung gilt: Abend im dunklen Thema, Morgen im hellen. */
#game-view .liga-view--start {
  position: relative;
  z-index: 0;
  min-height: min(62vh, 520px);
}
#game-view .liga-view--start > *:not(.liga-kulisse) { position: relative; z-index: 1; }

#game-view .liga-kulisse {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  z-index: 0;
  pointer-events: none;
  color: var(--violet-text);

  /* KEINE KANTEN. Gemeldet: "Das schaut aus wie ein Foto mit klaren Kanten,
     das soll fliessend sein."

     Genau das war es: `inset: 0` mit `overflow: hidden` ergibt ein Rechteck,
     und das Bild hoerte an allen vier Seiten schlagartig auf — unten mitten
     durch die Menge, seitlich an der Kante des Einstiegs. Der Schleier half
     nicht, denn der daempft die HELLIGKEIT; die Kante ist eine Frage der
     FORM.

     Zwei Masken, uebereinandergelegt und verschnitten: eine senkrecht, eine
     waagerecht. Wo eine von beiden durchsichtig ist, ist es das Ganze — so
     laeuft das Bild an allen vier Raendern aus, statt zu enden.

     Unten wird laenger ausgeblendet als oben (72 % bis 100 % gegen 0 % bis
     28 %): Dort steht die Menge, und ein hart abgeschnittener Fuss faellt
     mehr auf als ein weich beginnender Himmel.

     mask-composite: intersect ist die Norm, -webkit-mask-composite:
     source-in die aeltere Schreibweise fuer WebKit. Beide stehen da, weil
     Safari lange nur die zweite kannte; fehlt beides, liegt einfach die
     erste Maske an, und das ist immer noch weicher als vorher. */
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0%, #000 26%, #000 68%, transparent 100%),
    linear-gradient(to right, transparent 0%, #000 13%, #000 87%, transparent 100%);
          mask-image:
    linear-gradient(to bottom, transparent 0%, #000 26%, #000 68%, transparent 100%),
    linear-gradient(to right, transparent 0%, #000 13%, #000 87%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}

/* Das Foto. `inset: -12px` plus Unschaerfe: Ein verwischtes Bild wird an
   seinen Raendern durchsichtig, und ohne den Ueberstand saehe man rundum
   einen hellen Saum. */
#game-view .liga-kulisse::before {
  content: "";
  position: absolute;
  inset: -12px;
  background-image: var(--hero-bild, url('assets/hero-bg.jpg'));
  background-size: cover;
  /* Unten im Bild, wo Stadion und Rasen stehen — oben ist Himmel, und dort
     steht die Ueberschrift. */
  background-position: center 72%;
  filter: blur(3px);
}

/* Der Schleier. Er ist der Grund, warum das Foto nichts schlechter lesbar
   macht: Bei 0.93 Deckung bleibt vom Bild ein Zwanzigstel uebrig — genug,
   dass man ein Stadion ahnt, zu wenig, um irgendetwas zu stoeren. Die Werte
   sind unten gegen die hellste und dunkelste Stelle des Fotos nachgerechnet,
   nicht geschaetzt. */
#game-view .liga-kulisse::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(15, 22, 19, 0.955) 0%,
    rgba(15, 22, 19, 0.94) 55%,
    rgba(15, 22, 19, 0.925) 100%);
}

/* Die gezeichnete Menge liegt VOR dem Foto — der Vordergrund, so wie in der
   Vorlage die Leute auf der Tribuene. */
#game-view .liga-kulisse__svg {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  /* z-index, weil ::after NACH allen Kindern gezeichnet wird: Ohne die Zeile
     liegt der Schleier ueber der Menge und sie ist schlicht weg. Genau so
     war es im ersten Entwurf — unsichtbar, und die Deckung war unschuldig. */
  z-index: 1;
  display: block; width: 100%; height: 220px;
  opacity: 0.075;
  filter: blur(1.2px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, rgba(0,0,0,0.55) 45%, #000 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, rgba(0,0,0,0.55) 45%, #000 100%);
}

/* Helles Thema: derselbe Aufbau, Schleier in Papierfarbe. */
:root[data-theme='light'] #game-view .liga-kulisse::after {
  background: linear-gradient(to bottom,
    rgba(243, 239, 230, 0.955) 0%,
    rgba(243, 239, 230, 0.94) 55%,
    rgba(243, 239, 230, 0.925) 100%);
}
:root[data-theme='light'] #game-view .liga-kulisse__svg { opacity: 0.12; }

/* ---- Die drei Kacheln des Startbildschirms -------------------------------

   Sie waren Pillen in einer Reihe — richtig als Filter, zu leise als
   Einstieg. Das hier ist der erste Bildschirm der Liga und hat genau eine
   Aufgabe: die drei Wege zeigen. Also Groesse, Symbol und eine Zeile
   darunter.

   DREI SPALTEN AB 620 px, darunter eine. Der Umbruch liegt dort, weil die
   laengste Beschriftung ("Du brauchst den 6-Zeichen-Code") bei schmaleren
   Spalten auf drei Zeilen geht und die Kacheln dann verschieden hoch
   werden. `align-items: stretch` haelt sie gleich hoch, solange sie
   nebeneinander stehen.

   KEIN SCHWEBERUCK wie bei den Katalogkacheln — die Regel dafuer ist unter
   #game-view ohnehin abgeschaltet (siehe oben, das Wackeln in Abseits). Was
   die Kachel beim Ueberfahren tut, sagt hier der Rahmen. */
#game-view .liga-reiter {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  margin: 4px 0 14px;
}
@media (min-width: 620px) {
  #game-view .liga-reiter { grid-template-columns: repeat(3, 1fr); align-items: stretch; }
}

#game-view .liga-kachel {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  padding: 16px 16px 15px;
  border-radius: 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--muted);
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color 0.14s ease, background 0.14s ease, color 0.14s ease;
}
#game-view .liga-kachel:hover { border-color: var(--muted); color: var(--text); }

/* Der gewaehlte Weg. Der Lime-Ton als FLAECHE, nicht --card: In diesem Thema
   ist --card dunkler als --panel, ein aktiver Zustand damit waere ein Loch
   statt einer Hervorhebung. Steht als Regel im Projekt-Handbuch. */
#game-view .liga-kachel.is-on {
  background: rgba(var(--marke-rgb), 0.14);
  border-color: var(--violet-text);
  color: var(--text);
}

#game-view .liga-kachel__symbol {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; margin-bottom: 2px;
  border-radius: 12px;
  background: var(--card);
  color: var(--muted);
  transition: color 0.14s ease, background 0.14s ease;
}
#game-view .liga-kachel__symbol svg { width: 21px; height: 21px; }
#game-view .liga-kachel.is-on .liga-kachel__symbol {
  background: rgba(var(--marke-rgb), 0.18); color: var(--violet-text);
}

#game-view .liga-kachel__titel {
  display: flex; align-items: center; gap: 7px;
  font-size: 1.02rem; font-weight: 800; color: var(--ink);
  letter-spacing: -0.01em;
}
#game-view .liga-kachel__text { font-size: 0.8rem; line-height: 1.35; }

#game-view .liga-reiter__tafel {
  display: flex; flex-direction: column; gap: 12px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 16px;
}
#game-view .liga-reiter__tafel .cp-filter { margin: 0; }

/* ---- Die Unterseite je Kachel (27.09.2026) --------------------------------
   Aktive Ligen, Gruenden und Beitreten klappen nicht mehr unter den Kacheln
   auf, sondern stehen als eigene Seite — mit dem Weg zurueck oben links, der
   Kopf der Liga tritt dort zurueck (er steht im Zurueck-Knopf). Die Kachel
   bekommt dafuer einen Pfeil: Sie fuehrt jetzt irgendwohin, statt etwas
   aufzuklappen. */
#game-view .liga-kachel { position: relative; padding-right: 36px; }
#game-view .liga-kachel__pfeil {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  font-size: 1.5rem; line-height: 1; color: var(--muted);
}
#game-view .liga-view--unterseite .liga-kopf { display: none; }
#game-view .liga-unterseite { display: flex; flex-direction: column; gap: 6px; }
#game-view .liga-zurueck {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 6px 14px 6px 10px; margin-bottom: 6px;
  border-radius: var(--radius-full, 999px);
  background: var(--panel); border: 1px solid var(--line);
  color: var(--text); font: inherit; font-size: 0.88rem; font-weight: 700; cursor: pointer;
}
#game-view .liga-zurueck span { font-size: 1.3rem; line-height: 1; }
#game-view .liga-unterseite__titel {
  margin: 0; font-size: 1.45rem; font-weight: 800; letter-spacing: -0.02em; color: var(--ink);
}
#game-view .liga-unterseite__text { margin: 0 0 8px; font-size: 0.86rem; color: var(--muted); }

/* Der Sammelknopf sitzt rechts in der Abschnittsueberschrift, wo sonst die
   Restzeit der Saison steht — beides sind Angaben zur Tabelle als Ganzes,
   nicht zu einer Zeile. `margin-left: auto` schiebt ihn ans Ende, damit er
   nicht mit der Ueberschrift verschmilzt. */
#game-view .liga-alle-fordern { margin-left: auto; }
/* Der Satz "alle bekommen dieselbe Aufgabe" gehoert unter die Knoepfe des
   Formulars und nicht daneben — er erklaert, was der Klick tut. */
#game-view .lf-hinweis { flex-basis: 100%; margin: 2px 0 0; }

/* Duelle oder Tages-Liga, beim Gruenden. Dieselbe Reihe wie die
   Schwierigkeitswahl — die Knoepfe sind buchstaeblich .grad-btn. */
#game-view .liga-modus { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* Die Sportarten-Auswahl einer Tages-Liga: ein Raster kleiner Chips statt
   einer langen Liste, damit neun Sportarten nicht neun volle Zeilen kosten. */
#game-view .liga-sportarten {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px; border: 1px dashed var(--line); border-radius: 12px;
}
#game-view .liga-sportarten-liste { display: flex; flex-wrap: wrap; gap: 8px; }
#game-view .liga-sportart-chip {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line);
  font-size: 0.86rem; cursor: pointer; user-select: none;
}
#game-view .liga-sportart-chip:has(:checked) {
  border-color: var(--violet); background: rgba(var(--violet-rgb), 0.14);
}
/* :has() fehlt in manchen Browsern noch — die Markierung faellt dann weg,
   die Checkbox bleibt trotzdem bedienbar und sichtbar. Kein zweiter Weg
   noetig, nur ein kleinerer Gewinn dort, wo :has() fehlt. */
#game-view .liga-sportart-check { accent-color: var(--violet); }

/* Vergangene Saisons — klein und am Ende. Sie beantworten keine Frage, die
   man beim Oeffnen hat; sie sind das, was bleibt. */
#game-view .liga-saisons { display: flex; flex-direction: column; gap: 4px; }
#game-view .liga-saison-zeile {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: 8px 12px;
}
#game-view .liga-saison-zeile summary {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  cursor: pointer; font-size: 0.86rem;
}
#game-view .liga-saison-name { font-weight: 700; }
#game-view .liga-saison-datum { font-size: 0.74rem; color: var(--muted); white-space: nowrap; }
#game-view .liga-saison-tabelle { margin-top: 8px; border-top: 1px solid var(--line); padding-top: 8px; }
#game-view .liga-saison-platz {
  display: grid; grid-template-columns: 26px minmax(0, 1fr) 44px;
  gap: 8px; padding: 3px 0; font-size: 0.82rem;
}
#game-view .liga-saison-platz span:first-child { color: var(--muted); font-weight: 800; text-align: center; }
#game-view .liga-saison-platz span:nth-child(3) { text-align: right; font-weight: 700; color: var(--violet-text); }

/* Der Verlauf gespielter Liga-Duelle, zugeklappt. Eigener Marker statt des
   Browserdreiecks: Das sitzt links und ruecht die Ueberschrift ein, sie soll
   aber buendig unter der Tabelle stehen. Gleiche Bauart wie .fr-verlauf. */
#game-view .liga-verlauf > summary {
  cursor: pointer; list-style: none; user-select: none;
  /* .liga-abschnitt-titel ist KEIN Flex-Container — ohne diese Zeile schoebe
     margin-left:auto am Marker nichts nach rechts, er klebte am Wort. */
  display: flex; align-items: center; gap: 8px;
}
#game-view .liga-verlauf > summary::-webkit-details-marker { display: none; }
#game-view .liga-verlauf > summary::after {
  content: "▾"; margin-left: auto; font-size: 0.9rem; line-height: 1;
  transition: transform 0.15s ease;
}
#game-view .liga-verlauf[open] > summary::after { transform: rotate(180deg); }


/* ==========================================================================
   DIE STARTSEITE AUF DEM TELEFON — Entwurf C (14. September 2026)

   Gemeldet: "Die Startseite gefällt mir noch gar nicht, das ist alles viel zu
   groß und unübersichtlich, das muss minimalistischer werden." Gemessen bei
   375 x 812: 2201 px, also 2,7 Bildschirme.

   Gewaehlt wurde Entwurf C — nur das Noetige, der Rest hinter "Mehr".

   NUR AUF DEM TELEFON. Ab 900 px gibt es die untere Leiste nicht, und dort
   ist die Startseite eine lange Seite, die auch so gedacht ist.

   DIE DREI NAVIGATIONSKACHELN FALLEN GANZ WEG, nicht hinter "Mehr" — und das
   ist der Fund, der diesen Umbau erst billig macht: "Dein Profil", "Alle
   Spiele" und "Liga" fuehren an genau die drei Orte, die die untere Leiste
   schon hat (Start · Spiele · Liga · Profil). Sie waren also nie eine
   Abkuerzung, sondern eine zweite Tastatur fuer dieselben Tasten. Was man
   doppelt anbietet, muss man nicht wegklappen; man kann es weglassen.

   Uebrig bleibt oben, was die Startseite eigentlich ist: die Begruessung, der
   Countdown und die Challenges des Tages samt Serie.

   HINTER "MEHR" liegt, was zusaetzlich da ist und nicht jeden Tag gebraucht
   wird: die zwei Erklaerkacheln und "Meistgespielt". Beides ist Auskunft,
   keine Aufgabe.

   Der Schalter haengt an einer Klasse auf <body>, nicht an einem <details>:
   Die Bloecke sind eigene <section>-Elemente auf oberster Ebene, und sie in
   ein Aufklappelement zu verschieben hiesse, das DOM umzubauen — mit allem,
   was daran haengt (zeigeBereich, data-reveal, die Beobachter). Eine Klasse
   kostet nichts und laesst die Struktur, wie sie ist. */
@media (max-width: 899px) {
  /* Die Doppelungen der unteren Leiste. */
  .hub__tile--profil,
  .hub__tile--nav { display: none; }

  /* UND DER COUNTDOWN STAND ZWEIMAL DA. Die Hub-Kachel zeigt ihn gross auf
     dem Stadionbild, und der Kopf von "Heute" sagte "Neu in 05:49:39"
     gleich darunter noch einmal — dazu eine Ueberschrift und eine Zeile,
     die beide erklaeren, was die Kachel darueber schon erklaert hat.

     Auf dem Telefon faellt der Kopf deshalb weg. Was bleibt, sind die zwei
     Challenge-Kacheln und der eigene Stand — und die brauchen keine
     Ueberschrift, weil ueber ihnen die Kachel steht, die sie ankuendigt. */
  #heute .sectionhead { display: none; }

  /* Hier stand, was hinter "Mehr" wartete (Erklaerkacheln und
     "Meistgespielt"). Seit dem 27.09.2026 gibt es die Kacheln nicht mehr und
     "Meistgespielt" steht immer da; die Klassen unten bleiben fuer den
     gleichnamigen Schalter im Profil. */

  .mehr-schalter {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; margin: 0 auto;
    padding: 13px 18px;
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    color: var(--color-fg-muted);
    font: inherit; font-size: 0.88rem; font-weight: 700;
    cursor: pointer;
  }
  .mehr-huelle { margin-block: calc(var(--space-section) / 4); }
  .mehr-schalter__pfeil { transition: transform var(--dur-fast) var(--ease-out); }
  body.mehr-offen .mehr-schalter__pfeil { transform: rotate(180deg); }
}

/* ==========================================================================
   DIE STARTSEITE EINER SPORTART AUF DEM TELEFON — ein Bildschirm
   (27. September 2026, Ansage des Eigentuemers)

   "Bei Start soll man alles sehen koennen ohne zu scrollen: von oben bis
   ausschliesslich Meistgespielt diese Woche." Gemessen bei 375 x 812 vorher:
   Buehne 77–621, "Heute" bis 1126 — die Tableiste beginnt bei 748. Nichts
   davon ist weggefallen; alles ist kleiner, in denselben Proportionen.

   Darunter "Meistgespielt" als EINE Reihe aus drei kleinen Kacheln statt
   2 + 1 mit einer grossen dritten.

   NUR BIS 560 px — ein Telefon. Ein Tablet hat die Hoehe fuer die grosse
   Fassung und bekaeme hier Briefmarken. */
@media (max-width: 560px) {
  /* ---- Buehne: nur noch die Begruessungszeile ----------------------------
     ZWEITER DURCHGANG (28.09.2026): "immer noch zu unuebersichtlich". Die
     grosse Tages-Kachel mit Countdown und die Einladung "Fang mit einer Runde
     an" sagten dasselbe wie die zwei Challenge-Kacheln darunter — nur
     groesser. Am Telefon fallen sie weg; der Countdown steht im Kopf von
     "Heute", und die Challenges sind selbst die Einladung. Uebrig bleibt
     oben die Begruessung mit dem Sport-Chip. */
  /* GEWACHSEN AUF RUND 30 % DES BILDSCHIRMS (30.09.2026, Ansage des
     Eigentuemers) — der Platz kommt von "Meistgespielt", das als
     durchlaufendes Band ohne Bilder jetzt viel weniger Hoehe braucht (siehe
     dort). `.stage` traegt kein eigenes sichtbares Element hier ausser der
     Begruessungszeile; der Rest dieses Abstands ist Foto, kein Leerraum,
     denn .stage__bg fuellt die ganze Box als Hintergrund (siehe dort).
     Gemessen bei 375 x 812: vorher 123 px (15 %) bis zur harten Kante,
     jetzt 247 px (30 %) — von y = 0 aus gerechnet, denn das Bild reicht
     hinter die transparente Kopfleiste bis ganz nach oben.

     NICHT `.stage { padding-bottom: … }` ALLEIN — das verlor gegen
     `:is(.section, .stage):has(+ .marquee) { padding-block-end: … }`
     aus rivalz-layout.css (zwei Klassen-Stufen gegen eine, Spezifitaet
     schlaegt Dateireihenfolge). Im Browser gemessen statt am Selektor
     abgelesen: computed padding-bottom blieb bei 10 px, egal welcher Wert
     hier stand. Dieselbe Selektorform gewinnt durch die spaetere Datei. */
  /* 210 statt 130 (02.10.2026 nachts, wie in der App: der Block darunter
     rueckt 80 px tiefer, das Stadion steht freier). */
  .stage { padding-bottom: 210px; }
  :is(.section, .stage):has(+ .marquee) { padding-block-end: 210px; }
  .hub { padding-top: 4px; padding-bottom: 0; gap: 0; }
  .hub__greet { font-size: 0.98rem; gap: 0.5rem; }
  .hub__mark { width: 24px; height: 24px; }
  .hub__mark::after { width: 11px; height: 11px; }
  .sportchip { min-height: 32px; font-size: 0.8rem; padding: 0.2em 0.75em 0.2em 0.55em; }
  .hub__body { display: none; }

  /* ---- Serie: eigene Zeile VOR "Tages-Challenge" (30.09.2026, vierter
     Durchgang, Ansage des Eigentuemers) -------------------------------------
     Stand bis dahin als vierte Kachel IM Raster, nach den zwei
     Spielkacheln. Jetzt der erste Block auf der Seite unter der Buehne —
     das, was man verlieren kann, ist das Erste, was man sieht. Derselbe
     Bauplan wie vorher (.today__stats), nur nicht mehr in einem Grid-Feld,
     sondern allein in seiner eigenen Zeile. */
  #heuteStreakSlot { display: block; padding-inline: var(--gutter); margin: 14px 0 12px; }
  #heuteStreakSlot:empty { display: none; }
  #heuteStreakSlot li { list-style: none; }

  /* ---- Heute: zwei Kacheln, nicht drei (30.09.2026) -----------------------
     Die dritte Kachel (Stadionbild + Countdown) ist weg — die Restzeit steht
     jetzt im Kopf, neben dem Titel, genau wie am Rechner (#today-timer, dort
     bisher ausgeblendet). Kopf ist deshalb wieder eine Zeile statt
     gestapelt: Titel/Unterzeile links, Uhr rechts. */
  #heute.section { padding-top: 10px; padding-bottom: 0; }
  #heute .sectionhead {
    display: flex; align-items: baseline; justify-content: space-between;
    flex-wrap: wrap; column-gap: 10px; margin-bottom: 8px;
  }
  #heute .sectionhead__title { font-size: 1.05rem; }
  /* Der Satz unter "Tages-Challenge" ist am Telefon weg (02.10.2026, Wunsch
     des Eigentuemers) — der Titel und "Neu in" sagen es. */
  #heute .sectionhead__sub { display: none; }
  #heute .today__timer { display: block; font-size: 0.74rem; white-space: nowrap; }
  .today__grid, .today__grid--solo { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 0; gap: 8px; }
  /* Hebt die 720-px-Regel auf (".today__grid .today__cell:last-child" weiter
     oben in der Datei) — die galt einer dritten Kachel, die voller Breite
     unter den zwei Spielen lag. Seit die Serie den Slot vor der Sektion
     bekommen hat, ist die LETZTE Kachel wieder ein ganz normales Spiel und
     darf nicht mehr die ganze Zeile fuer sich nehmen. */
  .today__grid .today__cell:last-child { grid-column: auto; }
  /* Quadratisch statt 3 : 4 — die zwei Kacheln ein Viertel niedriger
     (02.10.2026, wie in der App). */
  .today__card { min-height: 0; aspect-ratio: 1 / 1; border-radius: var(--radius-md); }
  .today__cardTop { padding: 6px 6px 0; }
  .today__cardBody { padding: 7px; gap: 2px; }
  .today__cardName { font-size: 0.8rem; line-height: 1.15; text-shadow: 0 1px 12px rgba(0, 0, 0, 0.5); }
  .today__cta {
    margin-top: 0; padding: 0; background: none; color: rgba(255, 255, 255, 0.82);
    font-size: 0.6rem; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase;
  }
  .today__badge { font-size: 0.5rem; padding: 3px 6px; gap: 3px; }
  .today__badge svg { width: 10px; height: 10px; }

  /* DIE UEBERSCHRIFT WAR BLASS, und nicht wegen ihrer Farbe (gemessen: dieselbe
     wie bei "Meistgespielt"). Die Buehne ist positioniert, und ihr Bild reicht
     110 px ueber die eigene Kante hinaus (siehe "The seam under the stage");
     ein nicht positionierter Abschnitt danach wird VOR positionierten
     Elementen gemalt, der Bildverlauf lag also als Schleier ueber dem Kopf
     von "Tages-Challenge". Eine eigene Ebene holt ihn nach vorn. Gilt jetzt
     fuer den Slot der Serie, denn der steht als Erstes unter der Buehne. */
  #heuteStreakSlot, #heute { position: relative; z-index: 1; }

  /* DER STAND, SCHMAL UND IN DERSELBEN FARBE WIE DIE KACHELN (28.09.2026,
     Zeilenform unveraendert seit dem vierten Durchgang). Eine Zeile: links
     die Serie, rechts die Woche und der Tagesfortschritt. Nicht mehr die
     graue Flaeche der Seite, sondern das dunkle Glas, auf dem auch die
     Bildkacheln darueber und darunter liegen. Die Quote faellt weg — sie
     steht im Profil unter "Statistik". */
  .today__stats {
    display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center;
    column-gap: 14px; row-gap: 6px;
    padding: 7px 10px; border-radius: var(--radius-md);
    background: rgba(15, 22, 19, 0.62);
    -webkit-backdrop-filter: blur(12px) saturate(1.3); backdrop-filter: blur(12px) saturate(1.3);
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: none;
    color: #EEF3F0;
    --color-fg: #EEF3F0; --color-fg-muted: #A7B3AC; --color-border: rgba(255, 255, 255, 0.16);
    --color-surface: transparent; --color-bg-inset: rgba(255, 255, 255, 0.06);
  }
  .today__statsHead, .today__statLine, .today__streakLabel { display: none; }
  .today__streak { grid-column: 1; grid-row: 1 / span 2; column-gap: 5px; row-gap: 0; }
  .today__streak .today__streakKurz {
    display: block; grid-column: 1 / -1; font-size: 0.54rem; font-weight: 800;
    letter-spacing: 0.06em; text-transform: uppercase; color: #A7B3AC; white-space: nowrap;
  }
  .today__streakBig { font-size: 1.35rem; }
  .today__streakFlame { font-size: 1rem; }
  .today__stats > .today__week, .today__stats > .today__progress { grid-column: 2; }
  .today__week { gap: 4px; }
  .today__weekDot { height: 5px; }
  .today__progress { margin-top: 0; padding: 0; gap: 4px; border: 0; background: none; }
  .today__progressText { font-size: 0.6rem; }
  .today__progressTrack { height: 4px; }

  /* Die Katalogkachel: auf zwei schmalen Spalten braucht das Bild ein
     hoeheres Format, um auf ~65 % der Kachel zu kommen (gemessen 0,64). */
  .card__cover { aspect-ratio: 8 / 5; }

  /* ---- Meistgespielt: ein durchlaufendes Band, wie das Wortband am Rechner
     (30.09.2026, fuenfter Durchgang, Ansage des Eigentuemers: "automatisch
     als Banner durchlaeuft, so wie das mit den Schlagwoertern bei der
     Desktop-Version"). War erst ein Raster aus drei Hochformat-Kacheln
     (144 px), dann eine wischbare Reihe liegender Karten mit Bild (52 px) —
     jetzt eine einzige Zeile je Spiel, ohne Bild, und das Band laeuft von
     selbst. Das macht es kuerzer als je zuvor, und genau dieser Platz geht
     an die Buehne oben (siehe dort, .stage).

     DIESELBE ANIMATION WIE DAS WORTBAND: @keyframes marquee aus
     rivalz-layout.css, translate3d(-50%,0,0) — das funktioniert fuer jeden
     Inhalt, der zweimal hintereinander steht, nicht nur fuer Schlagwoerter.
     Eine zweite, eigene Keyframe-Regel waere die Art Verdoppelung, die beim
     naechsten Tempo-Wechsel nur eine Stelle findet. renderPodium() zeichnet
     den Inhalt am Telefon zweimal (siehe app.js); hier steht nur, wie er
     aussieht und laeuft. */
  #top3.section { padding-top: 14px; padding-bottom: 2px; }
  #top3 .sectionhead { margin-bottom: 6px; }
  /* Kleiner als "Tages-Challenge" (02.10.2026): ein Nebenabschnitt. */
  #top3 .sectionhead__title { font-size: 0.9rem; }
  #top3 .sectionhead__sub { display: none; }
  .podiumgrid {
    display: flex; grid-template-columns: none; gap: 0; margin-top: 0;
    width: max-content;
    animation: marquee 22s linear infinite;
  }
  /* Der Rahmen liegt um .podiumband, nicht um .container — sonst staeke die
     Ueberschrift mit in derselben Box wie die laufende Zeile. Dieselbe
     Kulisse wie .marquee: ausgeblendete Kanten statt eines harten Schnitts,
     eine eigene Flaeche statt der nackten Seite darunter. overflow:hidden
     sitzt hier und nicht an .podiumgrid selbst, denn die ist durch
     `width: max-content` absichtlich breiter als der Bildschirm — das
     Abschneiden muss am unbeweglichen Rahmen passieren, nicht am Inhalt,
     der sich durch ihn hindurch bewegt. */
  .podiumband {
    overflow: hidden; padding-block: 6px;
    border-block: 1px solid var(--color-border);
    background: var(--color-bg-subtle);
    mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  }
  @media (prefers-reduced-motion: reduce) {
    .podiumgrid { animation: none; }
  }
  .podium--zeile { flex: 0 0 auto; }
  .podium--zeile .podium__card {
    display: flex; align-items: center; gap: 8px; height: 36px;
    padding-inline: 14px; white-space: nowrap;
  }
  /* Die grosse Umrissziffer war fuers Poster gedacht (Fuellung transparent,
     nur ein weisser Rand, AUF einer Fotoflaeche lesbar). In der Zeile ist
     ein Umriss ohne Fuellung bei dieser Groesse keine Zahl mehr, sondern
     ein Haarstrich — deshalb hier eine echte Fuellfarbe, dieselbe wie beim
     Rang im Wortband nebenan (--color-primary-text). */
  .podium--zeile .podium__rank {
    position: static; flex: 0 0 auto;
    font-family: var(--font-display); font-size: 0.85rem; font-weight: 900;
    font-style: italic; -webkit-text-stroke: 0; color: var(--color-primary-text);
    filter: none;
  }
  .podium--zeile .podium__cover { display: none; }
  .podium--zeile .podium__body {
    position: static; display: flex; align-items: baseline; gap: 6px;
  }
  .podium--zeile .podium__title {
    font-size: 0.82rem; font-weight: 800; line-height: 1; text-shadow: none;
    color: var(--color-fg);
  }
  .podium--zeile .podium__meta {
    font-size: 0.68rem; margin-top: 0; letter-spacing: 0.01em; color: var(--color-fg-muted);
  }
}

/* Die Kurzbeschriftung der Serie gibt es nur im schmalen Stand am Telefon —
   am Rechner steht der ganze Satz (.today__streakLabel). */
.today__streakKurz { display: none; }

/* #heuteStreakSlot braucht KEINE eigene "display: none"-Grundregel: Am
   Rechner fuellt renderHeute() ihn nie, ein leerer <div> nimmt ohnehin
   keinen sichtbaren Platz ein. Eine unbedingte Regel HIER, nach der
   bedingten weiter oben im 560-px-Block, haette genau diese gewinnen lassen
   (gleiche Spezifitaet, spaeter in der Quelle) — geschehen und im Browser
   gefunden: der Slot blieb display:none, obwohl JavaScript ihn schon
   gefuellt hatte. */

/* Tablet-Breite: zwei breite Spalten und der kleine Kachelkoerper des
   Telefons — dort erreicht ein flaches Format die ~65 % (3/2 lag bei 0,78). */
@media (min-width: 561px) and (max-width: 899px) {
  .card__cover { aspect-ratio: 5 / 2; }
}

/* Ab der Breite, ab der es die untere Leiste gibt, ist der Schalter sinnlos —
   dort steht ohnehin alles. */
@media (min-width: 900px) {
  .mehr-huelle { display: none; }
}


/* ==========================================================================
   DAS PROFIL AUF DEM TELEFON — Entwurf C (14. September 2026)

   Gemessen bei 375 x 812, vor dem Umbau: 3165 px, also 3,9 Bildschirme.
   Davon Kennzahlen-Raster 532, Kalender 758, Modus-Werte 984.

   Entwurf C: Level, Serie und Raenge stehen oben; die Statistiken klappen
   auf. Nur auf dem Telefon — am Rechner ist die Seite eine Uebersicht, und
   dort ist Platz.

   Die Serie steht als eigene Zeile UEBER dem Schalter. Sie steckte als eine
   von sechs gleich grossen Kacheln im Raster und war damit so wichtig wie
   "XP gesamt"; sie ist aber das Einzige hier, das man verlieren kann, indem
   man nichts tut. */
#game-view .profil-serie { display: none; }
#game-view .profil-mehr-schalter { display: none; }

@media (max-width: 899px) {
  #game-view .profil-serie {
    display: flex; align-items: baseline; justify-content: center; gap: 9px;
    margin: 14px 0 4px;
  }
  #game-view .profil-serie__flamme { font-size: 1.1rem; }
  #game-view .profil-serie__zahl {
    font-size: 2.6rem; font-weight: 900; line-height: 1;
    color: var(--ink); font-variant-numeric: tabular-nums;
  }
  #game-view .profil-serie__label {
    font-size: 0.74rem; font-weight: 700; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--muted);
  }

  #game-view .profil-mehr-schalter {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; margin: 12px 0 2px; padding: 12px 18px;
    background: transparent;
    border: 1px solid var(--line); border-radius: 999px;
    color: var(--muted);
    font: inherit; font-size: 0.86rem; font-weight: 700; cursor: pointer;
  }
  #game-view .profile-view:not(.mehr-offen) .profil-mehr-block { display: none; }
  #game-view .profile-view.mehr-offen .profil-mehr-schalter .mehr-schalter__pfeil {
    transform: rotate(180deg);
  }
}


/* ==========================================================================
   DIE SPIELE AUF EINEN SCHIRM — Telefon (14. September 2026)

   Nach dem Schrumpfen des gemeinsamen Kopfes blieb der Ueberlauf im Inhalt
   der Spiele selbst. Gemessen bei 375 x 812, je Spiel einzeln.

   ---- Das Quiz: die Ligaleiter --------------------------------------------

   Gemessen: Frage samt Antworten 552 px, LEITER 351 px. Fuenfzehn Stufen
   untereinander sind am Rechner eine Spalte neben dem Spiel und auf dem
   Telefon eine Wand darunter.

   Was die Leiter beantwortet, sind drei Fragen: Wo stehe ich, was kommt als
   Naechstes, und wo ist das naechste Netz. Dafuer braucht es nicht alle
   fuenfzehn Zeilen — es braucht die aktuelle, ihre zwei Nachbarn und die
   Sicherheitsstufen. Genau die bleiben stehen.

   DIE LUECKEN SIND LESBAR, weil jede Zeile ihre Nummer traegt: Ein Sprung von
   15 auf 8 auf 5 liest sich als "das sind die sicheren", nicht als Fehler.
   Ohne die Nummern waere dieselbe Kuerzung eine Irrefuehrung.

   :has() fuer den Vorgaenger der aktuellen Stufe — den Nachfolger holt der
   Geschwisterwaehler. Fehlt :has(), fehlt eine Zeile; die Leiter bleibt
   benutzbar. */
/* Die Polsterung der Spielkarte. 28 px rundum sind am Rechner richtig; auf
   einem 375 px breiten Schirm sind allein die seitlichen 56 px ein Siebtel
   der Breite, und oben und unten noch einmal 56 px Hoehe. Das trifft JEDES
   Spiel, nicht nur die zwei dicksten. */
@media (max-width: 899px) {
  /* .card steht hier neben .game-card, weil Abseits als einziges Spiel seine
     Bildschirme aus der Katalogkachel-Klasse baut (siehe die Regel weiter
     oben, die ihr die Kachelbewegungen wegnimmt). Ohne diese Zeile war es
     das einzige Spiel, das von der Polsterung nichts hatte. */
  #game-view .game-card,
  #game-view #game-container > .card { padding: 16px; border-radius: 18px; }
}

@media (max-width: 899px) {
  #game-view .quiz-stufe { display: none; }
  #game-view .quiz-stufe.aktuell,
  #game-view .quiz-stufe.sicher,
  #game-view .quiz-stufe.aktuell + .quiz-stufe,
  #game-view .quiz-stufe:has(+ .quiz-stufe.aktuell) { display: flex; }
}

/* ==========================================================================
   DEMO-WERTE IN KOPF AN KOPF (16.09.2026) — cmpStatMarke() in app.js

   Ein Schild neben dem Namen der Statistik, wenn ihre Werte erfunden sind.
   Gold wie die Challenge-Marke, aber als Umriss: auffaellig genug, dass es
   niemand uebersieht, und kein zweites "Heute"-Abzeichen.
   ========================================================================== */
#game-view .cmp-demo {
  display: inline-block;
  margin-left: 6px;
  padding: 0 6px;
  border: 1px solid var(--color-accent-text);
  border-radius: 999px;
  color: var(--color-accent-text);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: middle;
}
#game-view .cmp-demo-hinweis,
#game-view .demo-band {
  margin: 0;
  padding: 10px 12px;
  border: 1px dashed var(--color-accent-text);
  border-radius: 12px;
  color: var(--text);
}

/* DER QUELLENNACHWEIS ist bewusst leiser als das Demo-Band darueber. Das
   Band warnt — gestrichelter Rahmen, Akzentfarbe —, der Nachweis nennt nur,
   woher die Zahlen kommen. Er erfuellt eine Lizenzbedingung (CC BY) und
   verlangt Lesbarkeit, keine Aufmerksamkeit. */
#game-view .quelle-band {
  margin: 0;
  font-size: 0.82rem;
  color: var(--muted);
}
#game-view .quelle-band a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
#game-view .quelle-band a:hover { color: var(--text); }

/* ==========================================================================
   DAS BUCHSTABENBRETT SCHRUMPFT BEI LANGEN NAMEN (16.09.2026)

   Die Felder waren fest 44 px breit. Beim Fussball (fuenf Buchstaben) sind das
   244 px und passen ueberall. Tennis erlaubt acht (394 px) und Formel 1 elf
   (550 px) — breiter als die Karte auf einem Telefon, und die Zeile lief
   seitlich heraus. Die Felder duerfen jetzt schrumpfen, bis 44 px bleibt die
   Obergrenze: Fussball sieht aus wie vorher.
   ========================================================================== */
#game-view .wordle-row .wordle-cell {
  flex: 1 1 0;
  min-width: 0;
  max-width: 44px;
  width: auto;
  height: auto;
  aspect-ratio: 1 / 1;
  font-size: clamp(0.72rem, 3.6vw, 1.1rem);
}

/* ==========================================================================
   CHECKOUT (Darts, 16.09.2026) — renderCheckout() in app.js

   Das Pad ist fuenf Spalten breit: 1–20 in vier Reihen, darunter 25/Bull.
   Die Knoepfe sind mindestens 44 px hoch — es wird getippt, nicht gezielt.
   ========================================================================== */
#game-view .checkout-stand { margin: 0; color: var(--muted); font-size: 0.9rem; }
#game-view .checkout-ziel { display: flex; align-items: baseline; gap: 12px; margin: 6px 0 2px; }
#game-view .checkout-ziel__zahl { font-size: 3.2rem; font-weight: 800; line-height: 1; color: var(--violet-text); font-variant-numeric: tabular-nums; }
#game-view .checkout-ziel__rest { color: var(--muted); font-variant-numeric: tabular-nums; }
#game-view .checkout-pfeile { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 10px 0; }
#game-view .checkout-pfeil {
  min-height: 44px; border-radius: 12px; border: 1px solid var(--line); background: var(--panel);
  color: var(--text); font-weight: 700; display: flex; align-items: center; justify-content: center; gap: 6px;
}
#game-view .checkout-pfeil span { color: var(--muted); font-weight: 400; }
#game-view .checkout-pfeil--leer { border-style: dashed; background: transparent; }
#game-view .checkout-faktor { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 8px 0; }
#game-view .checkout-faktor__knopf {
  min-height: 40px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--text); font-weight: 600;
}
#game-view .checkout-faktor__knopf.is-aktiv { background: var(--violet); border-color: var(--violet); color: var(--on-solid); }
#game-view .checkout-pad { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
#game-view .checkout-zahl {
  min-height: 44px; border-radius: 10px; border: 1px solid var(--line); background: var(--card);
  color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums;
}
#game-view .checkout-zahl:disabled, #game-view .checkout-faktor__knopf:disabled { opacity: 0.4; }
#game-view .checkout-zahl[data-zahl="25"] { grid-column: span 5; }
#game-view .checkout-aktionen { display: flex; gap: 12px; align-items: center; margin-top: 12px; flex-wrap: wrap; }
#game-view .checkout-ergebnis { display: flex; flex-direction: column; gap: 4px; }
#game-view .checkout-bilanz { display: grid; gap: 6px; margin: 10px 0; }
#game-view .checkout-bilanz__zeile {
  display: grid; grid-template-columns: 3.5rem 1fr auto; gap: 10px; align-items: center;
  padding: 8px 12px; border-radius: 10px; background: var(--panel);
}
#game-view .checkout-bilanz__zeile b { font-variant-numeric: tabular-nums; }
#game-view .checkout-bilanz__zeile em { font-style: normal; color: var(--muted); }
#game-view .checkout-bilanz__zeile.ist-richtig em { color: var(--correct-text, var(--violet-text)); font-weight: 700; }
#game-view .checkout-bilanz__summe { margin: 6px 0 0; font-weight: 700; }

/* Aufgaben-Spiele (17.09.2026): Spielstand, Scorekarte, Punktrichter,
   Boxenfunk, Spitzname. Stand, Ergebnis und Bilanz leihen sich die
   checkout-Klassen — dieselbe Leiste, keine zweite Beschreibung davon. */
#game-view .aufgabe { display: grid; gap: 10px; margin: 8px 0 12px; }
#game-view .aufgabe__titel { margin: 0; font-weight: 700; }
#game-view .aufgabe__gross {
  margin: 4px 0; font-size: clamp(1.6rem, 6vw, 2.4rem); font-weight: 800; line-height: 1.15;
  color: var(--violet-text);
}
#game-view .aufgabe__folge {
  list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; counter-reset: punkt;
}
#game-view .aufgabe__punkt {
  counter-increment: punkt; display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px 4px 6px; border-radius: 999px; font-size: 0.85rem; font-weight: 600;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
}
#game-view .aufgabe__punkt::before {
  content: counter(punkt); min-width: 1.4em; height: 1.4em; border-radius: 999px; display: inline-grid; place-items: center;
  font-size: 0.72rem; font-variant-numeric: tabular-nums; background: var(--card); color: var(--muted);
}
#game-view .aufgabe__punkt--a { border-color: rgba(var(--marke-rgb), 0.55); }
#game-view .aufgabe__punkt--a::before { background: var(--violet); color: var(--on-solid); }
#game-view .aufgabe__punkt--n { border-style: dashed; color: var(--muted); }
#game-view .aufgabe__tabelle-rahmen { overflow-x: auto; }
#game-view .aufgabe__tabelle { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
#game-view .aufgabe__tabelle th {
  text-align: left; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--muted); font-weight: 600; padding: 6px 8px; border-bottom: 1px solid var(--line);
}
#game-view .aufgabe__tabelle td { padding: 7px 8px; border-bottom: 1px solid var(--line); }
#game-view .aufgabe__tabelle tr.ist-markiert td { background: rgba(var(--marke-rgb), 0.14); font-weight: 700; }
#game-view .aufgabe__regel { margin: 0; font-size: 0.85rem; color: var(--muted); }
#game-view .aufgabe__frage { margin: 4px 0 0; font-weight: 700; font-size: 1.05rem; }
#game-view .aufgabe__optionen { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
#game-view .aufgabe__option {
  min-height: 48px; padding: 10px 12px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--card); color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums;
  text-align: center; cursor: pointer;
}
#game-view .aufgabe__option:not(:disabled):hover { border-color: rgba(var(--marke-rgb), 0.7); }
#game-view .aufgabe__option:disabled { cursor: default; }
#game-view .aufgabe__option.ist-richtig { border-color: var(--correct); background: rgba(var(--marke-rgb), 0.16); color: var(--correct-text, var(--text)); }
#game-view .aufgabe__option.ist-falsch { border-color: var(--rot-text); color: var(--rot-text); }
#game-view .aufgaben .checkout-bilanz__zeile { grid-template-columns: 2rem 1fr auto; }
/* Streckenumriss (Formel 1 · Strecke). Die Linie nimmt die Markenfarbe der
   Sportart; ein heller Unterstrich darunter traegt sie auf beiden Themen. */
#game-view .rate-umriss { margin: 6px auto 12px; max-width: 260px; text-align: center; }
#game-view .rate-umriss svg { width: 100%; height: auto; aspect-ratio: 1; display: block; }
#game-view .rate-umriss path {
  fill: none; stroke: var(--violet-text); stroke-width: 2.4; stroke-linejoin: round; stroke-linecap: round;
}
#game-view .rate-umriss figcaption { font-size: 0.72rem; color: var(--muted); margin-top: 2px; }
#game-view .rate-umriss figcaption a { color: inherit; }
/* Zuordnen (Fachsprache): Begriffe als Leiste, Bedeutungen als Karten mit
   einem Platz vorne. Der gewaehlte Begriff traegt die Markenfarbe, ein
   vergebener wird blass — er steht schon irgendwo. */
#game-view .zuordnen { display: grid; gap: 10px; }
#game-view .zuordnen__begriffe { display: flex; flex-wrap: wrap; gap: 6px; }
#game-view .zuordnen__begriff {
  min-height: 40px; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--card); color: var(--text); font-weight: 700; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
}
#game-view .zuordnen__begriff.ist-gewaehlt { background: var(--violet); border-color: var(--violet); color: var(--on-solid); }
#game-view .zuordnen__begriff.ist-vergeben:not(.ist-gewaehlt) { opacity: 0.45; }
#game-view .zuordnen__karten { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
#game-view .zuordnen__karte {
  width: 100%; min-height: 48px; display: grid; grid-template-columns: minmax(84px, 38%) 1fr; gap: 10px; align-items: center;
  padding: 8px 12px; border-radius: 12px; border: 1px solid var(--line); background: var(--panel); color: var(--text);
  text-align: left; cursor: pointer; font: inherit;
}
#game-view .zuordnen__slot {
  min-height: 30px; display: inline-flex; align-items: center; justify-content: center; gap: 4px; padding: 2px 8px;
  border-radius: 8px; border: 1px dashed var(--line); font-weight: 700; color: var(--text); font-size: 0.85rem;
  flex-wrap: wrap; text-align: center;
}
#game-view .zuordnen__slot s { color: var(--muted); font-weight: 400; }
#game-view .zuordnen__karte.ist-falsch .zuordnen__slot { color: var(--correct-text, var(--text)); }
#game-view .zuordnen__text { font-size: 0.92rem; }
#game-view .zuordnen__karte.ist-richtig { border-color: var(--correct); }
#game-view .zuordnen__karte.ist-falsch { border-color: var(--rot-text); }
#game-view .flagge { width: 30px; height: 20px; display: block; flex: none; }
/* Auf dem Handy: dieselben Aufgaben auf einem Bildschirm. Gemessen am
   17.09.2026 bei 375 × 812 lag etwa jedes dritte Regelspiel mit seiner
   letzten Antwort unter der Kante, auf Experte bis 1036 px. Gestrafft wird
   Luft, nicht Trefferflaeche: Antworten und Karten bleiben 44 px hoch. */
@media (max-width: 560px) {
  #game-view .aufgabe { gap: 6px; margin: 4px 0 8px; }
  #game-view .aufgabe__frage { font-size: 0.98rem; margin-top: 0; }
  #game-view .aufgabe__regel { font-size: 0.76rem; line-height: 1.35; }
  #game-view .aufgabe__tabelle th { padding: 4px 6px; font-size: 0.68rem; }
  #game-view .aufgabe__tabelle td { padding: 4px 6px; font-size: 0.88rem; }
  #game-view .aufgabe__folge { gap: 4px; }
  #game-view .aufgabe__punkt { padding: 2px 8px 2px 4px; font-size: 0.8rem; }
  #game-view .aufgabe__optionen { gap: 6px; }
  #game-view .aufgabe__option { min-height: 44px; padding: 6px 8px; }
  #game-view .aufgabe__gross { margin: 0; }
  #game-view .zuordnen { gap: 6px; }
  #game-view .zuordnen__begriff { min-height: 36px; padding: 4px 10px; font-size: 0.88rem; }
  #game-view .zuordnen__karten { gap: 4px; }
  #game-view .zuordnen__karte { min-height: 44px; padding: 5px 8px; gap: 8px; grid-template-columns: minmax(72px, 36%) 1fr; }
  #game-view .zuordnen__text { font-size: 0.84rem; line-height: 1.3; }
  #game-view .aufgaben .checkout-stand { font-size: 0.82rem; }
  #game-view .aufgaben .checkout-aktionen { margin-top: 6px; }
}
#game-view .checkout-modi { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 4px 0 10px; }
#game-view .checkout-modi .checkout-faktor__knopf { font-size: 0.85rem; padding: 0 6px; }
#game-view .aufgabe__uhr { height: 6px; border-radius: 999px; background: var(--panel); overflow: hidden; margin: 6px 0 2px; }
#game-view .aufgabe__uhr span { display: block; height: 100%; width: 100%; background: var(--violet); border-radius: inherit; }
@media (max-width: 420px) {
  #game-view .aufgabe__optionen--viele { grid-template-columns: 1fr; }
}

/* ==========================================================================
   DIE LIGA WIE EINE FUSSBALL-APP (28. September 2026, Ansage des Eigentuemers)

   "Die Herausforderungen sind zu gross, die Tabelle schaut noch nicht clean
   aus, orientiere dich an Fussball-Apps." Gemessen bei 375 x 812 mit fuenf
   Mitgliedern und drei offenen Duellen: 1287 px, gut anderthalb Bildschirme.

   Was eine Tabelle in einer Fussball-App ausmacht und hier uebernommen ist:
   EINE Flaeche statt einer Karte je Zeile, Haarlinien dazwischen, schmale
   Zahlenspalten mit fester Breite, die Punkte ganz rechts und fett, der
   eigene Platz getoent, die oberen Plaetze mit einem Farbstreifen am Rand.
   Die Duelle sind Zeilen derselben Art: wer, welches Spiel, wie lange noch,
   rechts die Handlung.

   Die Regeln stehen am Ende der Datei und gewinnen dadurch gegen die aelteren
   gleicher Spezifitaet weiter oben — die aelteren erklaeren, WARUM feste
   Spaltenbreiten; das gilt hier weiter.
   ========================================================================== */

/* ---- Kopf ---------------------------------------------------------------- */
#game-view .liga-view .liga-kopf { margin-bottom: 8px; }
#game-view .liga-view .liga-kopf .cp-title { margin: 6px 0 0; }
#game-view .liga-code-zeile { margin-top: 6px; gap: 10px; }
#game-view .liga-code { font-size: 0.92rem; padding: 4px 10px; border-radius: 8px; letter-spacing: 0.16em; }
#game-view .liga-abschnitt-titel { margin: 12px 0 6px; font-size: 0.66rem; }

/* ---- Duelle: eine Zeile je Duell ------------------------------------------ */
#game-view .liga-duelle {
  gap: 0;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden;
}
#game-view .liga-duell,
#game-view .liga-duell--gross {
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 10px; row-gap: 0;
  padding: 9px 12px 9px 11px;
  background: none; border: 0; border-radius: 0;
  border-left: 3px solid transparent;
  font-size: 0.86rem;
}
#game-view .liga-duell + .liga-duell { border-top: 1px solid var(--line); }
#game-view .liga-duell.dran { border-left-color: var(--violet-text); }
#game-view .liga-duell.gewonnen { border-left-color: var(--correct, #17A65A); }
#game-view .liga-duell.verloren { border-left-color: var(--rot-text, #FF6B85); }
#game-view .liga-duell-info { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
#game-view .liga-duell-gegner,
#game-view .liga-duell--gross .liga-duell-gegner {
  font-size: 0.9rem; font-weight: 800;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#game-view .liga-duell-meta {
  display: flex; gap: 6px; min-width: 0;
  font-size: 0.72rem; color: var(--muted);
  overflow: hidden; white-space: nowrap;
}
#game-view .liga-duell-meta > * { overflow: hidden; text-overflow: ellipsis; }
#game-view .liga-duell-modus, #game-view .liga-duell-status { font-size: inherit; grid-column: auto; text-align: left; }
#game-view .liga-duell-modus::after { content: "·"; margin-left: 6px; }
#game-view .liga-duell-stand { grid-column: auto; font-variant-numeric: tabular-nums; }
#game-view .liga-duell-stand:empty { display: none; }
#game-view .liga-duell-aktionen,
#game-view .liga-duell .liga-duell-aktionen {
  grid-column: auto; justify-self: end; align-items: center; gap: 4px;
}
#game-view .liga-duell .liga-duell-spielen,
#game-view .liga-duell-aktionen .action {
  flex: none; margin: 0; min-height: 32px; padding: 5px 14px;
  font-size: 0.78rem; border-radius: 999px;
}
#game-view .liga-duell-zurueckziehen {
  flex: none; position: relative;
  display: inline-grid; place-items: center;
  width: 28px; height: 28px; padding: 0; margin: 0;
  border-radius: 50%; border: 1px solid var(--line);
  background: transparent; color: var(--muted);
  font: 400 1.05rem/1 inherit; cursor: pointer;
}
/* Die Scheibe bleibt klein, der Finger trifft 44 px. */
#game-view .liga-duell-zurueckziehen::before { content: ""; position: absolute; inset: -8px; }
#game-view .liga-duell-zurueckziehen:hover { color: var(--rot-text); border-color: var(--rot-text); }
#game-view .liga-dran { margin-bottom: 0; }
#game-view .liga-dran .liga-hinweis { margin: 0; padding: 12px; }
#game-view .liga-verlauf .liga-duelle { margin-top: 6px; }

/* ---- Tabelle ---------------------------------------------------------------
   #  Spieler  Sp  S  Form  Pkt  [VS]  — die Punkte ganz rechts, wie ueberall. */
#game-view .liga-tabelle--form {
  gap: 0;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden;
}
#game-view .liga-tabelle--form .liga-zeile {
  grid-template-columns: 26px minmax(0, 1fr) 28px 28px 62px 34px 34px;
  gap: 6px; row-gap: 0;
  min-height: 42px; padding: 0 10px 0 0;
  background: none; border: 0; border-radius: 0;
  font-size: 0.86rem;
  position: relative;
}
#game-view .liga-tabelle--form .liga-zeile + .liga-zeile { border-top: 1px solid var(--line); }
#game-view .liga-tabelle--form .liga-kopfzeile {
  min-height: 30px; padding-top: 0; padding-bottom: 0;
  font-size: 0.62rem; letter-spacing: 0.08em;
  background: rgba(127, 127, 127, 0.06);
}
/* Zahlenspalten: Sp, S und Pkt mittig bzw. rechtsbuendig, Kopf wie Zelle. */
#game-view .liga-tabelle--form .liga-zeile > :nth-child(1) { text-align: center; }
#game-view .liga-tabelle--form .liga-zeile > :nth-child(3),
#game-view .liga-tabelle--form .liga-zeile > :nth-child(4) { text-align: center; font-variant-numeric: tabular-nums; }
#game-view .liga-tabelle--form .liga-zeile > :nth-child(6) { text-align: right; font-variant-numeric: tabular-nums; }
#game-view .liga-spiele, #game-view .liga-siege { display: block; color: var(--muted); font-weight: 600; }
#game-view .liga-tabelle--form .liga-punkte { font-weight: 900; color: var(--ink); font-size: 0.92rem; }
#game-view .liga-platz { font-size: 0.82rem; }
/* Die oberen Plaetze tragen einen Streifen am Rand — die Farbe der
   Marke fuer Platz 1, darunter leiser. Wie die Champions-League-Plaetze. */
#game-view .liga-tabelle--form .liga-zeile:not(.liga-kopfzeile)::before {
  content: ""; position: absolute; left: 0; top: 6px; bottom: 6px; width: 3px;
  border-radius: 0 3px 3px 0; background: transparent;
}
#game-view .liga-tabelle--form .liga-zeile:has(.liga-platz.top)::before { background: rgba(var(--marke-rgb), 0.45); }
#game-view .liga-tabelle--form .liga-zeile:nth-child(2)::before { background: var(--violet-text); }
#game-view .liga-platz.top { color: var(--ink); }
#game-view .liga-tabelle--form .liga-zeile.ich {
  background: rgba(var(--marke-rgb), 0.12); border-color: var(--line);
}
#game-view .liga-tabelle--form .liga-zeile.ich .liga-name { color: var(--violet-text); }
#game-view .liga-form { gap: 2px; }
#game-view .liga-form__x { width: 16px; height: 16px; border-radius: 50%; font-size: 0.6rem; }

/* Die Tages-Tabelle (reine Tages-Liga und die zweite Tabelle bei "beides")
   in derselben Bauart: EINE Flaeche mit Haarlinien. Stand sie als Stapel
   einzelner Karten direkt unter der flachen Duelltabelle, sahen zwei
   Tabellen derselben Liga aus wie zwei verschiedene Dinge. */
#game-view .liga-tabelle--tage {
  gap: 0;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden;
}
#game-view .liga-tabelle--tage .liga-zeile {
  grid-template-columns: 26px minmax(0, 1fr) 34px 62px 44px;
  gap: 6px; min-height: 42px; padding: 0 10px 0 0;
  background: none; border: 0; border-radius: 0; font-size: 0.86rem;
}
#game-view .liga-tabelle--tage .liga-zeile + .liga-zeile { border-top: 1px solid var(--line); }
#game-view .liga-tabelle--tage .liga-kopfzeile {
  min-height: 30px; font-size: 0.62rem; letter-spacing: 0.08em;
  background: rgba(127, 127, 127, 0.06);
}
#game-view .liga-tabelle--tage .liga-zeile > :nth-child(1) { text-align: center; }
#game-view .liga-tabelle--tage .liga-punkte { font-weight: 900; color: var(--ink); font-size: 0.92rem; }
#game-view .liga-tabelle--tage .liga-zeile.ich { background: rgba(var(--marke-rgb), 0.12); }
#game-view .liga-tabelle--tage .liga-zeile.ich .liga-name { color: var(--violet-text); }
#game-view .liga-sportarten-liste--anzeige { margin-bottom: 8px; }
#game-view .liga-zeilenaktion { grid-column: auto; justify-content: flex-end; }
#game-view .liga-fordern-knopf {
  position: relative;
  display: inline-grid; place-items: center;
  width: 30px; height: 26px; padding: 0;
  border-radius: 8px; border: 1px solid var(--violet-text);
  background: rgba(var(--marke-rgb), 0.1); color: var(--violet-text);
  font: 900 0.62rem/1 inherit; letter-spacing: 0.02em; cursor: pointer;
}
#game-view .liga-fordern-knopf::before { content: ""; position: absolute; inset: -9px -4px; }

/* Am Telefon faellt die Form aus der Tabelle — sie ist die fuenfte Zahl in
   einer Zeile, die sonst umbricht. Der Streifen fuer "wie laeuft es gerade"
   steckt ohnehin in S und Pkt. */
@media (max-width: 559px) {
  #game-view .liga-tabelle--form .liga-zeile {
    grid-template-columns: 26px minmax(0, 1fr) 26px 26px 32px 32px;
    row-gap: 0; gap: 4px;
  }
  #game-view .liga-tabelle--form .liga-zeile > .liga-form,
  #game-view .liga-tabelle--form .liga-kopfzeile span:nth-child(5) { display: none; }
  #game-view .liga-tabelle--form .liga-kopfzeile span:nth-child(6),
  #game-view .liga-tabelle--form .liga-kopfzeile span:nth-child(7) { display: block; }
  #game-view .liga-zeilenaktion { grid-column: auto; justify-content: flex-end; }
  #game-view .liga-duell { grid-template-columns: minmax(0, 1fr) auto auto; }
  #game-view .liga-duell-aktionen { grid-column: auto; justify-self: end; }
  #game-view .liga-view .liga-kopf .cp-title { font-size: 1.4rem; }
  #game-view .liga-view .cp-actions { margin-top: 10px; }
  #game-view .liga-view .cp-actions #liga-verlassen { padding: 6px 14px; font-size: 0.8rem; min-height: 34px; }
  #game-view .liga-view .liga-zurueck { min-height: 34px; padding: 4px 12px 4px 8px; margin-bottom: 0; }
}

/* ---- Der Einstieg: drei Kacheln nebeneinander --------------------------------
   Wie "Meistgespielt": drei Hochformate in einer Reihe statt drei flacher
   Balken untereinander. Symbol oben, Titel und Zeile unten. */
@media (max-width: 619px) {
  /* Feste Mindesthoehe statt aspect-ratio: Das Seitenverhaeltnis gab bei
     "Aktive Ligen" (Titel auf zwei Zeilen plus Zahl) nach, und die drei
     Kacheln standen verschieden hoch. So streckt das Raster alle drei auf
     die hoechste. */
  #game-view .liga-reiter { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; align-items: stretch; }
  #game-view .liga-kachel {
    min-height: 184px; justify-content: space-between;
    padding: 14px 11px; border-radius: 18px; gap: 5px;
  }
  #game-view .liga-kachel__pfeil { display: none; }
  #game-view .liga-kachel__symbol { width: 42px; height: 42px; border-radius: 13px; }
  #game-view .liga-kachel__symbol svg { width: 23px; height: 23px; }
  #game-view .liga-kachel__titel { margin-top: auto; font-size: 0.98rem; line-height: 1.15; flex-wrap: wrap; gap: 4px; }
  #game-view .liga-kachel__titel .liga-zahl { margin-left: 0; }
  #game-view .liga-kachel__text { font-size: 0.7rem; line-height: 1.3; }
}

/* ==========================================================================
   DAS PROFIL IN VIER KACHELN (28. September 2026, Ansage des Eigentuemers)

   Spieler ueber die volle Breite, darunter Statistik und Woche nebeneinander,
   darunter Erfolge. Jede Kachel ist ein Knopf und fuehrt dorthin, wo steht,
   was sie nur anreisst — siehe renderProfil(). Auf allen Breiten dieselbe
   Anordnung; am Rechner wird sie nur breiter, nicht anders.
   ========================================================================== */
#game-view .profil-kacheln {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px;
  max-width: 720px; margin: 0 auto;
}
#game-view .profil-kachel {
  position: relative;
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  min-width: 0; padding: 14px;
  border-radius: 18px; border: 1px solid var(--line);
  background: var(--panel); color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
  transition: border-color 0.14s ease;
}
#game-view .profil-kachel:hover { border-color: var(--muted); }
#game-view .profil-kachel:focus-visible { outline: 2px solid var(--color-ring); outline-offset: 2px; }
#game-view .profil-kachel b { color: var(--ink); }
#game-view .profil-kachel__kopf {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 0.66rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}
#game-view .profil-kachel__pfeil { font-size: 1.3rem; line-height: 0.6; color: var(--muted); letter-spacing: 0; }
#game-view .profil-kachel__klein {
  font-size: 0.72rem; line-height: 1.35; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
}
#game-view .profil-kachel__xp {
  display: block; height: 6px; border-radius: 99px; overflow: hidden;
  background: var(--color-bg-inset, var(--line));
}
#game-view .profil-kachel__xp i { display: block; height: 100%; border-radius: inherit; background: var(--violet); }

/* ---- 1. Spieler, volle Breite ---- */
#game-view .profil-kachel--spieler {
  grid-column: 1 / -1;
  flex-direction: row; align-items: center; gap: 14px;
  border-color: rgba(var(--marke-rgb), 0.45);
}
#game-view .profil-kachel--spieler > .profil-kachel__pfeil { position: absolute; right: 14px; top: 14px; }
#game-view .profil-kachel__avatar {
  position: relative; flex: none; width: 76px; height: 76px;
  border-radius: 50%; border: 2px solid var(--violet);
  background: var(--color-bg-inset, var(--card));
}
#game-view .profil-kachel__avatar svg { width: 100%; height: 100%; display: block; border-radius: 50%; overflow: hidden; }
#game-view .profil-kachel__level {
  position: absolute; left: 50%; bottom: -8px; transform: translateX(-50%);
  white-space: nowrap; padding: 2px 8px; border-radius: 99px;
  background: var(--violet); color: var(--on-solid);
  font-size: 0.62rem; font-weight: 800;
}
#game-view .profil-kachel__spieler { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; padding-right: 14px; }
#game-view .profil-kachel__name {
  font-size: 1.3rem; font-weight: 800; letter-spacing: -0.02em; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#game-view .profil-kachel__rang {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--violet-text);
}
#game-view .profil-kachel__sterne i { font-style: normal; color: var(--line); letter-spacing: 1px; font-size: 0.8rem; }
#game-view .profil-kachel__sterne i.on { color: var(--color-accent-text); }

/* ---- 2. Statistik ---- */
#game-view .profil-zahlen { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 6px; }
#game-view .profil-zahlen > span { display: flex; flex-direction: column; min-width: 0; }
#game-view .profil-zahlen b { font-size: 1.25rem; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
#game-view .profil-zahlen small { font-size: 0.64rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- 3. Woche ---- */
#game-view .profil-serie2 { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
#game-view .profil-serie2 > span { font-size: 1.1rem; }
#game-view .profil-serie2 b { font-size: 2rem; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }
#game-view .profil-serie2 small { font-size: 0.64rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; }
#game-view .profil-woche { display: flex; gap: 4px; }
#game-view .profil-woche__tag { flex: 1 1 0; height: 8px; border-radius: 99px; background: var(--line); }
#game-view .profil-woche__tag.is-voll { background: var(--color-accent-text); }
#game-view .profil-woche__tag.is-kommt { background: none; box-shadow: inset 0 0 0 1px var(--line); }
#game-view .profil-woche__tag.is-heute { box-shadow: 0 0 0 2px var(--panel), 0 0 0 3px var(--color-accent-text); }

/* ---- 4. Erfolge, volle Breite ---- */
#game-view .profil-kachel--erfolge { grid-column: 1 / -1; }
#game-view .profil-erfolge { display: flex; align-items: center; gap: 12px; }
#game-view .profil-erfolge__zahl { flex: none; font-size: 0.9rem; color: var(--muted); font-variant-numeric: tabular-nums; }
#game-view .profil-erfolge__zahl b { font-size: 1.5rem; font-weight: 800; }
#game-view .profil-erfolge .profil-kachel__xp { flex: 1; }
#game-view .profil-erfolge .profil-kachel__xp i { background: var(--color-accent-text); }

/* ---- Die Unterseiten ---- */
#game-view .profile-view--detail { max-width: 720px; margin: 0 auto; }
#game-view .profil-zurueck {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 36px; padding: 5px 14px 5px 10px; margin-bottom: 10px;
  border-radius: 999px; background: var(--panel); border: 1px solid var(--line);
  color: var(--text); font: inherit; font-size: 0.86rem; font-weight: 700; cursor: pointer;
}
#game-view .profil-zurueck span { font-size: 1.25rem; line-height: 1; }
#game-view .profil-detail__titel { margin: 0 0 12px; font-size: 1.4rem; font-weight: 800; color: var(--ink); }
/* Auf der Spielerseite ist nichts mehr hinter "Details zeigen" versteckt. */
#game-view .profile-view--detail .profil-mehr-schalter,
#game-view .profile-view--detail .profil-serie { display: none; }

/* Der Slogan unter den drei Liga-Kacheln (28.09.2026). Gross und in der
   Schrift der Ueberschriften, damit er als Aussage steht und nicht als
   Hinweis; die Unterzeile leise darunter. */
#game-view .liga-slogan { position: relative; margin: 48px 0 8px; }
#game-view .liga-slogan__gross {
  margin: 0; font-family: var(--font-display); font-size: clamp(2rem, 9vw, 3rem);
  font-weight: 800; line-height: 1.02; letter-spacing: -0.03em; color: var(--ink);
}
#game-view .liga-slogan__klein {
  margin: 8px 0 0; font-size: 1rem; font-weight: 600; color: var(--violet-text);
}

/* ==========================================================================
   DIE SPIELE AUF DEM TELEFON — jedes auf einen Blick
   (28. September 2026, Ansage des Eigentuemers)

   "Wenn man irgendwo draufklickt, soll man alles auf einen Blick sehen."
   Gemessen bei 375 x 812. Was hier steht, gilt fuer alle Spiele; was nur ein
   Spiel betrifft, steht in dessen Abschnitt weiter unten.
   ========================================================================== */

/* ALLES AB HIER GILT NUR AM TELEFON (29.09.2026, Ansage des Eigentuemers):
   "Die Aenderungen sollen nur fuer die Handyansicht gelten, auf dem Laptop
   soll das alte Design wieder her." Deshalb steht der ganze Rest dieser
   Datei in einer Medienabfrage bis 560 px; was im Markup anders ist, fragt
   handyAnsicht() in app.js mit derselben Schwelle. Verschachtelte
   Medienabfragen darin sind gueltiges CSS und bleiben stehen. */
@media (max-width: 560px) {
/* ---- Kopf an Kopf, Tages-Challenge: drei Kacheln statt drei Zeilen -------- */
#game-view .cmp-tages-kacheln {
  list-style: none; margin: 14px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
}
#game-view .cmp-tages-kacheln li {
  display: flex; flex-direction: column; justify-content: center; gap: 3px;
  min-height: 74px; padding: 10px 8px; text-align: center;
  border-radius: 14px; border: 1px solid var(--line);
  background: rgba(var(--marke-rgb), 0.08);
}
#game-view .cmp-tages-kacheln b { font-size: 0.98rem; font-weight: 800; color: var(--ink); line-height: 1.15; overflow-wrap: anywhere; hyphens: auto; }
#game-view .cmp-tages-kacheln span {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
}
#game-view .cmp-tages-aktionen .action:first-child { flex: 1 1 100%; }

@media (max-width: 560px) {
  /* ---- Die Spielleiste: ein Pfeil, ein Name, eine Zeile -------------------
     "Zurück zum Katalog" brach am Telefon auf zwei Zeilen um und schob den
     Spielnamen ebenfalls in zwei — die Leiste war 60 px Beschriftung fuer
     einen Pfeil. Der Pfeil allein ist die Geste, die jeder kennt; sein
     Name steht im aria-label. */
  .spielleiste { gap: 10px; height: 52px; }
  .spielleiste__zurueck { min-width: 44px; justify-content: center; }
  .spielleiste__zurueck #back-btn-text { display: none; }
  .spielleiste__name {
    font-size: 1rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1;
  }
}

@media (max-width: 560px) {
  /* ---- Der Kopf jedes Spiels ----------------------------------------------
     Der grosse Titel wiederholte, was einen Fingerbreit darueber in der
     Spielleiste steht — am Telefon faellt er weg. Die Moduszeile bleibt,
     aber als eine Zeile, die sich kuerzt statt umzubrechen: Wer mehr wissen
     will, findet es hinter dem i. */
  #game-view .spiel-kopf .spiel-titel { display: none; }
  #game-view .spiel-kopf .modus-reihe { gap: 6px; }
  #game-view .spiel-kopf .modus-btn { min-height: 34px; padding: 6px 13px; font-size: 0.8rem; }
  #game-view .spiel-kopf .modus-hinweis {
    margin: 6px 0 4px; font-size: 0.68rem; line-height: 1.35;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  #game-view .spiel-kopf .spiel-serie { font-size: 0.74rem; margin-top: 2px; }

  /* ---- Flugroute ---------------------------------------------------------
     Die Karte ist das Bild dieses Spiels und wird groesser; die Stationen
     werden kleiner — eine Zeile Verein mit Toren rechts, eine Zeile Jahre
     darunter, der Balken faellt weg (die Tore stehen als Zahl daneben). */
  #game-view .cp-map-wrap { margin: 8px 0 4px; border-radius: 14px; }
  #game-view .cp-map { max-height: 190px; }
  #game-view .cp-km { font-size: 0.7rem; margin: 0 0 4px; min-height: 0; }
  #game-view .cp-stations-head { margin: 4px 0 4px; font-size: 0.7rem; }
  #game-view .cp-stations { gap: 4px; margin-bottom: 8px; }
  #game-view .cp-station-row {
    grid-template-columns: 18px minmax(0, 1fr) auto; gap: 0 8px;
    padding: 5px 9px; border-radius: 10px;
  }
  #game-view .cp-station-num { font-size: 0.66rem; grid-row: 1 / 3; }
  #game-view .cp-station-club { font-size: 0.84rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  #game-view .cp-station-meta { font-size: 0.64rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  #game-view .cp-station-stats { grid-column: 3; grid-row: 1 / 3; align-self: center; text-align: right; font-size: 0.68rem; }
  #game-view .cp-station-bar { display: none; }
  #game-view .cp-aufdecken { margin-block: 6px; }
  #game-view .cp-aufdecken .action { min-height: 38px; padding: 7px 12px; font-size: 0.82rem; }
  #game-view .cp-question { font-size: 0.95rem; margin: 4px 0 6px; }
  #game-view .cp-lives-bar { margin-block: 6px; padding: 4px 12px; }
  #game-view .cp-shop-hint { margin-top: 4px; font-size: 0.68rem; }
  #game-view .cp-aufgeben { margin-top: 6px; padding: 7px 14px; font-size: 0.8rem; }
  /* Position und Region auf EINER Linie, je die halbe Breite. */
  #game-view .cp-filters { flex-wrap: nowrap; gap: 8px; margin: 6px 0 0; }
  #game-view .cp-filters .cp-filter { flex: 1 1 0; min-width: 0; font-size: 0.6rem; gap: 3px; }
  #game-view .cp-filters .cp-filter select { min-width: 0; max-width: none; width: 100%; padding: 7px 9px; font-size: 0.82rem; }
}

/* Der Block darueber gilt noch — aber nur fuer das Duell (renderDuel()),
   das weiterhin .cp-map-wrap/.cp-stations/.cp-station-row zeichnet. Fuer
   Endlos, Tages-Challenge und Archiv zeichnet drawHandy() seit dem
   29.09.2026 andere Klassen (Stationen links, Karte rechts, siehe der
   Kommentar dort in careerpath.js), die bislang ungestylt blieben. */
@media (max-width: 560px) {
  /* ---- Flugroute, Endlos/Tages/Archiv: Liste links, Karte rechts ---------- */
  #game-view .cp-feld {
    display: flex; gap: 10px; align-items: stretch;
    height: 300px; /* Fallback, bevor cpFeldAnpassen() misst und ueberschreibt */
    margin: 10px 0 4px;
  }
  #game-view .cp-feld__liste {
    flex: 1 1 42%; min-width: 0; min-height: 0;
    display: flex; flex-direction: column;
  }
  #game-view .cp-feld__liste .cp-stations-head { margin: 0 0 4px; font-size: 0.66rem; flex: 0 0 auto; }
  #game-view .cp-feld__liste .cp-aufdecken { margin: 6px 0 0; flex: 0 0 auto; }
  #game-view .cp-feld__liste .cp-aufdecken .action { min-height: 36px; padding: 6px 10px; font-size: 0.78rem; }
  #game-view .cp-feld__liste .cp-aufdecken-preis { font-size: 0.66rem; }
  #game-view .cp-hstationen {
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
    display: flex; flex-direction: column; gap: 4px;
  }
  #game-view .cp-hstation {
    display: grid; grid-template-columns: 18px minmax(0, 1fr);
    grid-template-rows: auto auto; align-items: center; gap: 0 6px;
    background: var(--panel); border: 1px solid var(--line); border-radius: 9px;
    padding: 5px 8px;
  }
  /* Nur die neu aufgedeckte Station animiert — sonst "wandert" die ganze Liste bei jedem Redraw. */
  #game-view .cp-hstation.is-new { animation: slideIn 0.25s ease; }
  #game-view .cp-hstation__nr {
    grid-column: 1; grid-row: 1 / 3; align-self: center;
    background: var(--violet); color: var(--on-solid); font-weight: 700;
    border-radius: 50%; width: 17px; height: 17px;
    display: flex; align-items: center; justify-content: center; font-size: 0.6rem;
  }
  #game-view .cp-hstation__club {
    grid-column: 2; font-weight: 700; font-size: 0.76rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  #game-view .cp-hstation__meta {
    grid-column: 2; color: var(--muted); font-size: 0.62rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  #game-view .cp-feld__karte {
    flex: 1 1 58%; min-width: 0; min-height: 0; position: relative;
    background: #0C1A24; border: 1px solid var(--line); border-radius: 14px;
    overflow: hidden;
  }
  #game-view .cp-feld__karte .cp-map { width: 100%; height: 100%; display: block; }
  #game-view .cp-feld__km {
    position: absolute; right: 8px; bottom: 8px;
    background: rgba(4, 16, 9, 0.65); color: #EEF3F0;
    font-size: 0.64rem; font-weight: 700; letter-spacing: 0.02em;
    padding: 3px 8px; border-radius: 999px; font-variant-numeric: tabular-nums;
  }
}

/* ---- Die Elf: eine Spielfeldhaelfte, Trikots mit Nummer (28.09.2026) ------
   Alle Breiten. Das Feld ist gemaehter Rasen in zwei Gruentoenen, darauf die
   gezeichnete Haelfte (m11FeldSvg in app.js); die Reihen liegen darueber. */
#game-view .m11-feld {
  position: relative; isolation: isolate;
  max-width: 420px; margin: 12px auto 10px; padding: 16px 10px 12px; gap: 12px;
  border-radius: 14px; border: 1px solid rgba(255, 255, 255, 0.10);
  background:
    repeating-linear-gradient(180deg, #1d6b3a 0 36px, #1a6135 36px 72px);
  overflow: hidden;
}
/* Das Feld endet ueber der Fusszeile (Zaehler, Versuche, Aufgeben) — sonst
   liefen Strafraum und Tor unter die Knoepfe. */
#game-view .m11-platz {
  position: absolute; left: 0; top: 0; width: 100%; height: calc(100% - 50px); z-index: -1;
  color: rgba(255, 255, 255, 0.55);
}
#game-view .m11-reihe { position: relative; }
/* Der Torwart stand links: Die Reihe war ein Raster mit einer Spalte der
   Breite `auto`, und die sitzt ohne Anweisung am Anfang. */
#game-view .m11-reihe--tor,
#game-view .m11-reihe--sturm { justify-content: center; grid-auto-columns: minmax(0, 84px); }
#game-view .m11-reihe--sturm { width: auto; gap: 28px; }
#game-view .m11-reihe--tor { padding-top: 6px; }
#game-view .m11-reihe--tor .m11-slot { width: auto; }
#game-view .m11-slot,
#game-view .m11-slot.is-set,
#game-view .m11-slot--tor.is-set {
  background: none; border: 0; padding: 0; gap: 3px; max-width: 84px;
}
#game-view .m11-shirt svg,
#game-view .m11-trikot { width: 42px; height: 38px; display: block; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35)); }
#game-view .m11-trikot__stoff { fill: rgba(255, 255, 255, 0.10); stroke: rgba(255, 255, 255, 0.75); stroke-width: 1.4; stroke-linejoin: round; }
#game-view .m11-trikot__kragen, #game-view .m11-trikot__saum { stroke: rgba(255, 255, 255, 0.75); stroke-width: 1.4; }
#game-view .m11-trikot text {
  fill: rgba(255, 255, 255, 0.85); font: 800 15px/1 var(--font-display, system-ui); letter-spacing: -0.02em;
}
#game-view .m11-slot--tor .m11-trikot__stoff { fill: rgba(255, 197, 61, 0.22); stroke: #FFC53D; }
#game-view .m11-slot--tor .m11-trikot__kragen, #game-view .m11-slot--tor .m11-trikot__saum { stroke: #FFC53D; }
#game-view .m11-name {
  max-width: 84px; padding: 1px 6px; border-radius: 6px;
  background: rgba(4, 16, 9, 0.55); color: rgba(255, 255, 255, 0.72);
  font-size: 0.62rem; line-height: 1.25;
}
#game-view .m11-slot.is-set .m11-name { background: #fff; color: #0a1a10; font-weight: 800; }
#game-view .m11-slot .m11-kopf { box-shadow: 0 0 0 2px #fff, 0 2px 6px rgba(0, 0, 0, 0.4); }
#game-view .m11-fuss {
  position: relative; margin: 2px -10px -12px; padding: 8px 10px;
  background: rgba(4, 16, 9, 0.55); color: rgba(255, 255, 255, 0.85);
}
#game-view .m11-fuss .m11-versuche { color: rgba(255, 255, 255, 0.7); }
#game-view .m11-fuss .m11-zaehler, #game-view .m11-fuss .m11-zaehler b { color: #fff; }

@media (max-width: 560px) {
  #game-view .m11-aufgabe { font-size: 0.98rem; margin: 6px 0 2px; }
  #game-view .m11-aufgabe + .hint { font-size: 0.72rem; margin: 0; }
  #game-view .m11-feld { padding: 12px 6px 10px; gap: 9px; margin: 8px auto; }
  #game-view .m11-fuss { margin: 2px -6px -10px; padding: 7px 8px; }
  #game-view .m11-shirt svg, #game-view .m11-trikot { width: 36px; height: 33px; }
  #game-view .m11-reihe { gap: 4px; }
}

/* ---- Beflockung: das Brett auf einem Trikotruecken (28.09.2026) -----------
   Alle Breiten. Der Ruecken ist eine Stoffflaeche in der Farbe der Marke mit
   V-Kragen oben, die Buchstaben stehen darauf wie aufgeflockt: kraeftig,
   in der Schrift der Ueberschriften. Die Farben der Rueckmeldung (richtig /
   anderswo / fehlt) bleiben die des Spiels — sie sind die Regel. */
#game-view .wd-info { display: flex; gap: 8px; flex-wrap: wrap; margin: 8px 0 10px; }
#game-view .wd-info span {
  padding: 4px 10px; border-radius: 99px; border: 1px solid var(--line);
  background: var(--panel); font-size: 0.74rem; color: var(--muted);
}
#game-view .wd-info b { color: var(--ink); font-weight: 800; }
#game-view .wd-trikot {
  position: relative; margin: 0 auto 12px; max-width: 360px;
  padding: 26px 18px 18px;
  border-radius: 22px 22px 16px 16px;
  background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.035) 0 6px, transparent 6px 12px),
    linear-gradient(180deg, rgba(var(--marke-rgb), 0.28), rgba(var(--marke-rgb), 0.10));
  border: 1px solid rgba(var(--marke-rgb), 0.35);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}
#game-view .wd-trikot__kragen {
  position: absolute; left: 50%; top: -1px; width: 64px; height: 18px; transform: translateX(-50%);
  border-radius: 0 0 32px 32px;
  background: var(--card); border: 1px solid rgba(var(--marke-rgb), 0.35); border-top: 0;
}
#game-view .wd-trikot__brett { display: flex; flex-direction: column; align-items: center; gap: 6px; }
#game-view .wd-trikot .wordle-row { justify-content: center; margin: 0; width: 100%; }
#game-view .wd-trikot .wordle-cell {
  border-radius: 8px; border: 1.5px solid rgba(255, 255, 255, 0.16);
  background: rgba(0, 0, 0, 0.22);
  font-family: var(--font-display); font-weight: 900; letter-spacing: 0;
  color: #fff; text-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
}
#game-view .wd-trikot .wordle-cell.correct { background: var(--correct); border-color: var(--correct); color: var(--on-solid); text-shadow: none; }
#game-view .wd-trikot .wordle-cell.present { background: var(--present); border-color: var(--present); color: var(--on-solid); text-shadow: none; }
#game-view .wd-trikot .wordle-cell.absent { background: var(--absent); border-color: var(--absent); color: var(--text); }
#game-view #wordle-giveup { margin-top: 8px; padding: 7px 16px; font-size: 0.82rem; }

@media (max-width: 560px) {
  #game-view .wd-info { margin: 4px 0 8px; }
  #game-view .wd-trikot { padding: 22px 14px 14px; }
  #game-view .wd-trikot .wordle-row .wordle-cell { max-width: 40px; }
}

/* ---- Spielerpass, Spielstaette & Co.: ein Pass statt einer Liste ---------
   (28.09.2026) Alle Breiten fuer die Akte, das Telefon fuer die Tafel.
   Die Akte sieht aus wie die Datenseite eines Passes: farbiges Kopfband in
   der Spielfarbe, die Felder in zwei Spalten (Bezeichnung klein darueber),
   unten die Maschinenzeile. Das Grundprinzip — Akte oben, Tipps darunter,
   Eingabe, Versuchspunkte — bleibt wie bei allen Ratespielen. */
#game-view .rate-akte {
  position: relative; overflow: hidden;
  margin: 10px 0 12px; padding: 0 0 10px;
  border-left-width: 1px; border-radius: 14px;
}
#game-view .rate-akte-kopf {
  display: flex; align-items: center; justify-content: space-between;
  margin: 0 0 8px; padding: 7px 12px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--rate-ton) 34%, transparent), transparent);
  color: var(--rate-ton); letter-spacing: 0.14em;
}
#game-view .rate-akte-kopf::after { content: "RIVALZ"; font-size: 0.56rem; letter-spacing: 0.3em; opacity: 0.7; color: var(--muted); }
#game-view .rate-akte-liste { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; margin: 0; padding: 0 12px; }
#game-view .rate-akte-zeile { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-size: 0.84rem; }
#game-view .rate-akte-zeile dt { font-size: 0.56rem; }
#game-view .rate-akte-zeile dd { overflow-wrap: anywhere; line-height: 1.25; }
/* Ein Feld mit langem Inhalt ("nicht Deutschland · nicht Argentinien")
   darf die ganze Breite nehmen, wenn es die erste Zeile ist. */
#game-view .rate-akte-zeile:first-child:not(.ist-offen) { grid-column: 1 / -1; }
#game-view .rate-akte::after {
  content: "P<RIVALZ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";
  display: block; margin: 9px 12px 0; overflow: hidden; white-space: nowrap;
  font: 600 0.58rem/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.18em;
  color: var(--muted); opacity: 0.45;
}

@media (max-width: 560px) {
  /* Name und Kacheln wieder in EINER Zeile: Die Kacheln werden kleiner (34),
     der Name darf auf zwei Zeilen umbrechen statt abgeschnitten zu werden —
     dann bleibt er lesbar, und sechs Tipps passen auf den Bildschirm. */
  #game-view .rate-reihe,
  #game-view .rate-kopfzeile { grid-template-columns: minmax(0, 1fr) auto; gap: 8px; padding: 5px 8px; }
  #game-view .rate-reihe { border-radius: 10px; }
  #game-view .rate-name { font-size: 0.76rem; line-height: 1.2; white-space: normal;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
  #game-view .rate-name--kopf { display: block; font-size: 0.55rem; }
  #game-view .rate-kacheln { gap: 3px; justify-content: flex-end; }
  #game-view .rate-kachel { width: 34px; height: 34px; font-size: 0.64rem; border-radius: 8px; }
  #game-view .rate-feldname { width: 34px; font-size: 0.5rem; }
  #game-view .rate-liste { gap: 4px; }
  #game-view .rate-tafel { margin-bottom: 10px; }
  #game-view .rate-akte-zeile { font-size: 0.8rem; }
  #game-view .rate-fuss { margin-top: 6px; }
  /* Die Filter im Endlosmodus nebeneinander — dieselbe Regel wie in der
     Flugroute (.cp-filters oben). */
}

#game-view .rate-fuss #rate-giveup { margin: 0 0 0 auto; padding: 6px 14px; font-size: 0.8rem; min-height: 34px; }
@media (max-width: 560px) {
  /* Offene Felder der Akte stehen am Telefon nicht als Zeile "noch offen" da
     — die Spaltenkoepfe der Tafel sagen schon, was es zu erfahren gibt. Die
     Akte waechst mit dem, was man weiss. */
  #game-view .rate-akte-zeile.ist-offen { display: none; }
  #game-view .rate-akte:not(:has(.rate-akte-zeile:not(.ist-offen))) .rate-akte-liste { display: none; }
  #game-view .rate-akte:not(:has(.rate-akte-zeile:not(.ist-offen))) .rate-akte-kopf { margin-bottom: 0; }
}

/* ---- Rangfolge: die Aufgabe als Karte, die Liste schmaler (28.09.2026) ---- */
#game-view .rank-aufgabe {
  display: flex; flex-direction: column; gap: 2px;
  margin: 10px 0 10px; padding: 10px 14px;
  border-radius: 14px; border: 1px solid rgba(var(--marke-rgb), 0.35);
  background: linear-gradient(135deg, rgba(var(--marke-rgb), 0.16), rgba(var(--marke-rgb), 0.04));
}
#game-view .rank-aufgabe__label {
  font-size: 0.6rem; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}
#game-view .rank-aufgabe__was { font-size: 1.15rem; font-weight: 800; color: var(--ink); line-height: 1.2; }
#game-view .rank-aufgabe__wie { font-size: 0.78rem; font-weight: 700; color: var(--violet-text); }
#game-view .rank-aufgabe__wie::before { content: "↓ "; }

@media (max-width: 560px) {
  /* "Zieh die Eintraege ... oder nutze die Pfeile" — am Telefon zeigen es
     der Griff links und die Pfeile rechts selbst. */
  #game-view .rank-ziehhinweis { display: none; }
  #game-view .rank-list { gap: 5px; }
  #game-view .rank-row { min-height: 46px; padding: 5px 8px; gap: 6px; border-radius: 12px; }
  #game-view .rank-name { font-size: 0.86rem; line-height: 1.2; }
  #game-view .rank-pos { font-size: 0.82rem; }
  #game-view .rank-btn { width: 30px; height: 30px; }
  #game-view .rank-loesung { margin-top: 10px; }
}

/* ---- Kaderbau: der Startbildschirm als Saisonplan (28.09.2026) ----------- */
#game-view .kb-fakten {
  list-style: none; margin: 12px 0 10px; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
}
#game-view .kb-fakten li {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-height: 76px; padding: 10px 6px; text-align: center;
  border-radius: 14px; border: 1px solid var(--line); background: var(--panel);
}
#game-view .kb-fakten b { font-size: 1.45rem; font-weight: 900; color: var(--ink); line-height: 1; letter-spacing: -0.02em; }
#game-view .kb-fakten b i { font-style: normal; color: var(--violet-text); margin: 0 3px; font-size: 0.8em; }
#game-view .kb-fakten span { font-size: 0.62rem; font-weight: 700; letter-spacing: 0.04em; color: var(--muted); line-height: 1.25; }
/* Die Saisonleiter: fuenf Stufen auf einer Linie, das Ziel steigt nach rechts. */
#game-view .kb-leiter { margin: 0 0 14px; }
#game-view .kb-leiter__titel { display: block; margin-bottom: 8px; font-size: 0.62rem; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
#game-view .kb-leiter__stufen {
  position: relative; list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
}
#game-view .kb-leiter__stufen::before {
  content: ""; position: absolute; left: 10%; right: 10%; top: 11px; height: 2px;
  background: linear-gradient(90deg, rgba(var(--marke-rgb), 0.35), var(--color-accent-text, #FFC53D));
}
#game-view .kb-leiter__stufen li { position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px; }
#game-view .kb-leiter__stufen i {
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  font-style: normal; font-size: 0.72rem; font-weight: 800;
  background: var(--card); border: 2px solid rgba(var(--marke-rgb), 0.55); color: var(--ink);
}
#game-view .kb-leiter__stufen li:last-child i { border-color: var(--color-accent-text, #FFC53D); }
#game-view .kb-leiter__stufen b { font-size: 0.82rem; font-weight: 800; color: var(--ink); font-variant-numeric: tabular-nums; }

@media (max-width: 560px) {
  /* Der Einfuehrungssatz steht im i; am Telefon tragen die Kacheln. */
  #game-view .kb-intro { display: none; }
  #game-view .kb-buehne { gap: 10px; }
  #game-view .kb-buehne > .game-card #kb-start,
  #game-view .kb-buehne > .game-card #kb-fortsetzen { width: 100%; }
}

/* Kaderbau-Karten wie Sammelkarten: Staerke als Plakette oben rechts in der
   Farbe ihrer Hoehe, ein feiner Glanz ueber der Karte. Alle Breiten. */
#game-view .kb-karte {
  background:
    linear-gradient(160deg, rgba(255, 255, 255, 0.07), transparent 45%),
    var(--card);
}
#game-view .kb-staerke {
  top: 50%; transform: translateY(-50%); right: 8px;
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px;
  font-size: 0.82rem; font-weight: 900;
  background: rgba(var(--marke-rgb), 0.16); color: var(--violet-text);
  border: 1px solid rgba(var(--marke-rgb), 0.35);
}
@media (max-width: 560px) {
  #game-view .kb-karte { min-height: 44px; padding: 6px 40px 6px 10px; }
  #game-view .kb-name { font-size: 0.86rem; }
  #game-view #kb-abbrechen, #game-view .kb-abbrechen { padding: 6px 14px; font-size: 0.8rem; min-height: 34px; }
}

/* ---- Abseits: der Aufbau auf einen Bildschirm (28.09.2026) ---------------
   Mitspieler und "im Abseits" nebeneinander, die Chips einer Frage in einer
   Reihe, die Erklaersaetze klein. Alle Breiten fuer das Paar. */
#game-view .impo-paar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
#game-view .impo-paar .impo-stepper { width: 100%; max-width: none; }
@media (max-width: 560px) {
  #game-view .impo-einleitung { display: none; }
  #game-view .impo-feld { margin-top: 12px; }
  #game-view .impo-label { font-size: 0.62rem; margin-bottom: 5px; }
  #game-view .impo-stepper { min-height: 42px; }
  #game-view .impo-step { width: 34px; height: 34px; }
  #game-view .impo-wert { font-size: 1.15rem; }
  #game-view .impo-chips { flex-wrap: nowrap; gap: 6px; }
  #game-view .impo-chip { flex: 1 1 0; min-width: 0; min-height: 38px; padding: 6px 8px; font-size: 0.8rem; white-space: nowrap; }
  #game-view .impo-feld .hint { font-size: 0.7rem; margin: 5px 0 0; line-height: 1.35; }
  #game-view .impo-feld + .hint { font-size: 0.72rem; margin: 10px 0 4px; }
}

/* ---- Der Weg nach oben: die Leiter als Aufstiegsbalken (28.09.2026) -------
   Am Telefon stand die Leiter als Raster aus fuenf Stufen UNTER dem Spiel,
   und die vierte Joker-Taste lief seitlich aus dem Bild. Jetzt steht ueber der
   Frage ein Balken aus allen Stufen — unten links die A-Klasse, rechts der
   Weltmeister, die aktuelle leuchtet, die Netze tragen einen goldenen Rand —
   und darunter in Worten, wo man steht. Die Joker stehen als vier gleich
   breite Tasten in einer Reihe. */
@media (max-width: 560px) {
  #game-view .quiz-raum { display: flex; flex-direction: column; gap: 10px; }
  #game-view .quiz-leiter {
    order: -1; display: flex; flex-direction: row-reverse; gap: 3px;
    align-self: stretch; width: 100%; padding-top: 2px;
  }
  #game-view .quiz-stufe,
  #game-view .quiz-stufe.aktuell,
  #game-view .quiz-stufe.sicher,
  #game-view .quiz-stufe.aktuell + .quiz-stufe,
  #game-view .quiz-stufe:has(+ .quiz-stufe.aktuell) {
    display: block; flex: 1 1 0; height: 8px; padding: 0; border-radius: 99px;
    background: var(--line); box-shadow: none;
  }
  #game-view .quiz-stufe > * { display: none; }
  #game-view .quiz-stufe.erledigt { background: var(--correct-text); }
  #game-view .quiz-stufe.sicher { box-shadow: inset 0 0 0 1.5px var(--present-text); }
  #game-view .quiz-stufe.aktuell { background: var(--violet); height: 12px; margin-top: -2px; box-shadow: 0 0 0 2px rgba(var(--marke-rgb), 0.3); }
  #game-view .quiz-kopf { margin: 0; }
  #game-view .quiz-liga { font-size: 1.3rem; }
  #game-view .quiz-frage { font-size: 1rem; margin: 6px 0 10px; line-height: 1.35; }
  #game-view .quiz-antworten { gap: 7px; }
  #game-view .quiz-antwort { min-height: 44px; padding: 7px 12px; font-size: 0.92rem; }
  #game-view .quiz-buchstabe { width: 24px; height: 24px; font-size: 0.72rem; }
  #game-view .quiz-joker-reihe {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-top: 10px; overflow: visible;
  }
  #game-view .quiz-joker { min-width: 0; min-height: 40px; padding: 6px 4px; }
  #game-view .quiz-joker-name { font-size: 0.66rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
  #game-view .quiz-fuss { margin-top: 10px; padding-top: 8px; }
}

/* ---- Der Abschluss nach dem Tagesraetsel, am Telefon (28.09.2026) --------
   "Weniger Text, verpasste Tage nachholen soll man sehen." Die zwei
   Erklaersaetze fallen weg, der Wochenrueckblick wird eine Zeile, und die
   sieben Tage zum Nachholen stehen als EINE Reihe kleiner Kacheln — offen
   in der Markenfarbe umrandet, gespielt gedaempft mit Haken oder Kreuz. */
@media (max-width: 560px) {
  #game-view .ta-unterzeile, #game-view .ta-blockhinweis { display: none; }
  #game-view .ta-marke { font-size: 0.6rem; margin-top: 4px; }
  #game-view .ta-titel { font-size: 1.3rem; margin: 2px 0 8px; }
  #game-view .ta-ergebnis { margin: 0 0 8px; font-size: 0.86rem; }
  #game-view .ta-block { padding: 10px 12px; margin-bottom: 8px; border-radius: 14px; }
  #game-view .ta-blocktitel { font-size: 0.6rem; margin-bottom: 8px; }
  #game-view .ta-felder { gap: 5px; margin-bottom: 6px; }
  #game-view .ta-felder .ta-feld { width: 22px; height: 22px; border-radius: 6px; }
  #game-view .ta-zahlen { font-size: 0.74rem; gap: 12px; }
  /* Sieben Tage in EINER Reihe, bei jedem Spiel (29.09.2026, Ansage des
     Eigentuemers: "wie bei Kopf an Kopf, kompakt"). Mit :has, weil Die Elf
     sonst ueber die speziellere Regel oben auf zwei Spalten fiel. */
  #game-view .ta-tage,
  #game-view .ta-tage:has(.ta-tag__aufgabe) { grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
  #game-view .ta-tag { min-height: 46px; padding: 5px 2px; gap: 2px; border-radius: 10px; }
  #game-view .ta-tag b { font-size: 0.66rem; }
  #game-view .ta-tag span { font-size: 0.54rem; }
  #game-view .ta-tag__aufgabe { display: none; }
  #game-view .tagesabschluss .cp-actions { margin-top: 10px; }
  #game-view .tagesabschluss .cp-actions .action,
  #game-view .tagesabschluss .cp-actions .secondary { flex: 1 1 0; min-height: 40px; padding: 8px 10px; font-size: 0.86rem; }
}
}

/* ==========================================================================
   ZWEITE RUNDE AM TELEFON (29.09.2026) — nur bis 560 px, am Laptop gilt das
   alte Design. Kopf an Kopf, Beflockung, die Ratespiele, Kaderbau, Abseits.
   ========================================================================== */
@media (max-width: 560px) {
  /* ---- Kopf an Kopf, Tages-Challenge: das Duell als Bild ---------------- */
  #game-view .cmp-tages-hero {
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px;
    margin: 12px 0 4px; padding: 16px 14px;
    border-radius: 18px; overflow: hidden; position: relative;
    background:
      radial-gradient(circle at 50% 50%, rgba(var(--marke-rgb), 0.28), transparent 60%),
      linear-gradient(135deg, rgba(var(--marke-rgb), 0.10), rgba(255, 197, 61, 0.08));
    border: 1px solid rgba(var(--marke-rgb), 0.3);
  }
  #game-view .cmp-tages-hero__seite {
    display: grid; place-items: center; aspect-ratio: 1; width: 100%; max-width: 104px; justify-self: center;
    border-radius: 50%; border: 2px dashed rgba(255, 255, 255, 0.28);
    background: rgba(0, 0, 0, 0.22);
    font: 900 2.4rem/1 var(--font-display); color: rgba(255, 255, 255, 0.55);
  }
  #game-view .cmp-tages-hero__vs {
    font: 900 italic 1.6rem/1 var(--font-display); letter-spacing: -0.04em; color: var(--violet-text);
    text-shadow: 0 0 18px rgba(var(--marke-rgb), 0.5);
  }
  #game-view .cmp-tages-kacheln { margin-top: 10px; }
  #game-view .cmp-tages-kacheln li { min-height: 84px; }
  #game-view .cmp-tages-ablauf {
    counter-reset: ablauf; list-style: none; margin: 12px 0 4px; padding: 0;
    display: grid; gap: 7px;
  }
  #game-view .cmp-tages-ablauf li {
    counter-increment: ablauf; display: flex; align-items: center; gap: 10px;
    font-size: 0.82rem; color: var(--text); line-height: 1.3;
  }
  #game-view .cmp-tages-ablauf li::before {
    content: counter(ablauf); flex: none; display: grid; place-items: center;
    width: 22px; height: 22px; border-radius: 50%;
    background: rgba(var(--marke-rgb), 0.16); color: var(--violet-text); font-size: 0.72rem; font-weight: 800;
  }

  /* ---- Beflockung: das Brett auf dem Rasen, jede Zeile mit Nummer -------- */
  #game-view .wd-platz {
    position: relative; isolation: isolate; overflow: hidden;
    margin: 4px 0 12px; padding: 18px 12px;
    border-radius: 18px; border: 1px solid rgba(255, 255, 255, 0.12);
    background:
      radial-gradient(ellipse at 50% 40%, rgba(255, 255, 255, 0.10), transparent 65%),
      repeating-linear-gradient(90deg, #1d6b3a 0 34px, #1a6135 34px 68px);
    box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.35);
  }
  #game-view .wd-platz__linien {
    position: absolute; inset: 6px; width: calc(100% - 12px); height: calc(100% - 12px); z-index: -1;
    color: rgba(255, 255, 255, 0.35);
  }
  #game-view .wd-platz__brett { display: flex; flex-direction: column; align-items: center; gap: 6px; }
  #game-view .wd-platz .wordle-row { display: flex; align-items: center; justify-content: center; gap: 5px; margin: 0; width: 100%; }
  /* Feste Felder: Die allgemeine Regel laesst sie schrumpfen (flex 1 1 0) —
     in einer Zeile ohne feste Breite schrumpften sie hier auf Nichts. Bis
     neun Buchstaben passen 32 px nebeneinander, darueber werden sie
     schmaler. */
  #game-view .wd-platz .wordle-row .wordle-cell { flex: 0 1 36px; width: 36px; height: auto; aspect-ratio: 1; min-width: 22px; }
  #game-view .wd-nr {
    flex: none; width: 22px; text-align: right; margin-right: 3px;
    font: 900 0.86rem/1 var(--font-display); color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  }
  #game-view .wd-leer .wd-nr { color: rgba(255, 255, 255, 0.4); }
  #game-view .wd-platz .wordle-row .wordle-cell {
    max-width: 40px; border-radius: 7px; font-size: 1rem;
    border: 1.5px solid rgba(255, 255, 255, 0.35);
    background: rgba(255, 255, 255, 0.94); color: #0b1f12;
    font-family: var(--font-display); font-weight: 900;
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.25);
  }
  #game-view .wd-platz .wd-leer .wordle-cell { background: rgba(4, 20, 10, 0.35); border-color: rgba(255, 255, 255, 0.22); box-shadow: none; }
  #game-view .wd-platz .wordle-cell.correct { background: var(--correct); border-color: #fff; color: var(--on-solid); }
  #game-view .wd-platz .wordle-cell.present { background: var(--present); border-color: #fff; color: var(--on-solid); }
  #game-view .wd-platz .wordle-cell.absent { background: #3a4540; border-color: rgba(255, 255, 255, 0.25); color: #fff; }

  /* ---- Ratespiele: die Kategorien untereinander, von Anfang an ----------
     "Am Anfang ist zu wenig, nach dem ersten Tipp die Kategorien
     untereinander." Jede Kategorie ist eine Zeile — links der Name, rechts
     was man weiss, offen steht "?" statt eines kursiven Satzes. */
  #game-view .rate-akte-zeile.ist-offen { display: flex; }
  #game-view .rate-akte:not(:has(.rate-akte-zeile:not(.ist-offen))) .rate-akte-liste { display: grid; }
  #game-view .rate-akte:not(:has(.rate-akte-zeile:not(.ist-offen))) .rate-akte-kopf { margin-bottom: 8px; }
  #game-view .rate-akte-liste { grid-template-columns: 1fr; gap: 0; }
  #game-view .rate-akte-zeile,
  #game-view .rate-akte-zeile:first-child:not(.ist-offen) {
    grid-column: auto; flex-direction: row; align-items: baseline; justify-content: space-between; gap: 12px;
    padding: 7px 0; border-top: 1px solid var(--line);
  }
  #game-view .rate-akte-zeile:first-child { border-top: 0; }
  #game-view .rate-akte-zeile dt { flex: none; font-size: 0.6rem; }
  #game-view .rate-akte-zeile dd { text-align: right; font-size: 0.84rem; }
  #game-view .rate-akte-zeile.ist-offen dd { font-size: 0; }
  #game-view .rate-akte-zeile.ist-offen dd::after { content: "?"; font-size: 0.9rem; font-style: normal; color: var(--muted); }

  /* ---- Kaderbau: Anzeigetafel, Spielfeld, Hand ------------------------ */
  #game-view .kbh .game-card { padding: 12px; }
  #game-view .kbh-tafel {
    display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 4px 10px;
    padding: 10px 12px; border-radius: 14px; background: #0c1410; border: 1px solid var(--line);
    font-variant-numeric: tabular-nums;
  }
  #game-view .kbh-tafel b { color: #fff; }
  #game-view .kbh-runde, #game-view .kbh-gesamt { font-size: 0.72rem; color: var(--muted); font-weight: 700; }
  #game-view .kbh-ziel { text-align: center; font-size: 0.9rem; color: var(--muted); }
  #game-view .kbh-ziel b { font-size: 1.35rem; font-weight: 900; color: var(--violet-text); }
  #game-view .kbh-balken { grid-column: 1 / -1; height: 5px; border-radius: 99px; background: var(--line); overflow: hidden; }
  #game-view .kbh-balken i { display: block; height: 100%; background: linear-gradient(90deg, var(--violet), var(--color-accent-text, #FFC53D)); }
  #game-view .kbh-feld {
    margin: 10px 0; padding: 12px 8px 10px; border-radius: 16px;
    background:
      radial-gradient(ellipse at 50% 0%, rgba(255, 255, 255, 0.10), transparent 60%),
      repeating-linear-gradient(90deg, #1d6b3a 0 30px, #1a6135 30px 60px);
    border: 1px solid rgba(255, 255, 255, 0.12);
  }
  #game-view .kbh-plaetze { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 5px; }
  #game-view .kbh-platz {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    min-height: 70px; padding: 6px 3px; border-radius: 10px;
    border: 1.5px dashed rgba(255, 255, 255, 0.35); background: rgba(0, 0, 0, 0.15);
    color: rgba(255, 255, 255, 0.5); font: inherit;
  }
  #game-view .kbh-platz i { font-style: normal; font-weight: 800; font-size: 0.8rem; }
  #game-view .kbh-platz.is-voll {
    border: 1.5px solid #fff; background: rgba(255, 255, 255, 0.95); color: #0b1f12; cursor: pointer;
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.3);
  }
  #game-view .kbh-platz.is-voll b {
    display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
    background: #0b1f12; color: #fff; font-size: 0.78rem; font-weight: 900;
  }
  #game-view .kbh-platz.is-voll span {
    max-width: 100%; font-size: 0.6rem; font-weight: 800; line-height: 1.1; text-align: center;
    overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  }
  #game-view .kbh-rechnung { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; color: #fff; }
  #game-view .kbh-kombo { font-size: 0.86rem; font-weight: 800; }
  #game-view .kbh-kombo.leer { font-weight: 600; opacity: 0.75; font-size: 0.78rem; }
  #game-view .kbh-formel { display: inline-flex; align-items: center; gap: 4px; font-variant-numeric: tabular-nums; }
  #game-view .kbh-formel .kb-wert { min-width: 30px; padding: 3px 6px; border-radius: 7px; font-size: 0.86rem; text-align: center; }
  #game-view .kbh-formel .kb-mal { font-size: 0.8rem; opacity: 0.8; }
  #game-view .kbh-punkte strong { font-size: 1.2rem; font-weight: 900; }
  #game-view .kbh-hand { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  #game-view .kbh-hand .kb-karte { min-height: 42px; padding: 6px 38px 6px 10px; border-radius: 10px; }
  #game-view .kbh-knoepfe { display: grid; grid-template-columns: 1fr 1fr auto; gap: 8px; margin-top: 10px; }
  #game-view .kbh-knoepfe .action { margin: 0; min-height: 42px; padding: 8px 10px; font-size: 0.9rem; }
  #game-view .kbh-knoepfe .action small { margin-left: 4px; font-size: 0.72rem; opacity: 0.75; }
  #game-view .kbh-abbruch {
    width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--line);
    background: transparent; color: var(--muted); font-size: 1.2rem; cursor: pointer;
  }
  #game-view .kbh-fuss { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-top: 10px; font-size: 0.74rem; color: var(--muted); }
  #game-view .kbh-kombos { text-align: right; }
  #game-view .kbh-kombos summary { cursor: pointer; font-weight: 800; color: var(--violet-text); list-style: none; }
  #game-view .kbh-kombos summary::after { content: " ▾"; }
  #game-view .kbh-kombos[open] summary::after { content: " ▴"; }
  #game-view .kbh-kombos .kb-kombos { margin-top: 8px; text-align: left; }
  #game-view .kbh-fuss:has(.kbh-kombos[open]) { flex-direction: column; }
  #game-view .kbh-fuss:has(.kbh-kombos[open]) .kbh-kombos { width: 100%; }

  /* ---- Abseits im Kleid der Duell-Einstellung ------------------------------ */
  #game-view .impo-handy .duell-setup { gap: 14px; }
  #game-view .impo-handy .cmp-seg { width: 100%; }
  #game-view .impo-handy .cmp-seg-btn { flex: 1 1 0; min-width: 0; min-height: 40px; font-size: 0.84rem; }
  #game-view .impo-handy .cmp-seg-btn.active { background: rgba(var(--marke-rgb), 0.18); color: var(--violet-text); }
  #game-view .impo-zahl { align-items: center; }
  #game-view .impo-zahl .cmp-seg-btn { flex: 0 0 44px; font-size: 1.15rem; }
  #game-view .impo-zahl__wert { flex: 1; text-align: center; font-size: 1.25rem; font-weight: 800; color: var(--ink); }
  #game-view .impo-handy .impo-anzahl { font-style: normal; margin-left: 5px; font-size: 0.72rem; opacity: 0.7; }
  #game-view .impo-handy__hinweis { display: block; margin-top: 6px; font-size: 0.7rem; line-height: 1.35; color: var(--muted); }
  #game-view .impo-handy .duell-feld > span em { font-style: normal; font-weight: 600; text-transform: none; letter-spacing: 0; opacity: 0.75; margin-left: 6px; }
  #game-view .impo-handy__topf { margin: 0; font-size: 0.74rem; color: var(--muted); text-align: center; }
  #game-view .impo-handy #impo-start { width: 100%; margin: 0; }
}
@media (max-width: 560px) {
  /* Sechs Tipps und die volle Akte muessen zusammen passen: gemessen 826 px
     nach fuenf Tipps. Die Maschinenzeile faellt am Telefon weg, Akte und
     Tipp-Zeilen werden je ein paar Pixel flacher. */
  #game-view .rate-akte::after { display: none; }
  #game-view .rate-akte { padding-bottom: 4px; margin: 8px 0 10px; }
  #game-view .rate-akte-kopf { padding: 6px 12px; margin-bottom: 2px; }
  #game-view .rate-akte-zeile,
  #game-view .rate-akte-zeile:first-child:not(.ist-offen) { padding: 5px 0; }
  #game-view .rate-akte-zeile dd { font-size: 0.8rem; }
  #game-view .rate-reihe { padding: 3px 7px; }
  #game-view .rate-kachel { width: 32px; height: 32px; }
  #game-view .rate-feldname { width: 32px; }
  #game-view .rate-kopfzeile { margin-bottom: 3px; }
  #game-view .rate-tafel { margin-bottom: 8px; }
}
@media (max-width: 560px) {
  /* Platz ist da (gemessen 533 px mit zugeklappten Kombos): Feld und Hand
     duerfen groesser werden, die Kombotabelle steht offen — sie ist die
     Anleitung, und man klappt sie zu, wenn man sie kennt. */
  #game-view .kbh-platz { min-height: 86px; }
  #game-view .kbh-hand .kb-karte { min-height: 48px; }
  #game-view .kbh-kombos .kb-kombos { padding: 8px 10px; }
  #game-view .kbh-kombos .kb-komboliste { gap: 2px 10px; }
}
@media (max-width: 560px) {
  #game-view .kbh-fuss { margin-top: 8px; justify-content: flex-end; }
  #game-view .kbh-kombos .kb-kombos__titel { display: none; }
  #game-view .kbh-kombos .kb-kombos { margin-top: 6px; }
}
@media (max-width: 560px) {
  #game-view .impo-zahl .cmp-seg-btn { display: grid; place-items: center; line-height: 1; padding: 0; }
}

/* ---- Profil: Freunde einladen, unter den vier Kacheln (29.09.2026) ------- */
@media (max-width: 560px) {
  #game-view .profil-freunde {
    grid-column: 1 / -1; display: grid; grid-template-columns: 1fr auto; gap: 8px;
  }
  #game-view .profil-freunde__einladen {
    display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 10px 14px;
    border-radius: 18px; border: 1px solid rgba(var(--marke-rgb), 0.45);
    background: linear-gradient(135deg, rgba(var(--marke-rgb), 0.22), rgba(var(--marke-rgb), 0.06));
    color: var(--text); font: inherit; text-align: left; cursor: pointer;
  }
  #game-view .profil-freunde__einladen b { display: block; font-size: 0.98rem; color: var(--ink); }
  #game-view .profil-freunde__einladen small { display: block; font-size: 0.7rem; color: var(--muted); margin-top: 2px; }
  #game-view .profil-freunde__symbol {
    flex: none; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%;
    background: var(--violet); color: var(--on-solid); font-size: 1.4rem; font-weight: 800; line-height: 1;
  }
  #game-view .profil-freunde__liste {
    min-height: 64px; padding: 0 16px; border-radius: 18px; border: 1px solid var(--line);
    background: var(--panel); color: var(--text); font: inherit; font-weight: 800; font-size: 0.86rem; cursor: pointer;
  }
}

/* ==========================================================================
   Flugroute am Telefon: Stationen links, Karte rechts, ein Bildschirm
   (29.09.2026). Die Hoehe von .cp-feld setzt cpFeldAnpassen() in
   careerpath.js nach Messung; hier steht nur die Aufteilung. Nur bis 560 px,
   am Laptop gilt das alte Layout — die Klassen gibt es dort gar nicht.
   ========================================================================== */
@media (max-width: 560px) {
  #game-view .cp-card--handy .cp-feld {
    display: grid;
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    gap: 8px;
    height: 300px;
    margin: 8px 0 6px;
  }
  #game-view .cp-feld__liste { display: flex; flex-direction: column; min-height: 0; }
  #game-view .cp-card--handy .cp-stations-head { margin: 0 0 5px; font-size: 0.64rem; }
  #game-view .cp-hstationen {
    display: flex; flex-direction: column; gap: 4px;
    overflow-y: auto; min-height: 0; flex: 1 1 auto;
    scrollbar-width: none;
  }
  #game-view .cp-hstationen::-webkit-scrollbar { display: none; }
  #game-view .cp-hstation {
    display: grid; grid-template-columns: 16px minmax(0, 1fr); gap: 0 6px;
    padding: 5px 7px; border-radius: 10px;
    background: var(--panel); border: 1px solid var(--line);
  }
  #game-view .cp-hstation.is-new { border-color: rgba(var(--violet-rgb), 0.6); animation: fadeUp 0.35s ease both; }
  #game-view .cp-hstation__nr {
    grid-row: 1 / 3; align-self: center;
    width: 16px; height: 16px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--violet); color: var(--on-solid);
    font-size: 0.58rem; font-weight: 800;
  }
  #game-view .cp-hstation__club {
    font-size: 0.72rem; font-weight: 700; line-height: 1.2;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-clamp: 2; overflow: hidden;
  }
  #game-view .cp-hstation__meta { font-size: 0.6rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  #game-view .cp-card--handy .cp-aufdecken { display: block; margin: 6px 0 0; flex: none; }
  #game-view .cp-card--handy .cp-aufdecken .action { width: 100%; min-height: 36px; padding: 6px 8px; font-size: 0.72rem; line-height: 1.2; }
  #game-view .cp-feld__karte {
    position: relative; min-height: 0;
    border-radius: 14px; overflow: hidden;
    background: #0C1A24; border: 1px solid var(--line);
  }
  #game-view .cp-feld__karte .cp-map { width: 100%; height: 100%; max-height: none; display: block; }
  #game-view .cp-feld__km {
    position: absolute; left: 6px; bottom: 6px;
    padding: 2px 7px; border-radius: 999px;
    background: rgba(4, 7, 6, 0.7); color: var(--orange-text, var(--orange));
    font-size: 0.6rem; font-weight: 700;
  }
  /* Kopf und Eingabe enger, damit die Karte die Hoehe bekommt. */
  #game-view .cp-card--handy .cp-question { font-size: 0.86rem; margin: 2px 0 5px; }
  #game-view .cp-card--handy .input-row input,
  #game-view .cp-card--handy .input-row button { min-height: 40px; padding-block: 8px; }
  #game-view .cp-card--handy .cp-lives-bar { display: flex; width: 100%; box-sizing: border-box; margin: 6px 0 0; padding: 3px 4px 3px 12px; }
  #game-view .cp-card--handy .cp-lives-bar .cp-aufgeben { margin: 0 0 0 auto; padding: 5px 12px; min-height: 30px; font-size: 0.74rem; }
  #game-view .cp-card--handy .cp-shop-hint { margin-top: 4px; font-size: 0.64rem; }
  #game-view .cp-card--handy .cp-filters { margin-top: 4px; }
  /* Der Hinweis-Shop: vier kleine Knoepfe in einer Reihe statt vier grosser
     untereinander — er oeffnet sich nach dem ersten Fehlversuch und schob
     das Spiel sonst 200 px unter den Rand. */
  #game-view .cp-card--handy .cp-hint-shop { margin-top: 6px; padding: 6px 8px; }
  #game-view .cp-card--handy .cp-shop-label { font-size: 0.58rem; margin-bottom: 5px; }
  #game-view .cp-card--handy .cp-shop-items { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px; }
  #game-view .cp-card--handy .cp-shop-btn { min-height: 38px; padding: 4px 3px; font-size: 0.62rem; line-height: 1.15; text-align: center; }
  #game-view .cp-card--handy .cp-shop-btn span { font-size: 0.52rem; }
  #game-view .cp-card--handy .cp-shop-btn { overflow-wrap: anywhere; hyphens: auto; }
  #game-view .cp-card--handy #cp-result { font-size: 0.72rem; margin-top: 5px; padding: 6px 10px; }
  #game-view .cp-card--handy #cp-result:empty { display: none; }
  #game-view .cp-card--handy .cp-hints { margin: 0 0 5px; gap: 4px; }
  #game-view .cp-card--handy .cp-hint-chip { font-size: 0.66rem; padding: 3px 8px; }
}
