/* ══════════════════════════════════════════════════════════════════════════
   GLUECKSPILZ - Aussehen.

   Dunkel, gruen, ein bisschen Gold: ein Kasino im Wald. Alles ist fuer ein
   Handy gebaut und waechst nach oben - keine Tabelle, die auf 390 Pixeln
   seitlich herauslaeuft (das misst `pruefe-rahmen.mjs` nach). Was breit ist -
   Auszahlungstafeln, das Nagelbrett, der Chart - scrollt in seinem eigenen
   Kasten und nicht im Dokument.

   Dieses Spiel traegt **kein** `lobby.css`: es hat keine Lobby und keinen
   Warteraum, und die gemeinsame Basis waere hier nur Ballast. Wie bei Ameisen,
   Revier und Wurm.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --gruen: #1db954;
  --gruen-hell: #35e07a;
  --gold: #f7c948;
  --rot: #ef4444;
  --grund: #0b1410;
  --grund2: #101d17;
  --karte: #16261e;
  --kante: #223a2d;
  --text: #e8f2ec;
  --grau: #8fa79a;
  --reiter-h: 60px;
  /* Breite der Reiterschiene, sobald sie links steht (ab 62rem). */
  --schiene: 13rem;
}

* { box-sizing: border-box; }

/**
 * `hidden` schlaegt jedes `display`.
 *
 * Ohne diese Zeile gewinnt `display: flex` auf `.tor` gegen das
 * `hidden`-Attribut: das Anmeldefenster ist dann unsichtbar (weil es nichts
 * ueberdeckt, was man saehe) und faengt trotzdem jeden Klick ab - der Knopf
 * darunter reagiert auf nichts. Genau das hat der erste Browserlauf gefunden,
 * und keine Serverprobe haette es je gesehen. Dieselbe Falle steht in
 * `doku/pruefen.md` fuer `.overlay`.
 */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--grund);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  overscroll-behavior: none;
}

/**
 * **Das Dokument scrollt nicht, die Buehne scrollt.**
 *
 * Vorher lief die ganze Seite: Kopfzeile klebte oben, Reiter klebten unten,
 * und dazwischen wuchs alles nach unten weg. Auf einem Handy hiess das, nach
 * jeder Runde erst zum Spielknopf zurueckzuwischen - der stand unter dem
 * Spielfeld und damit unter dem Bildschirmrand. Jetzt ist der Koerper eine
 * Spalte in Bildschirmhoehe, und nur `#buehne` in der Mitte scrollt. Was
 * darin steht, kann sich daran ausrichten (siehe `.spielraum`).
 *
 * Folge, die man kennen muss: `window.scrollTo` bewegt nichts mehr. Wer
 * hochscrollen will, muss `#buehne` scrollen - `zeigeSeite` in `app.js` tut
 * genau das.
 */
body {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  -webkit-tap-highlight-color: transparent;
}

h1, h2, h3 { margin: 0 0 .5rem; line-height: 1.2; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1rem; color: var(--gold); margin-top: 1.25rem; }
p { margin: .5rem 0; line-height: 1.5; }
code { font-size: .85em; background: #0007; padding: .1em .3em; border-radius: 4px; }

.klein { font-size: .8rem; }
.muted { color: var(--grau); }
.mitte { text-align: center; }
.hex { font-family: ui-monospace, "SF Mono", Menlo, monospace; word-break: break-all; font-size: .72rem; }

.noscript {
  max-width: 34rem;
  margin: 15vh auto;
  padding: 1.5rem;
  text-align: center;
}
.noscript a { color: var(--gruen-hell); }

/* ── Knoepfe ───────────────────────────────────────────────────────────── */

.btn {
  font: inherit;
  font-weight: 600;
  color: #08140e;
  background: linear-gradient(180deg, var(--gruen-hell), var(--gruen));
  border: 0;
  border-radius: 12px;
  padding: .6rem 1rem;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform .08s, filter .15s;
}
.btn:active { transform: scale(.96); }
.btn:disabled { opacity: .4; cursor: default; }
.btn.zweit { background: #1e3328; color: var(--text); box-shadow: inset 0 0 0 1px var(--kante); }
.btn.gefahr { background: linear-gradient(180deg, #ff6b6b, var(--rot)); color: #fff; }
.btn.gross { padding: .8rem 1.2rem; font-size: 1.05rem; }
/**
 * Der runde Knopf - Zurueck, Ton, Hilfe, Schliessen.
 *
 * `display: grid; place-content: center` ist hier kein Schmuck: ein Knopf
 * zentriert seinen Text zwar waagerecht, aber senkrecht richtet er sich nach
 * der Zeilenbox, und die haengt an den Ober- und Unterlaengen der Schrift.
 * Beim Pfeil `←` sitzt sie deutlich zu tief - der Pfeil stand in jedem
 * Spielkopf sichtbar unter der Mitte. `line-height: 1` nimmt der Zeilenbox
 * den Rest.
 */
.btn.rund {
  width: 40px; height: 40px; padding: 0; border-radius: 50%;
  background: #1e3328; color: var(--text); box-shadow: inset 0 0 0 1px var(--kante);
  font-size: 1.1rem; line-height: 1; flex: 0 0 auto;
  display: grid; place-content: center;
}

/**
 * Der Zurueck-Pfeil steht **gezeichnet** im Knopf, nicht als Schriftzeichen.
 *
 * Das Zeichen „←" (U+2190) sitzt in jeder Schrift woanders in seiner Zeile:
 * es haengt an der Grundlinie wie ein Buchstabe, seine Spitze liegt aber auf
 * der Mathematik-Achse. In einem 40 Pixel hohen Kreis sieht man diese paar
 * Pixel Versatz sofort, und keine Zentrierung des *Kastens* (`place-content`,
 * `line-height`) bekommt sie weg - zentriert wird die Zeile, nicht die Tinte.
 * Zweimal nachgebessert, zweimal blieb der Pfeil zu hoch.
 *
 * Ein SVG hat keine Grundlinie. `viewBox` und Kreuz liegen exakt in der
 * Mitte, und `display: block` nimmt dem Bild den Zeilenkasten, in dem sonst
 * wieder Platz fuer Unterlaengen freigehalten wuerde.
 */
.btn.rund svg { display: block; width: 18px; height: 18px; }

input[type="text"], input[type="password"], input[type="number"], select {
  font: inherit;
  width: 100%;
  background: #0c1712;
  color: var(--text);
  border: 1px solid var(--kante);
  border-radius: 10px;
  padding: .6rem .7rem;
}
input:focus, select:focus, .btn:focus-visible { outline: 2px solid var(--gruen-hell); outline-offset: 2px; }

/* ── Anmeldung ─────────────────────────────────────────────────────────── */

.tor {
  position: fixed; inset: 0; z-index: 60;
  background: radial-gradient(120% 90% at 50% 0%, #163024, var(--grund) 70%);
  overflow-y: auto;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 1.25rem;
}
.torblatt { width: 100%; max-width: 26rem; padding-bottom: 3rem; }
.marke { font-size: 2rem; text-align: center; letter-spacing: -.02em; }
.unterzeile { text-align: center; color: var(--grau); margin-top: -.25rem; }

.hinweiskasten {
  background: var(--karte);
  border: 1px solid var(--kante);
  border-left: 3px solid var(--gold);
  border-radius: 10px;
  padding: .75rem .9rem;
  margin: 1rem 0;
  font-size: .85rem;
}
.hinweiskasten p { margin: .4rem 0; }

.torfelder label { display: block; font-size: .8rem; color: var(--grau); margin: .8rem 0 .25rem; }
.torknoepfe { display: flex; gap: .6rem; margin-top: 1rem; }
.torknoepfe .btn { flex: 1; }
.fehler { color: #ffb4b4; background: #3a1414; border-radius: 8px; padding: .5rem .7rem; font-size: .85rem; }

.zurueck { display: block; text-align: center; margin-top: 1.5rem; color: var(--grau); text-decoration: none; }
.zurueck:hover { color: var(--gruen-hell); }
.sprachwahl { display: flex; gap: .4rem; justify-content: center; margin-top: 1.25rem; }
.sprachwahl:empty { display: none; }
.sprachwahl button {
  font: inherit; font-size: .8rem; padding: .3rem .6rem; border-radius: 8px;
  background: #1e3328; color: var(--grau); border: 1px solid var(--kante); cursor: pointer;
}
.sprachwahl button[aria-pressed="true"] { color: var(--gold); border-color: var(--gold); }

/* ── Kopf ──────────────────────────────────────────────────────────────── */

#kopf {
  flex: 0 0 auto; z-index: 30;
  display: flex; align-items: center; gap: .5rem;
  padding: .55rem .8rem;
  padding-top: max(.55rem, env(safe-area-inset-top));
  background: #0b1410ee;
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--kante);
}
.kasse { display: flex; align-items: center; gap: .4rem; font-size: 1.15rem; }
.kasse strong { font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.kasse.blitzt { animation: kassePuls .5s; }
@keyframes kassePuls { 50% { color: var(--gold); text-shadow: 0 0 12px #f7c94888; } }
.kopfrechts { margin-left: auto; display: flex; gap: .4rem; }

.wirkungen { display: flex; gap: .3rem; font-size: .9rem; }
.wirkung {
  background: #24401f; border: 1px solid var(--gold);
  border-radius: 999px; padding: .1rem .45rem; font-size: .75rem;
  display: flex; align-items: center; gap: .2rem;
}

/* ── Buehne und Seiten ─────────────────────────────────────────────────── */

#buehne {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: .8rem;
  max-width: 46rem;
  width: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}
.seite { display: none; }
.seite.an { display: block; animation: rein .18s ease-out; }

/* Zwei Reiter brauchen die volle Hoehe: "Spiele", weil dort unter dem
   Spielfeld eine Steuerung stehenbleiben soll - und "Druecken", weil der
   gruene Knopf ganz unten kleben muss, in Daumenreichweite. */
#sSpiele.an, #sDruecken.an { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
@keyframes rein { from { opacity: 0; transform: translateY(6px); } }

/* ── Der Knopf ─────────────────────────────────────────────────────────── */

/**
 * Der Knopf sitzt **unten**, nicht oben.
 *
 * Auf einem Handy erreicht der Daumen die untere Haelfte des Bildschirms,
 * nicht die obere - und dieser Knopf wird oefter gedrueckt als alles andere
 * im Haus. Deshalb steht im HTML jetzt erst die Zahlenreihe und dann das
 * Klickfeld, und das Klickfeld wird mit `margin-top: auto` an den unteren
 * Rand geschoben. Ueber dem Knopf steht die Schwungleiste, direkt darueber
 * der erklaerende Satz.
 *
 * `align-items: center` statt `text-align: center`: der Knopf ist ein
 * `display: grid`-Element und damit auf Blockebene - `text-align` erreicht
 * ihn nicht, er klebte am linken Rand.
 */
.klickfeld {
  /* Wie weit der Knopf beim Druecken einsinkt. Die Zahl steht hier und nicht
     unten bei `.knopf:active`, weil das Feld sie zweimal braucht: als Weg
     nach unten **und** als Platz darunter (siehe `padding`). */
  --druck: 8px;
  margin-top: auto;
  /* Unten genau der Weg, den der Knopf beim Druecken macht. Ohne diesen
     Platz waechst die Scroll-Flaeche von `#buehne` bei jedem Druck, und der
     Rollbalken blitzt auf. */
  padding: 1rem 0 var(--druck);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .8rem;
}
.klickfeld p { margin: 0; }

/**
 * Die Schwungleiste.
 *
 * Sie war 12 Pixel hoch und trug den Multiplikator als Text in sich - auf
 * zwoelf Pixeln stand eine Zeile von elf Pixeln Hoehe, und die Zahl war
 * abgeschnitten statt lesbar. Jetzt ist die Leiste 26 Pixel hoch, die Zahl
 * steht mittig darin und traegt einen Schatten, damit sie auch ueber dem
 * hellen Gold noch lesbar bleibt.
 */
.schwungbalken {
  position: relative;
  height: 26px; width: min(100%, 22rem); margin: 0 auto;
  background: #0c1712; border: 1px solid var(--kante); border-radius: 999px;
  overflow: hidden;
}
.schwungbalken i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--gruen), var(--gold));
  transition: width .12s linear;
}
.schwungbalken span {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: .82rem; font-weight: 800; letter-spacing: .02em;
  color: #f2fff7; text-shadow: 0 1px 2px #000c, 0 0 3px #000a;
  font-variant-numeric: tabular-nums;
}
/* Waehrend eines Blitzes (Klickwert x3) steht in der Leiste eine deutlich
   groessere Zahl - der Rand sagt, woher sie kommt. */
.schwungbalken.blitzt { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold), 0 0 12px #f7c94855; }

.knopf {
  position: relative;
  width: min(62vw, 15rem); aspect-ratio: 1;
  border: 0; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #3ef08a, #12a34a 55%, #0a6b30);
  box-shadow: 0 12px 0 #073d1c, 0 18px 30px #000a, inset 0 2px 12px #ffffff44;
  color: #06210f; cursor: pointer; touch-action: manipulation;
  display: grid; place-content: center; gap: .2rem;
  transition: transform .06s, box-shadow .06s;
}
.knopf:active { transform: translateY(var(--druck, 8px)); box-shadow: 0 4px 0 #073d1c, 0 8px 16px #000a, inset 0 2px 12px #ffffff44; }
.knopfsym { font-size: 3rem; line-height: 1; }
.knopftext { font-weight: 800; font-size: 1rem; letter-spacing: .04em; text-transform: uppercase; }

/**
 * Der Ring waechst als **Outline**, nicht als Kasten.
 *
 * Er lag frueher zehn Pixel ausserhalb des Knopfes (`inset: -10px`) und wuchs
 * per `transform: scale(1.25)`. Beides zaehlt zur Scroll-Flaeche von
 * `#buehne`: zusammen mit dem eingesunkenen Knopf wuchs sie bei jedem Druck
 * um bis zu 30 Pixel, ein Rollbalken erschien und verschwand wieder - einmal
 * je Knopfdruck, und dieser Knopf wird oefter gedrueckt als alles andere im
 * Haus. Gemeldet wurde genau das: "bei jedem Druecken entsteht ein
 * Scrollbalken".
 *
 * Eine `outline` mit wachsendem `outline-offset` sieht genauso aus, liegt
 * aber - wie ein Schatten - ausserhalb jeder Layout-Rechnung: sie vergroessert
 * keine Scroll-Flaeche. Deshalb sitzt der Ring jetzt buendig auf dem Knopf
 * (`inset: 0`) und waechst nur noch nach aussen gemalt. Geprueft in G20.
 */
.knopfring {
  position: absolute; inset: 0; border-radius: 50%;
  outline: 2px solid #35e07a55; outline-offset: 8px;
  opacity: 0;
}
.knopf.puls .knopfring { animation: ring .5s ease-out; }
@keyframes ring {
  from { opacity: 1; outline-offset: 8px; }
  to { opacity: 0; outline-offset: 40px; }
}

.zahlen { display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; margin-top: 1.5rem; }
.zahl {
  background: var(--karte); border: 1px solid var(--kante); border-radius: 12px;
  padding: .6rem .7rem; display: flex; flex-direction: column; gap: .15rem;
}
.zahl strong { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.zahl .klein { color: var(--grau); }

/* ── Spielraster ───────────────────────────────────────────────────────── */

.raster { display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); gap: .6rem; }
.spielkachel {
  background: linear-gradient(160deg, var(--karte), #12201a);
  border: 1px solid var(--kante); border-radius: 14px;
  padding: .9rem .7rem; text-align: center; cursor: pointer; color: var(--text);
  font: inherit; transition: transform .1s, border-color .15s;
}
.spielkachel:active { transform: scale(.97); }
.spielkachel:hover { border-color: var(--gruen); }
.spielkachel .sym { font-size: 2rem; display: block; }
.spielkachel .nam { font-weight: 700; margin-top: .3rem; display: block; }
.spielkachel .was { font-size: .72rem; color: var(--grau); display: block; margin-top: .2rem; }

.spielbuehne {
  animation: rein .18s ease-out;
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
}
.spielkopf { flex: 0 0 auto; display: flex; align-items: center; gap: .6rem; margin-bottom: .6rem; }
.spielkopf h2 { margin: 0; flex: 1; font-size: 1.15rem; }

/**
 * Ein offenes Spiel besteht aus zwei Kaesten: `.spielfeld` (das Spiel selbst
 * und seine Einstellungen) und `.steuerung` (Einsatz, Spielknopf, Auszahlen).
 *
 * **Nur das Feld scrollt.** Die Steuerung steht fest am unteren Rand - auf
 * dem Handy quer ueber die Breite, auf dem Rechner als Spalte rechts daneben.
 * Der Grund war die Rueckmeldung "man muss immer scrollen, um neu zu
 * spielen": vorher stand der Spielknopf unter dem Spielfeld, und ein
 * Nagelbrett plus Auszahlungstafel plus zwei Einstellungszeilen sind auf 390
 * Pixeln mehr als ein Bildschirm. Einstellungen duerfen scrollen, der Knopf
 * zum Spielen nie.
 */
.spielraum {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; gap: .5rem;
}
.spielfeld {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
  /* Kurze Spielfelder - Flip, Limbo, Dice - stehen mittig statt oben, sonst
     klebt eine Handvoll Zeilen unter der Ueberschrift und darunter ist eine
     Handbreit Nichts. `safe` ist der ganze Trick: sobald der Inhalt hoeher
     ist als der Kasten (Turm, Plinko mit Tafel), faellt die Ausrichtung auf
     `flex-start` zurueck - ohne das waere der obere Rand weggescrollt und
     nicht mehr erreichbar. */
  display: flex; flex-direction: column; justify-content: safe center;
}
.steuerung {
  flex: 0 0 auto;
  display: flex; flex-direction: column; gap: .5rem;
  padding-top: .5rem;
  border-top: 1px solid var(--kante);
}
.steuerung .einsatzleiste { margin: 0; }
.steuerung .feldzeile { margin-bottom: 0; }
.steuerung .wahlreihe { justify-content: center; }

/* ── Einsatzleiste ─────────────────────────────────────────────────────── */

.einsatzleiste {
  background: var(--karte); border: 1px solid var(--kante); border-radius: 14px;
  padding: .7rem; margin: .8rem 0;
}
.feldzeile { display: flex; gap: .5rem; align-items: center; margin-bottom: .5rem; flex-wrap: wrap; }
.feldzeile label { font-size: .78rem; color: var(--grau); min-width: 4.2rem; }
.feldzeile .wachs { flex: 1 1 6rem; min-width: 6rem; }
.schnell { display: flex; gap: .35rem; }
.schnell button {
  font: inherit; font-size: .75rem; font-weight: 700; padding: .35rem .5rem;
  background: #1e3328; color: var(--grau); border: 1px solid var(--kante);
  border-radius: 8px; cursor: pointer;
}
.schnell button:active { transform: scale(.94); }

.wahlreihe { display: flex; gap: .35rem; flex-wrap: wrap; }
.wahlreihe button {
  font: inherit; font-size: .78rem; padding: .35rem .6rem;
  background: #1e3328; color: var(--grau); border: 1px solid var(--kante);
  border-radius: 999px; cursor: pointer;
}
.wahlreihe button[aria-pressed="true"] { background: var(--gruen); color: #06210f; border-color: var(--gruen); font-weight: 700; }

.ergebniszeile {
  min-height: 2.2rem; display: flex; align-items: center; justify-content: center;
  gap: .5rem; font-weight: 700; font-size: 1.05rem;
}
.ergebniszeile.gut { color: var(--gruen-hell); }
.ergebniszeile.schlecht { color: var(--grau); }

/* Die eine grosse Zahl, um die es geht - bei Dice der Wurf, bei Limbo der
   erreichte Multiplikator. Frueher war das eine `.crashzahl` mit zwei
   Ausnahmen per `style`-Attribut; das war dieselbe Klasse fuer zwei Dinge. */
.grossezahl {
  display: grid; place-content: center;
  min-height: 5.5rem; margin: .4rem 0;
  font-size: clamp(2.4rem, 13vw, 3.8rem); font-weight: 800;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.grossezahl.gut { color: var(--gruen-hell); }
.grossezahl.aus { color: var(--rot); }

/* ── Plinko ────────────────────────────────────────────────────────────── */

.plinkobrett { position: relative; width: 100%; aspect-ratio: 4 / 3; max-height: 42dvh; margin: 0 auto; }
.plinkobrett canvas { width: 100%; height: 100%; display: block; }
/* Die Faecherleiste teilt die Breite auf, statt seitlich hinauszulaufen:
   siebzehn Faecher muessen auf ein 390-Pixel-Handy passen. `min-width: 0` ist
   dabei der entscheidende Teil - ohne ihn weigert sich ein Flex-Kind, unter
   seine Inhaltsbreite zu schrumpfen. */
.faecher { display: flex; gap: 1px; margin-top: .4rem; padding-bottom: .2rem; }
.fach {
  flex: 1 1 0; min-width: 0; text-align: center; font-size: .58rem; font-weight: 700;
  padding: .25rem 0; border-radius: 4px; color: #06210f;
  overflow: hidden; white-space: nowrap;
}
.fach.treffer { animation: fachHuepf .5s; }
@keyframes fachHuepf { 30% { transform: translateY(-8px) scale(1.12); } }

/* ── Mines ─────────────────────────────────────────────────────────────── */

.minenfeld { display: grid; grid-template-columns: repeat(5, 1fr); gap: .4rem; margin: .8rem 0; }
.minenfeld button {
  aspect-ratio: 1; font-size: 1.4rem; border-radius: 10px; border: 1px solid var(--kante);
  background: #1a2c22; cursor: pointer; color: var(--text); display: grid; place-content: center;
  transition: transform .08s, background .15s;
}
.minenfeld button:disabled { cursor: default; }
.minenfeld button.frei { background: #17402a; border-color: var(--gruen); animation: aufdeck .3s; }
.minenfeld button.mine { background: #4a1414; border-color: var(--rot); }
.minenfeld button.blass { opacity: .35; }
/* Die Bombe, in die man gelaufen ist. Die anderen liegen `blass` daneben -
   aufgedeckt, aber ohne Anspruch auf den Blick. */
.minenfeld button.bumm { animation: bummStoss .45s cubic-bezier(.36, .07, .19, .97); z-index: 1; }
@keyframes bummStoss {
  0% { transform: scale(.6); }
  40% { transform: scale(1.25) rotate(6deg); }
  70% { transform: scale(.95) rotate(-4deg); }
  100% { transform: none; }
}
@keyframes aufdeck { from { transform: scale(.7) rotate(-8deg); } }

/* ── Drachenturm ───────────────────────────────────────────────────────── */

.turm { display: flex; flex-direction: column-reverse; gap: .35rem; margin: .8rem 0; }
.turmreihe { display: flex; gap: .35rem; }
.turmreihe.dran { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 10px; }
.turmreihe button {
  flex: 1; height: 2.6rem; border-radius: 8px; border: 1px solid var(--kante);
  background: #1a2c22; cursor: pointer; font-size: 1.1rem; color: var(--text);
}
.turmreihe button:disabled { cursor: default; }
.turmreihe button.ei { background: #17402a; border-color: var(--gruen); }
.turmreihe button.drache { background: #4a1414; border-color: var(--rot); }
.turmreihe .mult { flex: 0 0 3.4rem; display: grid; place-content: center; font-size: .7rem; color: var(--grau); }

/* ── Muenze, Bars, Diamanten ───────────────────────────────────────────── */

.muenzenreihe {
  display: flex; gap: .4rem; flex-wrap: wrap; justify-content: center;
  margin: .6rem 0; min-height: 3rem; align-items: center;
}
.muenzenreihe span { font-size: 2.2rem; animation: aufdeck .3s; }
.muenzenreihe span.wartet { opacity: .3; animation: none; }

/* Kopf oder Zahl: zwei Quadrate, Zeichen gross, Wort klein. `max-width`
   deckelt sie - ohne den Deckel waeren sie auf einem breiten Bildschirm
   handtellergross, und ein Quadrat, das den halben Bildschirm fuellt, sieht
   nicht nach einer Wahl aus, sondern nach einem Versehen. */
.muenzwahl { display: flex; gap: .7rem; justify-content: center; }
.muenzseite {
  font: inherit; cursor: pointer; touch-action: manipulation;
  flex: 1 1 0; max-width: 8.5rem; aspect-ratio: 1;
  display: grid; place-content: center; gap: .35rem;
  border: 1px solid var(--kante); border-radius: 16px;
  background: linear-gradient(160deg, #1e3328, #16261e);
  color: var(--text);
  transition: transform .08s, border-color .15s, background .15s;
}
.muenzseite:hover { border-color: var(--gruen); }
.muenzseite:active { transform: scale(.95); background: #17402a; }
.muenzseite .sym { font-size: 2.8rem; line-height: 1; }
.muenzseite .nam { font-weight: 700; font-size: .9rem; }

/* ── Bars: ein Streifen je Walze, Wucht je Zeichen ──────────────────────────

   Was hier steht, sind die Regler, die `casino.js` setzt - Zahlen, keine
   Stile:

   `--wucht`  wie hart das Zeichen einschlaegt (1 = Kirsche, 1,22 = Sieben).
   `.selten` / `.sehrselten`  wie das Zeichen glueht, nachdem es liegt.

   Ohne diese Klassen sah eine Sieben genauso aus wie eine Kirsche, und die
   Tafel darunter war der einzige Hinweis darauf, dass sie hundertmal so viel
   zahlt. Eine Tafel liest man einmal; eine Walze sieht man bei jedem Zug.

   Das **Tempo** steht nicht mehr hier. Es hing frueher an `--tempo` und wurde
   waehrend der Spannung in Stufen umgeschaltet; seit der Streifen aus
   `casino.js` gefahren wird, ergibt es sich aus der Strecke bis zur Zielzelle
   und der Zeit bis zum Halt.

   Der laufende Streifen und das liegende Zeichen sind **zwei** Elemente im
   selben Kasten, und immer ist nur eines zu sehen: `.streifen` waehrend der
   Fahrt, `.zeichen` danach. Ein einzelnes Element koennte beides nicht - der
   Streifen braucht acht Felder untereinander, das Ergebnis genau eines in der
   Mitte. Der Uebergang faellt nicht auf, weil der Streifen genau auf der
   Zelle steht, die `.zeichen` gleich zeigt: dieselbe Tinte, dieselbe Stelle. */

.walzen { display: flex; gap: .5rem; justify-content: center; margin: 1rem 0; }
.walze {
  --wucht: 1;
  --hoehe: 5.5rem;
  position: relative;
  width: 4.5rem; height: var(--hoehe); border-radius: 12px; background: #0c1712;
  border: 1px solid var(--kante); display: grid; place-content: center; font-size: 2.4rem;
  overflow: hidden;
  transition: border-color .18s, box-shadow .18s;
}

/* Der Streifen: alle sieben Zeichen untereinander, das achte Feld wiederholt
   das erste - dadurch ist die Naht unsichtbar.

   **Geschoben wird er aus JavaScript**, nicht von einer Animation hier. Der
   Grund steht bei `baueBars` in `casino.js`: eine CSS-Schleife dreht sich ohne
   Bezug zum Ergebnis, bleibt beim Halt irgendwo stehen, und das richtige
   Zeichen musste darueber eingeblendet werden - sichtbar als Zeichenwechsel im
   letzten Moment. Jetzt faehrt der Streifen auf seine Zelle zu und haelt
   darauf; `--tempo` gibt es nicht mehr, weil das Tempo aus der Strecke folgt. */
.streifen {
  display: none;
  position: absolute; left: 0; right: 0; top: 0;
  flex-direction: column;
  will-change: transform;
}
.streifen span { height: var(--hoehe); display: grid; place-content: center; }
.walze.dreht .streifen { display: flex; }
.walze.dreht .zeichen { visibility: hidden; }
.walze.gewinn { border-color: var(--gold); box-shadow: 0 0 16px #f7c94855; }

/* Der Einschlag. Die Walze staucht sich kurz, das Zeichen wird dabei einmal
   durchgedrueckt - `--wucht` streckt beides. Bewusst knapp: die Walze
   schneidet ab, was ueber ihren Rand hinausgeht (sie muss, sonst liefe der
   Streifen heraus), und ein angeschnittenes 7️⃣ ist schlimmer als ein ruhiges.

   Das Zeichen faehrt hier **nicht** mehr von oben herein (`translateY(-70%)`).
   Es ist bereits da - der Streifen hat es hereingedreht und steht darauf. Ein
   zweiter Einflug an derselben Stelle sah aus, als entstuende das Zeichen im
   Moment des Halts, und genau das war der Eindruck, den es loszuwerden galt.
   Geblieben ist der Stoss: die Walze setzt auf, das Zeichen federt. */
.walze.einschlag { animation: walzeStoss .28s cubic-bezier(.2, .9, .25, 1); }
.walze.einschlag .zeichen { animation: zeichenStoss .3s cubic-bezier(.16, 1.3, .3, 1); }
@keyframes walzeStoss {
  0% { transform: scaleY(calc(1 + (var(--wucht) - 1) * .5)) scaleX(calc(1 - (var(--wucht) - 1) * .35)); }
  55% { transform: scaleY(calc(1 - (var(--wucht) - 1) * .45)) scaleX(calc(1 + (var(--wucht) - 1) * .3)); }
  100% { transform: none; }
}
@keyframes zeichenStoss {
  0% { transform: scale(1); }
  45% { transform: scale(var(--wucht)); }
  100% { transform: none; }
}

/* Wie ein Zeichen liegenbleibt: ⭐ und aufwaerts leuchten, 💎 und 7️⃣ zusaetzlich
   mit einem Rand, der die Farbe der obersten Tafelzeile hat. Der Schein sitzt
   am Rahmen und nicht am Zeichen - ein `drop-shadow` mit grossem Radius wird
   am Rand der Walze abgeschnitten und sah aus wie ein Fehler. */
.walze.selten { border-color: #6fd39a; box-shadow: 0 0 14px #35e07a44; }
.walze.selten .zeichen { filter: drop-shadow(0 0 4px #35e07aaa); }
.walze.sehrselten { border-color: var(--gold); box-shadow: 0 0 22px #f7c94866, inset 0 0 18px #f7c94822; }
.walze.sehrselten .zeichen { filter: drop-shadow(0 0 5px #f7c948dd); }

/* Die dritte Walze, solange sie noch laeuft und etwas an ihr haengt. */
.walze.heiss { border-color: var(--gold); box-shadow: 0 0 18px #f7c94855; }
.walzen.spannung { animation: reihePuls .38s ease-in-out infinite alternate; }
.walzen.spannung3 { animation-duration: .22s; }
@keyframes reihePuls {
  from { filter: none; }
  to { filter: brightness(1.22) saturate(1.15); }
}

/* Ein kurzes Ruetteln der ganzen Reihe - `fx.wackeln` setzt die Klasse, wenn
   ein 💎 oder eine 7️⃣ faellt. */
.wackel { animation: wackeln .5s cubic-bezier(.36, .07, .19, .97); }
@keyframes wackeln {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-6px); }
  40%, 60% { transform: translateX(6px); }
}

.steine { display: flex; gap: .35rem; justify-content: center; flex-wrap: wrap; margin: 1rem 0; }
.stein { font-size: 2rem; animation: aufdeck .3s backwards; }
.stein.zaehlt { filter: drop-shadow(0 0 8px var(--gold)); transform: scale(1.15); }

/* ── Keno ──────────────────────────────────────────────────────────────── */

/**
 * Sechsunddreissig Felder, sechs mal sechs.
 *
 * Ein Quadrat, und zwar in **jeder** Breite - deshalb steht hier ein
 * `max-width` und keine zweite Regel fuer den Rechner. Vorher waren es acht
 * Spalten auf dem Handy und zehn am Rechner: ein Streifen, der oben breiter
 * wurde statt hoeher, und am Rechner eine Reihe von zehn Zahlen quer ueber den
 * halben Bildschirm. Warum sechsunddreissig und nicht vierzig, steht bei
 * `KENO_ZAHLEN` in `spiele.js`.
 */
.kenobrett {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 5px;
  margin: 0 auto .2rem;
  width: 100%; max-width: 24rem;
}
.kenofeld {
  font: inherit; font-size: .85rem; font-weight: 700;
  aspect-ratio: 1; padding: 0;
  display: grid; place-content: center;
  border: 1px solid var(--kante); border-radius: 8px;
  background: #12211a; color: var(--grau);
  cursor: pointer; touch-action: manipulation;
  font-variant-numeric: tabular-nums;
  transition: transform .1s, background .12s, color .12s, border-color .12s;
}
.kenofeld[aria-pressed="true"] {
  background: #17402a; color: var(--gruen-hell); border-color: var(--gruen);
}
/* Gezogen, aber nicht getippt: sichtbar, ohne den Blick zu ziehen. */
.kenofeld.gezogen { background: #23301f; color: #b9c9ae; border-color: #3f5533; }
/* Getroffen: das Einzige auf dem Brett, das leuchtet. */
.kenofeld.treffer {
  background: linear-gradient(180deg, var(--gold), #d9a916);
  color: #2a1f00; border-color: var(--gold);
  transform: scale(1.08);
}
.kenozeile { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin: .6rem 0; }
.kenozeile .btn { font-size: .85rem; padding: .45rem .9rem; }
.kenozaehler { font-size: .85rem; color: var(--grau); font-variant-numeric: tabular-nums; }

/* ── Crash ─────────────────────────────────────────────────────────────── */

/* `max-height`, damit die Kurve auf einem breiten Bildschirm nicht die halbe
   Hoehe frisst - das Seitenverhaeltnis gilt dann nur noch bis dorthin. */
.crashfeld { position: relative; width: 100%; aspect-ratio: 16 / 10; max-height: 40dvh;
  background: #0c1712;
  border: 1px solid var(--kante); border-radius: 12px; overflow: hidden; }
.crashfeld canvas { width: 100%; height: 100%; display: block; }
.crashzahl {
  position: absolute; inset: 0; display: grid; place-content: center;
  font-size: clamp(2rem, 12vw, 3.5rem); font-weight: 800; font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 20px #000; pointer-events: none;
}
.crashzahl.aus { color: var(--rot); }
/* Es gab hier einmal `.crashverlauf` (die letzten zwanzig Runden) und
   `.dabeiliste` (wer sonst noch in der Runde sitzt). Beides ist mit der
   gemeinsamen Runde weggefallen: Crash ist seit 03.09.2026 ein Spiel fuer
   einen, und eine Liste vergangener Absturzpunkte ist ohnehin nur eine
   Einladung, Muster in Zufall zu sehen. */

/* ── Boerse ────────────────────────────────────────────────────────────── */

.papierliste { display: flex; flex-direction: column; gap: .4rem; }
.papier {
  display: grid; grid-template-columns: 3.6rem 1fr auto; gap: .5rem; align-items: center;
  background: var(--karte); border: 1px solid var(--kante); border-radius: 12px;
  padding: .55rem .7rem; cursor: pointer; text-align: left; font: inherit; color: var(--text);
}
.papier[aria-pressed="true"] { border-color: var(--gold); }
.papier .kuerzel { font-weight: 800; letter-spacing: .04em; }
.papier .firma { font-size: .72rem; color: var(--grau); }
.papier .preis { font-variant-numeric: tabular-nums; text-align: right; }
.papier .delta { font-size: .72rem; }
.hoch { color: var(--gruen-hell); }
.runter { color: var(--rot); }

.chartkasten { position: relative; width: 100%; aspect-ratio: 16 / 9; margin: .8rem 0;
  background: #0c1712; border: 1px solid var(--kante); border-radius: 12px; overflow: hidden; }
.chartkasten canvas { width: 100%; height: 100%; display: block; }

.positionsliste { display: flex; flex-direction: column; gap: .4rem; }
.position {
  background: var(--karte); border: 1px solid var(--kante); border-radius: 12px; padding: .6rem .7rem;
  display: grid; grid-template-columns: 1fr auto; gap: .3rem .6rem; align-items: center;
}
.position.gewinnt { border-color: #1db95455; }
.position.verliert { border-color: #ef444455; }
.position .zeile2 { grid-column: 1 / -1; font-size: .72rem; color: var(--grau); }

.nachrichtenliste { display: flex; flex-direction: column; gap: .3rem; margin-top: .8rem; }
.nachricht { font-size: .78rem; padding: .4rem .6rem; border-radius: 8px; background: var(--karte);
  border-left: 3px solid var(--kante); }
.nachricht.gut { border-left-color: var(--gruen); }
.nachricht.schlecht { border-left-color: var(--rot); }

/* ── Laden ─────────────────────────────────────────────────────────────── */

.ladenliste { list-style: none; padding: 0; margin: 1rem 0 0; display: flex; flex-direction: column; gap: .6rem; }
.ladenliste li {
  background: var(--karte); border: 1px solid var(--kante); border-radius: 14px; padding: .75rem;
  display: grid; grid-template-columns: 2.6rem 1fr auto; gap: .6rem; align-items: center;
}
.ladenliste .sym { font-size: 1.8rem; text-align: center; }
.ladenliste .nam { font-weight: 700; }
.ladenliste .was { font-size: .76rem; color: var(--grau); }
.ladenliste .stufe { font-size: .72rem; color: var(--gold); }
.ladenliste .btn { white-space: nowrap; font-size: .85rem; }

/* ── Tafel ─────────────────────────────────────────────────────────────── */

.tafelspalten { display: grid; grid-template-columns: 1fr; gap: 1rem; }
@media (min-width: 34rem) { .tafelspalten { grid-template-columns: 1fr 1fr; } }
.rangliste { list-style: none; counter-reset: r; padding: 0; margin: 0; }
.rangliste li {
  counter-increment: r; display: flex; gap: .5rem; align-items: baseline;
  padding: .35rem .5rem; border-bottom: 1px solid var(--kante); font-size: .85rem;
}
.rangliste li::before { content: counter(r) "."; color: var(--grau); min-width: 1.4rem; }
.rangliste li strong { margin-left: auto; font-variant-numeric: tabular-nums; }
.rangliste li:nth-child(1) strong { color: var(--gold); }

.feed { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: .25rem; }
.feed li {
  display: flex; gap: .5rem; align-items: baseline; font-size: .8rem;
  background: var(--karte); border-radius: 8px; padding: .3rem .5rem;
  animation: rein .25s ease-out;
}
.feed .wer { font-weight: 700; }
.feed .was { color: var(--grau); }
.feed .mult { margin-left: auto; color: var(--gold); font-weight: 700; font-variant-numeric: tabular-nums; }

.fair { display: grid; grid-template-columns: 1fr; gap: .2rem; margin: .5rem 0 1rem; }
.fair dt { font-size: .75rem; color: var(--grau); margin-top: .5rem; }
.fair dd { margin: 0; }

/* ── Reiter ────────────────────────────────────────────────────────────── */

#reiter {
  flex: 0 0 auto; z-index: 40;
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: #0b1410f2; backdrop-filter: blur(8px);
  border-top: 1px solid var(--kante);
  padding-bottom: env(safe-area-inset-bottom);
}
.reiter {
  font: inherit; background: none; border: 0; color: var(--grau); cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: .1rem;
  padding: .5rem .2rem; font-size: .66rem; height: var(--reiter-h);
}
.reiter span:first-child { font-size: 1.25rem; line-height: 1; }
.reiter.an { color: var(--gruen-hell); }

/* ── Overlay ───────────────────────────────────────────────────────────── */

.overlay {
  position: fixed; inset: 0; z-index: 70; background: #000a;
  display: flex; align-items: flex-end; justify-content: center;
  backdrop-filter: blur(3px);
}
.overlay[hidden] { display: none !important; }
.blatt {
  width: 100%; max-width: 34rem; max-height: 88dvh; overflow-y: auto;
  background: var(--grund2); border: 1px solid var(--kante);
  border-radius: 18px 18px 0 0; padding: 1rem 1rem 2rem;
  animation: hoch .22s ease-out;
}
@keyframes hoch { from { transform: translateY(20px); opacity: 0; } }
.blattkopf { display: flex; align-items: center; gap: .5rem; }
.blattkopf h2 { flex: 1; margin: 0; }
.ablauf { padding-left: 1.1rem; }
.ablauf li { margin: .6rem 0; line-height: 1.5; font-size: .88rem; }

/* ── Toast ─────────────────────────────────────────────────────────────── */

.toast {
  position: fixed; left: 50%; bottom: calc(var(--reiter-h) + 1rem);
  transform: translateX(-50%); z-index: 80;
  background: #1e3328; border: 1px solid var(--kante); border-radius: 10px;
  padding: .5rem .9rem; font-size: .85rem; max-width: 90vw; text-align: center;
  animation: rein .2s ease-out;
}
.toast.schlecht { background: #3a1414; border-color: #7f2626; }

/* ── Effekte-Ebene ─────────────────────────────────────────────────────── */

#fx-lage { position: fixed; inset: 0; pointer-events: none; z-index: 55; overflow: hidden; }

.fx-zahl {
  position: absolute; transform: translate(-50%, -50%);
  font-weight: 800; font-size: 1.1rem; color: var(--gruen-hell);
  text-shadow: 0 2px 6px #000; animation: fxAuf 1.05s ease-out forwards;
}
.fx-zahl.gold { color: var(--gold); font-size: 1.4rem; }
.fx-zahl.rot { color: var(--rot); }
@keyframes fxAuf {
  from { opacity: 1; transform: translate(-50%, -50%) scale(.7); }
  40% { transform: translate(-50%, -140%) scale(1.15); }
  to { opacity: 0; transform: translate(-50%, -260%) scale(1); }
}

.fx-muenze {
  position: absolute; top: -8vh; font-size: 1.4rem;
  animation: fxFall linear forwards;
}
@keyframes fxFall { to { transform: translateY(115vh) rotate(540deg); opacity: .2; } }

/* Der Glueckbringer fliegt quer durch das Bild und laesst sich antippen.
   Er ist das einzige Element auf der Effekte-Ebene, das Klicks annimmt. */
.fx-bringer {
  position: absolute; pointer-events: auto; cursor: pointer;
  font-size: 2.6rem; border: 0; background: none; padding: .4rem;
  filter: drop-shadow(0 0 10px #f7c94899);
  animation: fxFlug 9s linear forwards;
}
.fx-bringer:active { transform: scale(1.3); }
@keyframes fxFlug {
  from { transform: translate(-15vw, 0) rotate(-10deg); }
  50% { transform: translate(45vw, -6vh) rotate(10deg); }
  to { transform: translate(110vw, 2vh) rotate(-10deg); }
}

.fx-jubel {
  position: fixed; left: 50%; top: 28%; transform: translateX(-50%);
  z-index: 58; pointer-events: none;
  font-size: clamp(1.6rem, 9vw, 2.6rem); font-weight: 900; text-align: center;
  color: var(--gold); text-shadow: 0 3px 14px #000, 0 0 24px #f7c94866;
  animation: fxJubel 1.5s ease-out forwards;
}
@keyframes fxJubel {
  from { opacity: 0; transform: translateX(-50%) scale(.6); }
  20% { opacity: 1; transform: translateX(-50%) scale(1.1); }
  75% { opacity: 1; transform: translateX(-50%) scale(1); }
  to { opacity: 0; transform: translateX(-50%) scale(1.05); }
}

.blitzschirm {
  position: fixed; inset: 0; z-index: 54; pointer-events: none;
  background: radial-gradient(circle, #f7c94833, transparent 70%);
  animation: fxBlitz .45s ease-out forwards;
}
.blitzschirm.rot { background: radial-gradient(circle, #ef444433, transparent 70%); }
@keyframes fxBlitz { from { opacity: 1; } to { opacity: 0; } }

/* ══════════════════════════════════════════════════════════════════════════
   Grosser Bildschirm

   Ab 62rem (rund 990 Pixel) wandert die Reiterleiste von unten nach links und
   das offene Spiel bekommt zwei Spalten: links das Feld, rechts die
   Steuerung. Beides hat denselben Grund - auf einem Rechner ist Hoehe knapp
   und Breite reichlich, und was unten quer liegt, kostet Hoehe, die dem Spiel
   fehlt. Danach sind Menue **und** ganzes Spiel gleichzeitig zu sehen, ohne
   irgendwo zu scrollen.

   Unter 62rem bleibt alles, wie es war: die Leiste unten, wo der Daumen ist.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Fallobst: sechs Spalten, fuenf Reihen ──────────────────────────────────

   Das Brett steht in einem Raster mit fester Zeilenzahl und quadratischen
   Kacheln (`aspect-ratio`), damit es auf 390 px genauso aussieht wie auf einem
   Bildschirm - nur kleiner. `overflow: hidden` haelt die einfallenden Kacheln
   im Brett: ohne das schoebe die oberste Reihe waehrend des Falls den Rest der
   Seite nach unten.

   `--verzug` staffelt den Fall: die unterste Luecke schliesst sich zuerst,
   darueber rutscht es nach. Dadurch sieht es aus, als falle etwas nach,
   obwohl in Wahrheit alle betroffenen Kacheln neu gesetzt wurden. */

.obstbrett {
  /* `flex: 0 0 auto` ist Pflicht und keine Feinheit: `.spielfeld` ist eine
     Spalte aus Flex-Elementen, und ein Raster mit `aspect-ratio` laesst sich
     von einem Flex-Container klaglos zusammendruecken. Ohne die Zeile standen
     von fuenf Reihen zwei da und eine halb. */
  flex: 0 0 auto;
  display: grid; gap: .3rem; margin: .8rem 0;
  border-radius: 12px; overflow: hidden;
}
.obst {
  aspect-ratio: 1; border-radius: 10px; border: 1px solid var(--kante);
  background: #14241c; display: grid; place-content: center;
  font-size: 1.7rem; line-height: 1;
  transition: transform .15s, background .15s, border-color .15s, opacity .15s;
}
/* Vor dem ersten Wurf ist das Brett leer - kein Zeichen, kein Rahmen, der
   nach Ergebnis aussieht. */
.obst.leer { background: #101b15; border-style: dashed; border-color: #1c2f24; }
.obst.faellt { animation: obstFall .3s cubic-bezier(.3, .8, .35, 1) backwards; animation-delay: var(--verzug, 0ms); }
@keyframes obstFall {
  from { transform: translateY(-220%); opacity: .15; }
  to { transform: none; opacity: 1; }
}

/* Was zaehlt, leuchtet und wird groesser; alles andere tritt zurueck. Beides
   zusammen - ohne das Zuruecktreten sieht man bei drei von dreissig Kacheln
   nicht, welche gemeint sind.

   **Drei Stufen, nicht eine.** Eine Dreierreihe fuer 0,16x und eine Lawine
   fuer 40x sahen bis zum 05.09.2026 gleich aus: derselbe Puls, dieselben
   620 ms. Wer den grossen Treffer hatte, sah ihn genauso lange und genauso
   laut wie den kleinen - und weil danach gleich das naechste Bild faellt, war
   er vorbei, bevor man ihn gelesen hatte. Jetzt setzt `casino.js` je nach
   Hoehe des Sturzes `wucht` oder `wucht2`, und die Kachel schlaegt zuerst
   einmal richtig aus, bevor sie in den Puls uebergeht. */
.obst.zaehlt {
  background: #17402a; border-color: var(--gold);
  box-shadow: 0 0 14px #f7c94866;
  animation: obstPuls .38s ease-in-out infinite alternate;
}
@keyframes obstPuls {
  from { transform: scale(1); }
  to { transform: scale(1.14); }
}
/* Der Ausschlag beim Auftauchen: einmal kraeftig, dann uebernimmt der Puls.
   Zwei Animationen an einer Kachel, hintereinander gestaffelt - der Puls
   wartet mit `animation-delay`, bis der Schlag durch ist. */
.obst.zaehlt.wucht {
  box-shadow: 0 0 22px #f7c948aa;
  animation: obstSchlag .34s cubic-bezier(.2, 1.5, .3, 1), obstPuls .34s ease-in-out .34s infinite alternate;
}
.obst.zaehlt.wucht2 {
  background: #4a3410; border-color: #ffe08a;
  box-shadow: 0 0 30px #f7c948, 0 0 60px #f7c94855;
  animation: obstSchlag2 .46s cubic-bezier(.2, 1.5, .3, 1), obstPuls .3s ease-in-out .46s infinite alternate;
}
@keyframes obstSchlag {
  0% { transform: scale(1); }
  45% { transform: scale(1.42) rotate(-4deg); }
  100% { transform: scale(1.14); }
}
@keyframes obstSchlag2 {
  0% { transform: scale(1); }
  30% { transform: scale(1.75) rotate(6deg); }
  62% { transform: scale(1.2) rotate(-5deg); }
  100% { transform: scale(1.14); }
}
.obst.still { opacity: .28; }

/* Die mitzaehlende Zeile unter dem Brett. Sie waechst mit dem, was dasteht -
   bei einer langen Lawine ist sie die Zahl, auf die alle sehen. */
#obstKette { transition: font-size .18s, color .18s; min-height: 1.2rem; }
#obstKette.gross { font-size: 1.05rem; font-weight: 700; color: #cfe9d9; }
#obstKette.riesig { font-size: 1.4rem; font-weight: 800; color: var(--gold); text-shadow: 0 0 14px #f7c94888; }

/* Die zwei Tafeln darunter: eine Zeile je Sorte, eine Spalte je Stufe. */
.obsttafel { display: grid; gap: .2rem; margin-top: .5rem; }
.obsttafelkopf { font-size: .72rem; color: var(--grau); text-align: center; margin-bottom: .1rem; }
.obstzeile {
  display: grid; grid-template-columns: 2.2rem repeat(3, 1fr); gap: .25rem;
  align-items: center; text-align: center; font-size: .78rem;
}
.obstzeile.kopf { color: var(--grau); font-size: .68rem; }
.obstzeile > div { background: #14241c; border-radius: 6px; padding: .2rem 0; }
.obstzeile.kopf > div { background: none; }
.obstsorte { font-size: 1.15rem; background: none !important; }

@media (min-width: 62rem) {
  /* Die Schiene liegt fest am linken Rand; der Koerper macht ihr Platz. Sie
     aus dem Fluss zu nehmen ist noetig, weil `body` eine Spalte ist - als
     Spaltenkind stuende sie sonst unter der Buehne statt neben ihr. */
  body { padding-left: var(--schiene); }

  #reiter {
    position: fixed; top: 0; left: 0; bottom: 0; width: var(--schiene);
    grid-template-columns: 1fr;
    grid-auto-rows: max-content;
    align-content: start;
    gap: .25rem;
    padding: .8rem .6rem;
    border-top: 0;
    border-right: 1px solid var(--kante);
  }
  .reiter {
    flex-direction: row; justify-content: flex-start; align-items: center;
    gap: .65rem;
    height: auto; padding: .65rem .8rem;
    font-size: .95rem; text-align: left;
    border-radius: 10px;
  }
  .reiter span:first-child { font-size: 1.3rem; }
  .reiter:hover { background: #17251d; color: var(--text); }
  .reiter.an { background: #17402a; color: var(--gruen-hell); font-weight: 600; }

  #kopf { padding-left: 1.2rem; padding-right: 1.2rem; }
  #buehne { max-width: 64rem; padding: 1rem 1.2rem; }

  /* Zwei Spalten. Die Steuerung scrollt fuer sich, falls ein Spiel viele
     Einstellungen hat - der Spielknopf bleibt trotzdem im Bild, weil die
     Spalte nie hoeher wird als der Bildschirm. */
  .spielraum { flex-direction: row; gap: 1.4rem; align-items: stretch; }
  .spielfeld { flex: 1 1 auto; }
  .steuerung {
    flex: 0 0 21rem;
    min-height: 0; overflow-y: auto;
    justify-content: flex-start;
    border-top: 0;
    border-left: 1px solid var(--kante);
    padding-top: 0; padding-left: 1.2rem;
  }

  /* Was auf dem Handy den ganzen Bildschirm braucht, darf hier kleiner sein:
     sonst steht eine Kurve von 40 dvh Hoehe neben einer halbleeren Spalte. */
  .crashfeld { max-height: 52dvh; }
  .plinkobrett { max-height: 54dvh; max-width: 34rem; }
  /* Die Faecherleiste muss **genau** so breit sein wie das Brett darueber,
     sonst faellt der Ball neben sein Fach: beide teilen dieselbe Breite in
     `reihen + 1` Spalten, und `canvas` und `.faecher` rechnen jeder mit ihrer
     eigenen. Auf dem Handy sind sie beide 100 % breit; hier nicht. */
  /* `width: 100%` gehoert dazu: `.spielfeld` ist ein Spalten-Flexkasten, und
     ein Kind mit `margin-left/right: auto` schrumpft darin auf seinen Inhalt
     statt sich zu strecken. Ohne die Zeile war die Leiste 287 px breit und das
     Brett darueber 544. */
  .plinkobrett + .faecher {
    width: 100%; max-width: 34rem; margin-left: auto; margin-right: auto;
  }
  .zahlen { grid-template-columns: repeat(4, 1fr); }
  .raster { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); }
}

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