/*
 * NORTHSIDE Player Portal — iOS-Designsystem.
 *
 * Übernommen aus dem abgestimmten Entwurf und hier zur wartbaren Datei
 * auseinandergenommen. Bewusst KEIN Framework und kein Build-Schritt — wie im
 * übrigen Frontend dieses Projekts.
 *
 * Der Leitgedanke: Das hier soll sich wie eine App anfühlen, nicht wie eine
 * Website. Daraus folgt alles Weitere — Bedienung unten in der Daumenzone,
 * Listen im Einstellungen-Stil, Blätter statt Seitenwechsel, und Farben aus
 * der iOS-Systempalette statt eigener Erfindungen.
 *
 * WICHTIG für alles, was hier ergänzt wird:
 *   * Kein Tippziel unter 44 px.
 *   * Sichere Bereiche beachten (env(safe-area-inset-*)), sonst liegt das
 *     unterste Element auf dem iPhone unter dem Home-Indikator.
 *   * Hell- UND Dunkelmodus bedienen; iOS kann beides, also können wir es auch.
 */

/* ── Poppins ────────────────────────────────────────────────
   Die Hausschrift der Bank — und NUR der Bank. Das übrige Portal bleibt bei
   der Systemschrift, weil es iOS nachbaut und iOS seine eigene Schrift
   mitbringt; die Bank bildet dagegen eine fremde App nach, und deren
   Schrift ist ein so großer Teil ihres Aussehens wie ihre Farbe.

   Mitgeliefert statt von Google geladen. Drei Gründe, in dieser Reihenfolge:
   das Portal soll als installierte App auch ohne Netz vollständig sein; ein
   Aufruf zu fonts.gstatic.com verrät jedem Spieler-Browser die Adresse
   dieser Seite; und der Server läuft auf http, ein Fremdaufruf nach https
   ist eine Fehlerquelle mehr. Poppins steht unter der SIL Open Font
   License 1.1 — Weitergabe mitsamt Programm ist ausdrücklich erlaubt.

   Vier Schnitte, je zweimal (latin und latin-ext). Mehr nicht: Kursiv
   benutzt die Vorlage nirgends, und jeder weitere Schnitt wäre Ladezeit für
   nichts. Wo ein Zeichen fehlt — kyrillische Spielernamen etwa —, springt
   die Systemschrift ein; das ist der Zweck der Kette hinter var(--font-bank).

   `font-display: swap`: Lieber sofort in der Systemschrift lesen und dann
   umspringen, als 100 ms auf eine leere Fläche schauen. */
@font-face {
  font-family: "Poppins NS"; font-style: normal; font-weight: 400; font-display: swap;
  src: url(fonts/poppins-400-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Poppins NS"; font-style: normal; font-weight: 400; font-display: swap;
  src: url(fonts/poppins-400-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Poppins NS"; font-style: normal; font-weight: 500; font-display: swap;
  src: url(fonts/poppins-500-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Poppins NS"; font-style: normal; font-weight: 500; font-display: swap;
  src: url(fonts/poppins-500-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Poppins NS"; font-style: normal; font-weight: 600; font-display: swap;
  src: url(fonts/poppins-600-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Poppins NS"; font-style: normal; font-weight: 600; font-display: swap;
  src: url(fonts/poppins-600-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Poppins NS"; font-style: normal; font-weight: 700; font-display: swap;
  src: url(fonts/poppins-700-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Poppins NS"; font-style: normal; font-weight: 700; font-display: swap;
  src: url(fonts/poppins-700-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* iOS-Systemfarben — die Werte hier sind die des HELLMODUS.
     Apple fuehrt vier davon im Dunkelmodus heller; die Abweichung steht
     im Dunkel-Block weiter unten (Figma: accent/blue, green, red, orange).
     Gelb, Lila, Pink, Tuerkis und Indigo kennt die Vorlage nicht — die
     bleiben ungeteilt. */
  --blue: #007AFF; --green: #34C759; --red: #FF3B30;
  --orange: #FF9500; --yellow: #FFCC00; --purple: #AF52DE;
  --pink: #FF2D55; --teal: #30B0C7; --indigo: #5856D6;
  /* Systemgrau — die deckende Fläche (z. B. Symbolkacheln). Nicht mit
     --label-2 verwechseln: das ist durchscheinende Schrift. */
  --grau: #8E8E93;

  /* Radien */
  --r-card: 22px; --r-box: 12px; --r-ctl: 8px; --r-pill: 999px;

  /* Abstände (8-pt-Raster) */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px; --s8: 32px;

  --gutter: 16px;
  /* Gerätestreifen. 54 px Statusleiste und 34 px Home-Anzeige sind die Maße
     des Apple-Kits (iPhone 15 Pro / Pro Max). */
  --statusbar-h: 54px;
  --homebar-h: 34px;


  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
          "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif;
  /* Die Bank traegt Poppins, der Rest des Portals nicht — siehe den
     Schriftblock oben. Die Kette dahinter ist dieselbe wie in --font:
     Faellt ein Zeichen aus Poppins heraus, springt die Systemschrift ein
     statt einer beliebigen Ersatzschrift des Browsers. */
  --font-bank: "Poppins NS", -apple-system, BlinkMacSystemFont, "SF Pro Text",
               "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif;
}

[data-theme="light"] {
  --bg: #F2F2F7;
  --bg-elev: #FFFFFF;
  /* Zweite Ebene: eine Flaeche AUF einer erhoehten Flaeche (Bildfelder,
     eingebettete Kaesten). bg/elevated-2 im Modus „Light". */
  --bg-elev-2: #F2F2F7;
  /* fill/control im Modus „Light": #78788033. Stand vorher auf
     118,118,128 bei .12 — Spur und Chips waren dadurch zu blass. */
  --fill: rgba(120,120,128,.20);
  --fill-2: rgba(118,118,128,.16);
  /* Ausgewähltes Segment: im Hellmodus weiß (Kit-Wert). */
  --seg-pille: #FFFFFF;
  --label: #000000;
  --label-2: rgba(60,60,67,.60);
  --label-3: rgba(60,60,67,.30);
  --separator: rgba(60,60,67,.29);
  /* Glaskanten, beide aus der Vorlage (Modus „Light"): glass/stroke
     #FFFFFF80, glass/highlight #FFFFFF99. Auch im Hellmodus ist die Kante
     WEISS, nur kraeftiger als im Dunkeln — eine dunkle Aussenkante, wie
     hier bis zum 30.08.2026 stand, war meine Annahme, nicht die Vorlage. */
  --glass-stroke: rgba(255,255,255,.50);
  --glass-highlight: rgba(255,255,255,.60);
  /* glass/regular im Modus „Light": #FFFFFFB8. Vorher ein eigener
     Grauton bei hoeherer Deckkraft. */
  --bar: rgba(255,255,255,.72);
  --sheet: #FFFFFF;
  --shadow: 0 1px 2px rgba(0,0,0,.06);
  --scrim: rgba(0,0,0,.4);
}

[data-theme="dark"] {
  /* Die vier Systemfarben, die Apple im Dunkelmodus heller fuehrt
     (Figma: accent/blue #0A84FF, green #30D158, red #FF453A,
     orange #FF9F0A). Bis 30.08.2026 galten hier die Hellmodus-Werte —
     auf schwarzem Grund wirkten sie eine Spur zu satt und zu dunkel.
     Das faellt ueberall auf: Schaltflaechen, Links, Schalter und die
     Kachelverlaeufe des Home-Bildschirms. */
  --blue: #0A84FF; --green: #30D158; --red: #FF453A; --orange: #FF9F0A;

  --bg: #000000;
  --bg-elev: #1C1C1E;
  --bg-elev-2: #2C2C2E;
  /* fill/control: rgba(120,120,128,.36). Vorher 118,118,128 bei .24 —
     die Spur des Segmented Control und die Chips waren dadurch zu blass. */
  --fill: rgba(120,120,128,.36);
  --fill-2: rgba(118,118,128,.32);
  /* Im Dunkelmodus ist die Pille grau, nicht weiß — sonst blendet sie. */
  --seg-pille: #636366;
  --label: #FFFFFF;
  --label-2: rgba(235,235,245,.60);
  --label-3: rgba(235,235,245,.30);
  --separator: rgba(84,84,88,.65);
  /* glass/stroke #FFFFFF1F und glass/highlight #FFFFFF33 aus der Vorlage.
     Sie hatten bis 30.08.2026 keinen Nutzer — nicht weil sie ueberfluessig
     waeren, sondern weil das Portal noch kein Liquid Glass machte. */
  --glass-stroke: rgba(255,255,255,.12);
  --glass-highlight: rgba(255,255,255,.20);
  /* glass/regular aus der Vorlage: #1C1C1EB8. Vorher rgba(22,22,22,.80) —
     etwas dunkler und etwas deckender als vorgesehen. */
  --bar: rgba(28,28,30,.72);
  --sheet: #1C1C1E;
  --shadow: none;
  --scrim: rgba(0,0,0,.55);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
  margin: 0; padding: 0; height: 100%;
  /* Beide Achsen, nicht nur die senkrechte: Gemessen stand hier
     `auto none` — waagerecht war das Gummiband also offen, und eine
     Wischgeste über den Rand hinaus zog die ganze Seite mit. In einer App
     gibt es das nicht. */
  overscroll-behavior: none;
}
body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--label);
  font-size: 17px;
  line-height: 1.29;
  letter-spacing: -.022em;
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
a { color: var(--blue); text-decoration: none; }
img { display: block; max-width: 100%; }

/* ── Rahmen ────────────────────────────────────────────────
   Fest positioniert mit eigenem Scrollbereich: Das ist der Preis für das
   App-Gefühl (die Adressleiste klappt dafür nicht mehr weg) und die
   Voraussetzung dafür, dass die Navigationsleiste oben stehen bleibt und der
   Bildschirmwechsel zwei Ebenen übereinander legen kann. */
.app {
  position: fixed; inset: 0;
  display: flex; flex-direction: column;
  max-width: 520px; margin: 0 auto;
  background: var(--bg);
  overflow: hidden;
}

/* ── Navigationsleiste ──────────────────────────────────────
   Scroll-Edge: Die Leiste ist im Grundzustand DURCHSICHTIG und wird erst zu
   Glas, sobald Inhalt darunter durchläuft. Bis iOS 18 war sie dauerhaft Glas;
   seit iOS 26 ist der Large-Title-Bereich oben offen, und das Material
   erscheint erst beim Scrollen.

   Geschaltet wird das von scroll-edge.js über die Klasse `is-scrolled`, ab
   8 px Scrollweg. Das ist eine ANDERE Schwelle als `collapsed` (28 px, siehe
   unten beim großen Titel) und macht ausschließlich das Material — den Titel
   fasst sie nicht an. Zwei Schwellen sind Absicht: Das Glas soll früh
   kommen, damit Inhalt nie unter einer offenen Leiste durchläuft; der Titel
   soll spät weichen, damit er nicht bei jeder Fingerbewegung springt. */
.navbar {
  position: sticky; top: 0; z-index: 50;
  padding-top: env(safe-area-inset-top);
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom: .5px solid transparent;
  transition:
    background .2s ease,
    border-color .2s ease,
    -webkit-backdrop-filter .2s ease,
    backdrop-filter .2s ease;
}
.navbar.is-scrolled {
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  /* Glaskante statt grauer Trennlinie, dazu das Licht auf der Innenseite
     der freien Unterkante. Zusammen ergibt das die Doppellinie, an der man
     Liquid Glass erkennt: aussen dunkler Saum, innen heller Grat. */
  border-bottom-color: var(--glass-stroke);
  box-shadow: inset 0 -.5px 0 0 var(--glass-highlight);
}
.navbar.collapsed { border-bottom-color: var(--glass-stroke); }
.navbar-row { height: 44px; display: flex; align-items: center; padding: 0 var(--gutter); gap: var(--s3); }
.navbar-title {
  flex: 1; text-align: center;
  font-size: 17px; font-weight: 600; letter-spacing: -.43px;
  opacity: 0; transform: translateY(6px);
  transition: opacity .18s ease, transform .18s ease;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.navbar.collapsed .navbar-title { opacity: 1; transform: none; }
.navbar-action {
  min-width: 44px; min-height: 44px;
  display: flex; align-items: center; justify-content: center;
  color: var(--blue); font-size: 17px; letter-spacing: -.43px;
}
/* Zurueck nach Apples Original: ein runder Knopf 44x44 mit NUR dem
   Chevron. Die Beschriftung „Zurück" faellt weg — in iOS 26 traegt der
   Knopf keine mehr.

   Sie wird nicht geloescht, sondern nur unsichtbar gemacht: Ein
   Vorlesewerkzeug braucht sie weiterhin, und ein Knopf, der nur aus einem
   Zeichen besteht, waere sonst unbeschriftet. */
.navbar-action.left {
  flex: none; width: 44px; min-width: 44px; height: 44px;
  justify-content: center;
  border-radius: 50%;
  background: var(--fill);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: inset 0 0 0 .5px var(--glass-stroke),
              inset 0 1px 0 -.5px var(--glass-highlight);
}
.navbar-action.left span {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.navbar-action.right { justify-content: flex-end; }
.navbar-action.hidden { visibility: hidden; }

/* Der große Titel weicht beim Scrollen dem kleinen in der Leiste — in iOS
   wandert er mit dem Inhalt nach oben weg, sobald der kleine erscheint.
   Hier hängt er in der festen Leiste und kann nicht mitwandern, also klappt
   er stattdessen zu. Ohne das stünden beide Titel gleichzeitig da, und
   „Einstellungen" läse sich zweimal untereinander.

   Zusammengeklappt wird über die Höhe, nicht über display:none — sonst
   spränge die Leiste, statt sich zu bewegen.

   Geschaltet von `collapsed`, das app.js ab 28 px Scrollweg setzt. */
.large-title {
  padding: 0 var(--gutter) var(--s2);
  overflow: hidden; max-height: 96px; opacity: 1;
  transition: max-height .24s ease, opacity .16s ease, padding-bottom .24s ease;
}
.navbar.collapsed .large-title { max-height: 0; opacity: 0; padding-bottom: 0; }

/* Die Schrift SCHRUMPFT beim Zuklappen auf das Maß des kleinen Titels.

   Ohne das fuhr der große Titel in voller Größe (34 px) nach oben aus dem
   Bild, während in der Zeile darüber der kleine (17 px) einblendete — zwei
   Größen ohne Übergang dazwischen. Weil beide Bewegungen gleich lang dauern
   (.24s), treffen sich die zwei Titel jetzt in Größe und Gewicht; das ist der
   Morph, den iOS zeigt.

   Der Selektor MUSS auf das `h1` zielen: Auf `.large-title` selbst sitzt
   keine Schriftgröße, eine Regel dort bliebe wirkungslos. */
.large-title h1 {
  margin: 0; font-size: 34px; font-weight: 700; letter-spacing: .37px; line-height: 41px;
  transition: font-size .24s ease, line-height .24s ease, letter-spacing .24s ease;
}
/* Ab 17 Zeichen eine Nummer kleiner (app.js setzt die Klasse): So bleibt auch
   ein langer Spielname einzeilig, statt den Bildschirm nach unten zu drücken. */
.large-title.lang h1 { font-size: 27px; letter-spacing: 0; line-height: 33px; }
/* Um eine Klasse spezifischer als `.large-title.lang h1` — deshalb morphen
   auch lange Titel auf dasselbe Ziel. Das Gewicht läuft bewusst nicht mit:
   Außerhalb variabler Schriften springt es ohnehin, und während des
   Ausblendens sieht das niemand. */
.navbar.collapsed .large-title h1 {
  font-size: 17px; line-height: 22px; font-weight: 600; letter-spacing: -.43px;
}
/* Das `h1` muss hier mitstehen, nicht nur der Kasten: Seit dem Morph hängt
   die Titel-Bewegung an der Überschrift, und der Kasten allein zu bremsen
   ließe die Schrift weiterlaufen. */
@media (prefers-reduced-motion: reduce) {
  .navbar,
  .large-title,
  .large-title h1 { transition: none; }
}
.large-title .sub {
  display: block; font-size: 13px; font-weight: 400; letter-spacing: -.08px;
  color: var(--label-2); margin-top: 2px;
}

/* ── Bühne und Scrollbereich ──────────────────────────────────
   Die Bühne hält beim Bildschirmwechsel zwei Scrollbereiche übereinander:
   den abtretenden (eine reglose Kopie) und den ankommenden. Sie schneidet ab,
   damit der hereinfahrende Bildschirm nicht neben dem Rahmen sichtbar wird. */
.buehne { position: relative; flex: 1; overflow: hidden; }

.scroll {
  position: absolute; inset: 0;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  /* Der sichere Bereich unten gehört jetzt der Tab-Leiste — hier bleibt nur
     der Abstand, den der Inhalt zum unteren Rand braucht. */
  padding-bottom: 24px;
  background: var(--bg);
  /* Kein Scrollbalken: Auf einem Telefon gibt es keinen, und auf dem Rechner
     verrät ein Balken am Rand sofort, dass hier eine Webseite läuft. */
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Das Gummiband endet hier, statt sich auf die Seite dahinter
     fortzupflanzen — sonst wackelt beim Überziehen der ganze Rahmen. */
  overscroll-behavior-y: contain;
}
.scroll::-webkit-scrollbar { display: none; }
/* Vollflächige Ansichten (die Karte): Der Inhalt füllt die Bühne randlos und
   bringt sein eigenes Scrollen mit — hier wird nicht gescrollt. */
.scroll.voll { padding: 0; overflow: hidden; }

/* ── Bildschirmwechsel: schieben statt umschalten ─────────────
   Das ist der Unterschied zwischen einer Website und einer App. In iOS
   schiebt sich der neue Bildschirm von rechts herein, während der alte ein
   Stück nach links mitgeht (Parallaxe: er bewegt sich langsamer, etwa ein
   Drittel der Strecke). Zurück läuft dasselbe rückwärts.

   Zeitkurve und Dauer wie beim Blatt von unten — es ist dieselbe Bewegung. */
.scroll.abtretend { pointer-events: none; }

@keyframes bs-rein-vor      { from { transform: translateX(100%); } to { transform: none; } }
@keyframes bs-raus-vor      { from { transform: none; } to { transform: translateX(-28%); } }
@keyframes bs-rein-zurueck  { from { transform: translateX(-28%); } to { transform: none; } }
/* `--wisch` ist der Punkt, an dem der Finger den Bildschirm losgelassen hat.
   Ohne das würde er nach dem Wischen erst auf 0 zurückspringen und dann
   hinausfahren. Ohne Wischen steht der Wert auf 0 und nichts ändert sich. */
@keyframes bs-raus-zurueck  { from { transform: translateX(var(--wisch, 0px)); } to { transform: translateX(100%); } }

.wechsel-vor .scroll:not(.abtretend)     { animation: bs-rein-vor .35s cubic-bezier(.32,.72,0,1) both; z-index: 2; }
.wechsel-vor .scroll.abtretend           { animation: bs-raus-vor .35s cubic-bezier(.32,.72,0,1) both; z-index: 1; }
.wechsel-zurueck .scroll:not(.abtretend) { animation: bs-rein-zurueck .35s cubic-bezier(.32,.72,0,1) both; z-index: 1; }
.wechsel-zurueck .scroll.abtretend       { animation: bs-raus-zurueck .35s cubic-bezier(.32,.72,0,1) both; z-index: 2; }

/* Der abtretende Bildschirm bekommt beim Vorwärtsgehen einen Schatten an der
   Kante — in iOS liegt der neue Bildschirm sichtbar über dem alten. */
.wechsel-vor .scroll:not(.abtretend),
.wechsel-zurueck .scroll.abtretend { box-shadow: -3px 0 12px rgba(0,0,0,.28); }

/* Wischen mit dem Finger: Solange gezogen wird, folgt der Bildschirm ohne
   Zeitkurve — sonst hinkt er hinterher. */
.buehne.zieht .scroll { animation: none; transition: none; }

/* Wer Bewegung reduziert haben möchte, bekommt den Wechsel ohne Schieben.
   Die Bildschirme wechseln dann so, wie sie es vorher taten. */
@media (prefers-reduced-motion: reduce) {
  .wechsel-vor .scroll, .wechsel-zurueck .scroll { animation: none; box-shadow: none; }
}

/* ── Gruppierte Listen (Einstellungen-Stil) ─────────────────
   16px statt der 12px aus `--r-box`: iOS 26 hat die Inset-Grouped-Container
   spürbar runder gemacht. Der Wert steht ABSICHTLICH hier und nicht im Token
   — `--r-box` hängt an sieben kleineren Flächen (.stat, .cs-tabelle,
   Karten-Popup, Diplomatie-Hinweise); auf denen sähen 16px aufgeblasen aus.
   Wer den Radius irgendwann überall anhebt, ändert das Token und löscht
   diese Zeile.

   Das Token hieß bis zum 30.08.2026 `--r-group` — ein Name, der nach dem
   Bauteil hier klang, es aber seit dem Radiuswechsel gerade NICHT mehr
   bediente. */
.group {
  background: var(--bg-elev);
  /* Feine Kante auch auf undurchsichtigen Flaechen: In iOS 26 ist jede
     erhoehte Flaeche gegen ihren Grund abgesetzt, nicht nur das Glas. */
  box-shadow: inset 0 0 0 .5px var(--glass-stroke);
  border-radius: 16px;
  margin: 0 var(--gutter) var(--s5);
  overflow: hidden;
}
/* 39 hoch nach Apples „Section Title" (vorher 45): 14 oben + 17 Schrift
   + 8 unten. Das waagerechte Innenmass von 16 stimmte bereits. */
.group-header {
  padding: 14px var(--gutter) var(--s2);
  font-size: 13px; letter-spacing: -.08px;
  color: var(--label-2); text-transform: uppercase;
}
.group-footer {
  margin: -12px var(--gutter) var(--s5);
  padding: var(--s2) 4px 0;
  font-size: 13px; color: var(--label-2); line-height: 1.35;
}
/* Masse aus Apples Kit (iOS 27, „Row"): einzeilig 52 hoch, zweizeilig 68,
   waagerechtes Innenmass 16. Apple setzt die Hoehe fest; im Web waechst
   eine Zeile mit ihrem Inhalt, deshalb Mindesthoehe plus Innenmass:
   einzeilig ergibt das 52, zweizeilig 67 — ein Pixel unter Apple, dafuer
   ohne feste Hoehe, die langen Text abschneiden wuerde.
   Bis 30.08.2026 standen hier 44 und 11 — beides aus der Zeit vor dem
   Kit-Abgleich. */
.row {
  display: flex; align-items: center; gap: var(--s3);
  min-height: 52px; padding: 13px var(--s4);
  position: relative; width: 100%; text-align: left;
}
.row + .row::before {
  content: ""; position: absolute; top: 0; left: var(--s4); right: 0;
  height: .5px; background: var(--separator);
}
/* Der Einzug ist EINHEITLICH 16px und fluchtet damit mit dem Zeilentext.

   Bis 30.08.2026 rückte `.row.inset + .row.inset::before` ihn auf 56px ein —
   der Abstand, der zu einem 29px-Symbol plus 12px Lücke passt. Die Klasse
   stand aber an 35 von 46 Stellen an Zeilen OHNE Symbol: alle
   Einstellungen-Gruppen, die Bank, die Diplomatie. Dort schwebte die Linie
   40px rechts vom Text, und weil `.inset` sonst keine Regel trug, fiel es
   niemandem als Ursache auf. Regel und Klasse sind beide entfernt.

   Wer die Linie für Zeilen MIT Symbol wieder am Text ausrichten will,
   braucht eine Kennzeichnung, die wirklich nur an solchen Zeilen steht — die
   alte war es nachweislich nicht. Über den Inhalt geht es auch: Die
   führenden Elemente sind uneinheitlich (`.row-icon`, `.avatar`, `.rank`,
   blankes `<img>`), ein `:has()` müsste sie alle aufzählen und bei jedem
   neuen mitwachsen. */
button.row:active, a.row:active { background: var(--fill); }
/* Listenzeilen sind keine Links, auch wenn sie technisch welche sind: In iOS
   zeigt der Pfeil rechts an, dass es weitergeht — blauer Text tut es nicht. */
a.row, a.card { color: inherit; text-decoration: none; }
.row-icon {
  width: 29px; height: 29px; flex: none; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 15px;
}
.row-body { flex: 1; min-width: 0; }
.row-title { font-size: 17px; letter-spacing: -.43px; }
.row-sub { font-size: 13px; color: var(--label-2); margin-top: 2px; letter-spacing: -.08px; }
.row-value { font-size: 17px; color: var(--label-2); letter-spacing: -.43px; flex: none; }
.chev { width: 7px; height: 12px; flex: none; color: var(--label-3); }

/* ── Karten ───────────────────────────────────────────────── */
.card {
  background: var(--bg-elev); border-radius: var(--r-card);
  padding: var(--s4); margin: 0 var(--gutter) var(--s4);
  box-shadow: var(--shadow);
}
.card-dunkel { color: #fff; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; padding: var(--s5) var(--gutter) var(--s3); }
.section-head h2 { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -.26px; }

/* ── Segmentierter Umschalter ─────────────────────────────── */
/* Maße aus dem Apple-Kit (Controls/Segmented Controls/Light/3 Buttons,
   Knoten 0:6510): Gesamthöhe 32 px, Spur rgba(118,118,128,.12) mit Radius
   8,91 px, Pille 2 px eingerückt mit Radius 6,93 px, Beschriftung 13 px bei
   18 px Zeilenhöhe — unausgewählt Regular, ausgewählt Semibold.

   32 px ist niedriger als die 44-px-Regel dieses Stylesheets. Das ist hier
   richtig so: Genau so hoch ist das Bauteil auf einem iPhone auch, und die
   Trefferfläche wächst über den Außenabstand, nicht über die Bauhöhe. */
.segmented {
  display: flex; height: 32px; align-items: stretch;
  background: var(--fill); border-radius: var(--r-pill); padding: 2px;
  /* 4px zwischen den Segmenten — sie ersetzen die frueheren Trennstriche. */
  gap: 4px;
  margin: 0 var(--gutter) var(--s4);
}
.segmented button {
  flex: 1; position: relative; border-radius: var(--r-pill);
  font-size: 13px; font-weight: 400; line-height: 18px;
  letter-spacing: -.08px; color: var(--label);
  transition: background .2s ease;
}
.segmented button[aria-selected="true"] {
  background: var(--seg-pille); font-weight: 600;
  border: .5px solid rgba(0,0,0,.04);
  box-shadow: 0 3px 8px rgba(0,0,0,.12), 0 3px 1px rgba(0,0,0,.04);
}
/* Die Trennstriche zwischen unausgewaehlten Segmenten sind entfallen: In
   iOS 27 trennt eine 4px-Luecke die Segmente, kein Strich mehr. Sie standen
   hier seit dem iOS-18-Kit. */

/* ── Schalter ─────────────────────────────────────────────── */
/* 64x28 mit einem KAPSELFOERMIGEN Knauf 38x24 — nicht mehr 51x31 mit
   rundem Knauf. Der Schalter ist damit breiter und flacher als die
   klassische Form, und der Knauf laenglich statt kreisrund. Masse aus
   Apples „Toggle - Switch" (iOS 27); die alten stammten aus dem
   iOS-18-Kit. Weg des Knaufs: 64 − 2 − 2 − 38 = 22px. */
.switch {
  width: 64px; height: 28px; border-radius: var(--r-pill);
  background: var(--fill-2); position: relative; flex: none;
  transition: background .25s cubic-bezier(.4,0,.2,1);
}
.switch::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 38px; height: 24px; border-radius: var(--r-pill); background: #fff;
  box-shadow: 0 3px 8px rgba(0,0,0,.15);
  transition: transform .25s cubic-bezier(.4,0,.2,1);
}
.switch[aria-checked="true"] { background: var(--green); }
.switch[aria-checked="true"]::after { transform: translateX(22px); }

/* ── Schaltflächen ────────────────────────────────────────── */
/* Kapsel statt gerundetem Rechteck: Apples „Button - Liquid Glass" hat
   Radius 1000 in allen drei Groessen. Die Hoehe von 50 entspricht Apples
   „Large" und stimmte bereits; das waagerechte Innenmass von 20 kommt neu
   dazu — ohne stand der Text bei Knoepfen, die nicht ueber die volle
   Breite gehen, an der Kante. */
.btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 50px; padding: 0 20px; border-radius: var(--r-pill);
  font-size: 17px; font-weight: 600; letter-spacing: -.43px;
  transition: opacity .15s ease;
}
.btn:active { opacity: .6; }
.btn:disabled { opacity: .4; }
.btn-primary { background: var(--blue); color: #fff; }
.btn-tinted { background: color-mix(in srgb, var(--blue) 15%, transparent); color: var(--blue); }
.btn-danger { background: color-mix(in srgb, var(--red) 15%, transparent); color: var(--red); }
.btn-gray { background: var(--fill); color: var(--label); }
.btn-block { margin: 0 var(--gutter) var(--s4); width: calc(100% - var(--gutter) * 2); }

/* ── Marken / Punkte ──────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 9px; border-radius: var(--r-pill);
  font-size: 12px; font-weight: 600; letter-spacing: -.08px;
  background: var(--fill); color: var(--label-2);
}
.pill.green { background: color-mix(in srgb, var(--green) 18%, transparent); color: var(--green); }
.pill.red { background: color-mix(in srgb, var(--red) 18%, transparent); color: var(--red); }
.pill.blue { background: color-mix(in srgb, var(--blue) 18%, transparent); color: var(--blue); }
.pill.orange { background: color-mix(in srgb, var(--orange) 18%, transparent); color: var(--orange); }

.avatar {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 600; color: #fff; letter-spacing: -.2px;
  background: var(--indigo); overflow: hidden;
}
.avatar.lg { width: 88px; height: 88px; font-size: 34px; }
.avatar.sm { width: 28px; height: 28px; font-size: 12px; }

/* ── Statistik-Kacheln ────────────────────────────────────── */
.stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); margin: 0 var(--gutter) var(--s4); }
/* 22px wie `.konto` daneben, nicht 12 aus `--r-box`: Auf dem Profil stehen
   beide Kartenreihen direkt uebereinander (Bargeld/Bank, darunter
   Kills/Tode/K-D) — mit verschiedenen Ecken sah das nach Versehen aus.
   Apples `radius/card` ist 22 und gilt fuer „Karten, Widgets"; diese
   Kacheln sind genau das. Gefunden beim Gesamtblick, nicht beim Messen der
   Einzelteile. */
.stat { background: var(--bg-elev); border-radius: 22px; padding: var(--s3) var(--s2); text-align: center; }
.stat .v { font-size: 22px; font-weight: 700; letter-spacing: -.4px; font-variant-numeric: tabular-nums; }
.stat .k { font-size: 11px; color: var(--label-2); margin-top: 3px; letter-spacing: -.08px; }

/* ── Zwei Geldtöpfe ───────────────────────────────────────────
   Bargeld und Bank stehen IMMER nebeneinander. Einen davon allein zu zeigen
   ist die häufigste Quelle für „warum reicht mein Geld nicht?". */
.konten { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); margin: 0 var(--gutter) var(--s4); }
/* Die Kennzahl-Karte (Bargeld/Bank in Löwenplay und in der Geldbörse).
   Maße nach dem Entwurf: 22px Radius, 12px oben / 14px unten / 16px seitlich,
   4px zwischen Beschriftung und Wert, Beschriftung auf Footnote (13px).
   Die Akzentfarben stehen zwei Zeilen tiefer und waren schon richtig. */
.konto { background: var(--bg-elev); border-radius: 22px; padding: 12px 16px 14px; }
.konto .k { font-size: 13px; color: var(--label-2); }
.konto .v { font-size: 22px; line-height: 28px; font-weight: 700; font-variant-numeric: tabular-nums; margin-top: 4px; }
.konto.bar .v { color: var(--green); }
.konto.bank .v { color: var(--blue); }

/* ── Amazon (Shop) ──────────────────────────────────────────
   Aufbau der Amazon-App: Suchleiste, „Liefern an"-Zeile, Kategorienstreifen,
   Produktraster. Der Akzent ist das Amazon-Orange — es gilt nur in dieser
   App, wie das Grün nur in den Kleinanzeigen gilt.

   Listenzeile, Preisformatierung, Lupenknopf und Trefferzeile stammen aus
   der Vorlage „Amazon UI Design (Community)" - Komponenten `Product`,
   `searchbar` und `result & sort`. Das Deal-Band behielt dabei Amazons
   echtes #CC0C39 statt des #B12704 der Vorlage. Bewertungssterne zeigt die
   Vorlage auch - die fehlen hier, weil der Shop keine Bewertungen kennt.

   Der KOPFBEREICH der Vorlage ist dagegen ueberholt: Sie zeigt die Website
   von 2021 mit dunkelblauer Leiste und gelbem Lupenknopf rechts. Die App
   von heute hat einen farbigen Kopf und die Lupe links - siehe
   „Amazons Kleid" weiter unten. */

/* Amazons Preisrot. Hell ist Amazons eigener Wert; dunkel eine Aufhellung
   desselben Farbtons - #B12704 steht auf dunklem Grund bei rund 2:1 und
   wäre dort unlesbar. Amazons Palette ist für weißen Grund gebaut. */
:root { --az-rot: #B12704; }
[data-theme="dark"] { --az-rot: #FF6E6B; }

/* Amazons Akzentorange. Hell #C45500 (Amazons eigener Wert für Text auf
   Weiß, so auch in der Vorlage), dunkel das Markenorange #FF9900 - auf
   hellem Grund käme #FF9900 nur auf 2,2:1. */
:root { --az-orange: #C45500; }
[data-theme="dark"] { --az-orange: #FF9900; }

/* Suchleiste mit dem gelben Lupenknopf rechts — Amazons auffälligstes
   Erkennungszeichen. Der Block misst 45px breit wie in der Vorlage; die
   Höhe wächst von 36 auf Amazons 40. Der Radius bleibt bei 10: die Vorlage
   zeigt mit 4 die Website, Amazons App rundet stärker. */
.az-suchknopf {
  display: flex; align-items: center; gap: var(--s2);
  width: calc(100% - var(--gutter) * 2); margin: 0 var(--gutter) var(--s2);
  min-height: 40px; padding: 0 0 0 12px; border-radius: 10px; overflow: hidden;
  background: var(--fill); color: var(--label-2);
  font-size: 17px; letter-spacing: -.43px; text-align: left;
}
.az-suchknopf:active { opacity: .6; }

.az-kats {
  display: flex; gap: var(--s2); overflow-x: auto; scrollbar-width: none;
  padding: 0 var(--gutter) var(--s4);
}
.az-kats::-webkit-scrollbar { display: none; }
.az-kat {
  flex: none; min-height: 34px; padding: 0 14px; line-height: 34px;
  border-radius: var(--r-pill); background: var(--fill); color: var(--label);
  font-size: 14px; white-space: nowrap; text-decoration: none;
}

.az-raster {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3);
  padding: 0 var(--gutter) var(--s4);
}
@media (min-width: 620px) { .az-raster { grid-template-columns: repeat(3, 1fr); } }
.az-kachel {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: var(--bg-elev); border-radius: var(--r-card); overflow: hidden;
  box-shadow: var(--shadow);
}
.az-kachel:active { opacity: .7; }
.az-bild {
  position: relative; aspect-ratio: 1 / 1; background: var(--fill);
  display: flex; align-items: center; justify-content: center; font-size: 40px;
}
/* `contain`, nicht `cover`: Artikelbilder sind freigestellte Gegenstände —
   ein Beschnitt würde ihnen die Hälfte abschneiden. */
.az-bild img { width: 100%; height: 100%; object-fit: contain; padding: 8px; }
.az-band {
  position: absolute; left: 0; top: 8px; padding: 3px 8px;
  background: #CC0C39; color: #fff; font-size: 11px; font-weight: 700;
  border-radius: 0 var(--r-pill) var(--r-pill) 0;
}
.az-band.fest { position: static; border-radius: var(--r-pill); }
.az-info { padding: var(--s3); display: flex; flex-direction: column; gap: 3px; }
.az-name {
  font-size: 14px; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* Preiszeile nach der Vorlage: Preis in Amazons Rot und mittlerer Stärke
   (nicht fett), alter Preis klein und durchgestrichen, dahinter die
   Ersparnis in Zahl und Prozent. Die Ersparnis steht in der normalen
   Textfarbe — sie ist die Rechnung, nicht der Reiz. */
.az-preisreihe { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.az-preis { font-size: 17px; font-weight: 500; letter-spacing: -.4px; color: var(--az-rot); }
.az-alt { font-size: 13px; color: var(--label-2); text-decoration: line-through; }
.az-spare { font-size: 14px; color: var(--label); }
.az-preisreihe.gross .az-preis { font-size: 26px; letter-spacing: -.6px; }
/* Bleibt im iOS-Rot: eine gesperrte Rolle ist ein Zustand des Kontos, keine
   Handelsangabe — anders als die Knappheitszeile in der Listenzeile. */
.az-sperre { font-size: 12px; color: var(--red); }

/* Listenzeile der Suchergebnisse — Amazons Trefferdarstellung aus `Product`:
   Bild links auf einem Viertel der Breite, rechts eine senkrechte Reihe mit
   8px Abstand. Auf dem Start-Bildschirm bleibt das Kachelraster: Amazon zeigt
   beim Stöbern Kacheln und erst bei Treffern Zeilen. */
.az-liste { padding: 0 var(--gutter) var(--s4); }
.az-zeile {
  display: flex; gap: var(--s3); align-items: flex-start;
  padding: var(--s4) 0; text-decoration: none; color: inherit;
}
.az-zeile + .az-zeile { border-top: .5px solid var(--separator); }
.az-zeile:active { opacity: .7; }
.az-zbild {
  flex: none; width: 104px; height: 104px; border-radius: var(--r-box);
  background: var(--fill); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.az-zbild img { width: 100%; height: 100%; object-fit: contain; padding: 6px; }
.az-ztext { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.az-ztitel {
  font-size: 17px; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
/* Das Band soll so breit sein wie sein Text, nicht so breit wie die Spalte. */
.az-ztext .az-band { align-self: flex-start; }
.az-zeile .az-preis { font-size: 21px; }
/* Amazons „Only 2 left in stock" — dieselbe Farbe wie der Preis. */
.az-knapp { font-size: 13px; color: var(--az-rot); }

/* Der Shop benutzt die Filterchips der Kleinanzeigen mit, und die tragen seit
   dem Marktplatz das Markt-Grün. In Amazons App wäre Grün falsch. Orange mit
   dunkler Schrift ist dieselbe Paarung wie beim Kaufknopf und die einzige,
   die in beiden Themen trägt: Weiß auf #FF9900 käme nur auf 2,1:1. */
[data-bildschirm="shop-suchen"] .mk-chip.an { background: #FF9900; color: #0F1111; }

/* Trefferzeile nach `result & sort`. Amazons Sortierknopf fehlt bewusst: die
   Shop-API kennt keine Sortierung, und ein Knopf ohne Wirkung ist schlimmer
   als keiner. */
.az-treffer { padding: 0 var(--gutter) var(--s3); font-size: 14px; color: var(--label-2); }
.az-treffer b { color: var(--az-orange); font-weight: 700; }

/* ── Amazons Kleid ──────────────────────────────────────────
   Nach der ECHTEN App (Bildschirmfoto des Betreibers, 31.08.2026) — NICHT
   nach der Figma-Vorlage. Die ist von 2021 und zeigt die Website mit
   dunkelblauem Kopf; die App von heute sieht anders aus:

     grüner Kopf statt dunkelblau
     weiße Pillen-Suchleiste, Lupe LINKS, keine gelbe Taste
     Lieferort als Chip in der Chipreihe, nicht als eigene Zeile
     rote Rabattbänder unten links auf der Kachel
     weiße, flache Tab-Leiste
     KEIN DUNKELMODUS

   Wo Vorlage und echte App auseinandergehen, gilt ab hier die App. */

/* Die App ist IMMER hell. Amazons App kennt keinen Dunkelmodus, und ein
   halb umgefärbtes Amazon wäre schlimmer als gar keins. Die Werte sind die
   des Hellmodus-Blocks ganz oben, eins zu eins übernommen.

   `:root[data-app=…]` und nicht bloß `[data-app=…]`: Beide Attribute sitzen
   am SELBEN Element, und `[data-theme="dark"]` ist gleich stark. Ohne das
   `:root` entschiede allein die Reihenfolge im Blatt — ein Stolperdraht für
   den Nächsten, der etwas verschiebt. */
:root[data-app="amazon"] {
  color-scheme: light;
  --bg: #FFFFFF;
  --bg-elev: #FFFFFF;
  --bg-elev-2: #F2F2F7;
  --fill: rgba(120,120,128,.20);
  --fill-2: rgba(118,118,128,.16);
  --seg-pille: #FFFFFF;
  --label: #0F1111;
  --label-2: #565959;
  --label-3: rgba(60,60,67,.42);
  --separator: rgba(60,60,67,.20);
  --glass-stroke: rgba(255,255,255,.50);
  --glass-highlight: rgba(255,255,255,.60);
  --bar: rgba(255,255,255,.92);
  --sheet: #FFFFFF;
  --shadow: 0 1px 2px rgba(0,0,0,.06);
  --scrim: rgba(0,0,0,.4);
  /* Amazons eigene Töne bleiben auf den Hellmodus-Zahlen — der Grund ist
     in dieser App immer weiß. */
  --az-rot: #B12704;
  --az-orange: #C45500;
  /* Der Farbton des Kopfes. Drei Stufen: oben heller, Mitte, unten satter.
     Sie leiten sich alle aus `--az-ton` ab, den app.js beim Wischen durch
     das Angebotskarussell umsetzt (azKarussellFarbe) — „der farbige
     Hintergrund wechselt beim Swipen der Angebote".

     Gemischt wird in oklch und nicht in srgb: Ein Mischen mit Schwarz in
     srgb frisst die Sättigung, und aus dem Rosa der vierten Karte würde
     ein Braun. */
  --az-gruen-0: color-mix(in oklch, var(--az-ton) 88%, #fff);
  --az-gruen: var(--az-ton);
  --az-gruen-2: color-mix(in oklch, var(--az-ton) 86%, #000);
}

/* Anfangston, bis das Karussell den ersten gemeldet hat — das Grün, mit dem
   die App startet. Steht am Wurzelelement, weil die Navigationsleiste
   außerhalb des Scrollbereichs liegt und dieselbe Farbe tragen muss. */
:root { --az-ton: #4BE578; }

/* Der Grundton, mit dem die App startet und zu dem alle Bildschirme außer
   der Startseite zurückkehren. */
:root { --az-basis: #4BE578; }

/* Dem Karussell folgt NUR die Startseite. Sonst trüge die Produktseite Rosa,
   bloß weil jemand zuletzt an einer rosa Angebotskarte stand — Zufall statt
   Gestaltung.

   ACHTUNG, das geht NICHT über die Variable: `azKarussellFarbe` setzt
   `--az-ton` als INLINE-Stil am Wurzelelement, und ein Inline-Stil schlägt
   jede Blattregel, egal wie spezifisch sie ist. Ein
   `[data-app]:not([data-bildschirm="shop"]) { --az-ton: … }` wäre wirkungslos
   gewesen — genau so ist es mir zuerst passiert. Überschrieben wird deshalb
   die REGEL, nicht die Variable. */
[data-app="amazon"]:not([data-bildschirm="shop"]) .navbar,
[data-app="amazon"]:not([data-bildschirm="shop"]) .navbar.is-scrolled {
  background: linear-gradient(180deg,
    color-mix(in oklch, var(--az-basis) 88%, #fff) 0%,
    var(--az-basis) 55%,
    color-mix(in oklch, var(--az-basis) 86%, #000) 100%);
}

/* Kopf: grün und deckend, kein Glas, keine Unschärfe. Die Glasregeln weiter
   oben müssen mit überschrieben werden — auch `is-scrolled` und die Kanten,
   sonst käme die Glaskante beim Scrollen zurück. */
[data-app="amazon"] .navbar,
[data-app="amazon"] .navbar.is-scrolled {
  /* Der helle Ton stand hier als fester Wert (#5BEA85) und ist jetzt eine
     Variable — sonst bliebe die Leiste beim Farbwechsel oben grün und
     spränge unten um. */
  background: linear-gradient(180deg, var(--az-gruen-0) 0%, var(--az-gruen) 55%, var(--az-gruen-2) 100%);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-bottom-color: transparent; box-shadow: none;
  transition: background .45s ease;
}
/* Auf dem Grün steht die Schrift dunkel, nicht weiß — so wie in der App. */
[data-app="amazon"] .navbar,
[data-app="amazon"] .navbar .large-title h1,
[data-app="amazon"] .navbar .navbar-title { color: #0F1111; }
[data-app="amazon"] .navbar .large-title .sub { color: rgba(15,17,17,.62); }
[data-app="amazon"] .navbar-action.left {
  background: rgba(255,255,255,.55); color: #0F1111; box-shadow: none;
}

/* Das Wortzeichen: klein geschrieben und eng, darunter der orange Bogen.
   Die Schrift bleibt die des Systems — Amazon Ember ist laut dem Style
   Guide der Vorlage nicht lizenzierbar und wird deshalb nicht eingebettet.

   ABWEICHUNG VON DER ECHTEN APP, mit Absicht: Dort steht auf der Startseite
   GAR KEIN Titel, nur Suchleiste und Chips. Das kann sich eine echte App
   leisten — im Portal ist Amazon eine App unter vielen, zwischen denen man
   hin und her springt, und ein Bildschirm ohne Namen wäre dort eine
   Zumutung. Wer das anders sieht, löscht diese beiden Regeln.

   Der Anker ist `[data-bildschirm="shop"]` und NICHT `[data-app]`: Das
   Wortzeichen ist eine Marke, kein Schriftschnitt. Hing es an der App,
   wurde aus „Suchen" ein „suchen" mit Bogen. */
[data-bildschirm="shop"] .large-title h1 {
  text-transform: lowercase; font-weight: 800; letter-spacing: -1.4px;
}
[data-bildschirm="shop"] .large-title h1::after {
  content: ""; display: block; width: 112px; height: 17px; margin-top: -3px;
  background: no-repeat center/contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 20'%3E%3Cpath d='M4 4c16 11 38 15 57 15 17 0 36-4 51-13' fill='none' stroke='%23FF9900' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M104 14 120 1 116 18z' fill='%23FF9900'/%3E%3C/svg%3E");
}
/* Zusammengeschoben trägt die Leiste den Titel klein und mittig — ein Bogen
   unter einem 17-px-Wort wäre breiter als das Wort. */
[data-bildschirm="shop"] .navbar.collapsed .large-title h1::after { display: none; }

/* Suchleiste und Chips sitzen im grünen Kopf und nicht im Inhalt. Der Block
   führt das Grün der Navigationsleiste randlos weiter. */
.az-kopfblock {
  background: linear-gradient(180deg, var(--az-gruen-2) 0%, var(--az-gruen-2) 100%);
  padding: var(--s2) 0 var(--s3); margin-bottom: var(--s4);
}

/* Angebotskarussell. Jede Karte trägt ihre eigene Farbe und gibt sie beim
   Wischen an den Kopf weiter (azKarussellFarbe in app.js). 84 % Breite,
   damit die nächste Karte angeschnitten sichtbar bleibt — erst das lädt zum
   Wischen ein. */
.az-karussell {
  display: flex; gap: var(--s3); overflow-x: auto; scrollbar-width: none;
  padding: var(--s4) var(--gutter) var(--s2);
  scroll-snap-type: x mandatory;
}
.az-karussell::-webkit-scrollbar { display: none; }
.az-angebot {
  flex: none; width: 84%; scroll-snap-align: start;
  background: var(--az-karte); border-radius: 20px; padding: var(--s4);
}
/* Fett und schwarz — die Überschriften sind das Lauteste auf dem Bildschirm.
   Die Kartentöne sind deshalb hell genug für schwarze Schrift gewählt. */
.az-angebot-titel {
  font-size: 27px; line-height: 1.12; font-weight: 800; letter-spacing: -.6px;
  color: #0F1111; margin-bottom: var(--s3);
}
.az-angebot-raster { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3); }
.az-akachel {
  position: relative; display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1; background: #fff; border-radius: 10px; overflow: hidden;
  text-decoration: none;
}
/* Unten Platz lassen: Dort liegt das Band. */
.az-akachel img { width: 100%; height: 100%; object-fit: contain; padding: 10px 10px 30px; }
.az-akachel-ersatz { color: #565959; }
.az-akachel:active { opacity: .75; }
/* Ohne Rabatt trägt das Band den Preis statt des Prozentsatzes — dann ist es
   keine Werbung mehr und darf nicht rot sein. */
[data-app="amazon"] .az-band.preis { background: #0F1111; }

/* Überschrift über dem Artikelraster. Amazon setzt diese Zeilen groß und
   schwer, nicht als kleine Rubrik. */
.az-modul-titel {
  font-size: 22px; font-weight: 800; letter-spacing: -.5px; color: var(--label);
  padding: var(--s5) var(--gutter) var(--s3);
}

/* Suchfeld: weiße Pille mit der Lupe LINKS. Die gelbe Taste der Vorlage gibt
   es in der App nicht — dort stehen rechts Kamera und Mikrofon, und die
   bilde ich nicht nach: Knöpfe für Funktionen, die es nicht gibt, sind
   schlimmer als keine Knöpfe. */
[data-app="amazon"] .az-suchknopf {
  background: #fff; color: #565959; border-radius: var(--r-pill);
  min-height: 48px; padding: 0 18px; gap: var(--s3);
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
}
[data-app="amazon"] .az-suchknopf .az-lupensymbol { color: #0F1111; flex: none; }

/* Chipreihe im Grün: helle, halbdurchsichtige Pillen. Der Lieferort ist der
   erste Chip — in der App steht dort die Postleitzahl. */
[data-app="amazon"] .az-kats { padding: var(--s3) var(--gutter) 0; }
[data-app="amazon"] .az-kat {
  background: rgba(255,255,255,.60); color: #0F1111; box-shadow: none;
  border-radius: var(--r-pill); min-height: 38px; line-height: 38px;
  padding: 0 16px; font-size: 15px;
}
[data-app="amazon"] .az-kat.az-ort { display: flex; align-items: center; gap: 6px; line-height: 1; }
/* Ohne Lieferort geht keine Bestellung — dann ist der Chip kein Filter mehr,
   sondern eine Aufforderung, und sieht auch so aus. */
[data-app="amazon"] .az-kat.az-ort.fehlt { background: #fff; font-weight: 700; }

/* Produktbilder stehen bei Amazon immer auf Weiß — freigestellte Ware auf
   weißem Grund ist die Bildsprache des Hauses. */
[data-app="amazon"] .az-bild,
[data-app="amazon"] .az-zbild,
[data-app="amazon"] .az-gbild { background: #fff; }

/* Kacheln: weiß, mit 12px gerundet und einer Haarlinie statt der iOS-Karte
   mit 22px und Schatten. */
[data-app="amazon"] .az-kachel {
  border-radius: 12px; box-shadow: inset 0 0 0 1px var(--separator);
}
[data-app="amazon"] .az-zbild { border-radius: 12px; }

/* Das Rabattband sitzt UNTEN LINKS im Bild und ist ein abgerundetes Rechteck
   — in der Vorlage klebte es oben links am Rand. */
[data-app="amazon"] .az-band {
  left: 8px; top: auto; bottom: 8px;
  border-radius: 6px; padding: 4px 9px; font-size: 12px;
}
[data-app="amazon"] .az-band.fest { border-radius: 6px; }

/* Tab-Leiste: weiß und flach wie in der App, aber in der Pillenform des
   Portals — die ist die Klammer, die alle Apps zusammenhält. Form vom
   Portal, Farbe von Amazon. Auf weißem Grund braucht die weiße Leiste eine
   Kante, sonst verschwindet sie. */
[data-app="amazon"] .az-tabs {
  background: #fff;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  box-shadow: inset 0 0 0 1px var(--separator), 0 6px 20px rgba(0,0,0,.16);
}
[data-app="amazon"] .az-tab { color: #565959; }
[data-app="amazon"] .az-tab.an { color: #0F1111; }
[data-app="amazon"] .az-tab.an:not(.mitte) { background: rgba(0,0,0,.06); }

/* Produktseite */
.az-gbild {
  height: 220px; margin: 0 var(--gutter) var(--s3);
  background: var(--bg-elev); border-radius: var(--r-card);
  display: flex; align-items: center; justify-content: center; font-size: 64px;
}
.az-gbild img { max-width: 100%; max-height: 100%; object-fit: contain; }
.az-kopf { padding: 0 var(--gutter) var(--s4); }
.az-gtitel { font-size: 22px; font-weight: 700; letter-spacing: -.4px; line-height: 1.25; }
.az-text {
  padding: 0 var(--gutter) var(--s5);
  font-size: 15px; line-height: 1.45; color: var(--label-2); white-space: pre-wrap;
}
/* Der Kaufknopf in Amazons Gelb — die eine Handlung, für die man die App
   öffnet, und dort seit jeher die auffälligste Fläche des Bildschirms. */
.az-kaufen { background: #FFD814; color: #0F1111; }
.az-kaufen:active { background: #F7CA00; }
.az-gesperrt {
  margin: 0 var(--gutter) var(--s4); padding: var(--s3) var(--s4);
  border-radius: var(--r-box); text-align: center;
  background: color-mix(in srgb, var(--red) 14%, transparent); color: var(--red);
  font-size: 15px; line-height: 1.4;
}

/* Mietartikel: „je Neustart" statt eines durchgestrichenen Preises, und das
   Band sagt „Miete" statt eines Rabatts. */
.az-jeneustart { font-size: 12px; color: var(--label-2); }
.az-band.miete { background: #8E5AF2; }

/* ── Meine Mieten ───────────────────────────────────────────
   Der Restzähler ist die Zahl, um die es geht — er steht groß und mit Balken,
   nicht als Nebensatz. */
.mt-miete {
  background: var(--bg-elev); border-radius: var(--r-card);
  margin: 0 var(--gutter) var(--s3); padding: var(--s4);
}
.mt-miete.vorbei { opacity: .55; }
.mt-miete-name { font-size: 17px; font-weight: 600; letter-spacing: -.43px; }
.mt-miete-rest {
  font-size: 28px; font-weight: 700; letter-spacing: -.5px; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.mt-miete .bar-fort i { background: var(--green); }
.mt-miete.vorbei .bar-fort i { background: var(--label-3); }

/* Tab-Leiste der App: Aufbau siehe „Tab-Leiste der Apps" weiter unten,
   app-eigen ist hier nur das Amazon-Orange. */
/* Das Orange kommt jetzt aus `--az-orange` und wird damit im Hellen zu
   #C45500 — #FF9900 kam auf der hellen Glasleiste nur auf 2,2:1. */
.az-tab.an { color: var(--az-orange); }

/* ── Bestellungen (Sendungen) ───────────────────────────────
   Aufbau einer Sendungsverfolgung: oben die Zahl der laufenden Sendungen,
   darunter die Sendungen nach Zustand gruppiert, im Detail der Verlauf als
   Stationenkette. Der Akzent ist das Paketbraun — es gilt nur hier und hebt
   den Verlauf von den blauen Bedienelementen des Shops ab. */
:root { --sendung: #AC8E68; }

.hm-kopf { text-align: center; padding: var(--s2) var(--gutter) var(--s5); }
.hm-kopf-v { font-size: 40px; font-weight: 700; letter-spacing: -.8px; line-height: 1.1; }
.hm-kopf-k { font-size: 13px; color: var(--label-2); margin-top: 2px; }

/* Das Artikelbild in der Zeile. `contain`, wie bei Amazon: freigestellte
   Gegenstände vertragen keinen Beschnitt. */
.hm-bild {
  width: 40px; height: 40px; flex: none; border-radius: 8px;
  background: var(--fill); overflow: hidden;
  display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.hm-bild img { width: 100%; height: 100%; object-fit: contain; padding: 3px; }
.hm-bild.sm { width: 32px; height: 32px; font-size: 16px; }

/* Kanzel der einzelnen Sendung */
.hm-kanzel { text-align: center; padding: var(--s2) var(--gutter) var(--s5); }
.hm-k-sym { font-size: 40px; line-height: 1; }
.hm-k-titel {
  font-size: 22px; font-weight: 700; letter-spacing: -.45px; line-height: 1.25;
  margin-top: var(--s2);
}
.hm-k-marken { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; margin-top: var(--s3); }

/* Der Verlauf: Stationen an einer senkrechten Linie. Erledigte Stationen
   tragen einen gefüllten Punkt, die offene einen hohlen — dieselbe Sprache
   wie bei einem Paketdienst. */
.hm-verlauf { margin: 0 var(--gutter) var(--s5); }
.hm-station { position: relative; display: flex; gap: var(--s3); padding-bottom: var(--s4); }
/* Die Linie hängt an der Station, nicht am Behälter: So endet sie von selbst
   an der letzten und muss nirgends nachgerechnet werden. */
.hm-station::before {
  content: ""; position: absolute; left: 6px; top: 16px; bottom: 0;
  width: 2px; background: var(--fill-2);
}
.hm-station.letzte::before { display: none; }
.hm-station.letzte { padding-bottom: 0; }
.hm-punkt {
  position: relative; z-index: 1; flex: none;
  width: 14px; height: 14px; margin-top: 3px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--fill-2);
}
.hm-station.an .hm-punkt { background: var(--sendung); border-color: var(--sendung); }
.hm-st-titel { font-size: 17px; font-weight: 600; letter-spacing: -.43px; }
.hm-station:not(.an) .hm-st-titel { color: var(--label-2); }
.hm-st-zeit { font-size: 13px; color: var(--sendung); font-variant-numeric: tabular-nums; margin-top: 1px; }
.hm-st-text { font-size: 13px; color: var(--label-2); line-height: 1.35; margin-top: 3px; }

/* Die Karte zeigt hier nur — gewählt wird der Ort im Shop. Deshalb flacher als
   die Auswahlkarte. Doppelte Klasse mit Absicht: `.karte` steht weiter unten
   im Stylesheet und würde die Höhe sonst zurücksetzen. */
.karte.hm-karte { height: 200px; margin: 0 var(--gutter) var(--s2); }

/* ── Tipico: ClutchCalls Kleid ──────────────────────────────
   Nach der Figma-Vorlage „ClutchCall – Sports Betting App UI Kit (Dark
   Theme)" (lQTevjrY3eiejh1hMxfw3F, 25 Bildschirme, abgenommen am
   31.08.2026). Die Datei führt KEINE Variablen — die Werte hier sind
   deshalb an ihren Bildschirmen gemessen, nicht geschätzt:

     Grund      #18181B  der Bildschirm
     Fläche     #292828  jede Karte, die Tab-Leiste, das Blatt
     Fläche 2   #2D2D2D  Pillen und Felder AUF einer Karte
     Feldrand   #656464  die Linie um ein Eingabefeld
     Akzent     #5FAE53  Quote, Fortschritt, jeder Knopf, der aktive Tab
     Schrift    #F9FAFB  Titel
     Schrift 2  #A4A4A4  Beschriftungen
     Schrift 3  #898989  Nebensachen
     Spur       #D9D9D9  die helle Bahn hinter dem Fortschritt

   Ebenso gemessen: Seitenrand 20, Kartenradius 20, Fortschrittsbalken 8
   hoch, Tab-Leiste 80 hoch bei 10 Seitenrand, Hauptknopf 40 hoch als
   volle Pille.

   DIE APP IST IMMER DUNKEL, auch wenn das Portal hell steht. Die Vorlage
   kennt keinen Hellmodus; eine halb aufgehellte Wett-App sähe schlechter
   aus als gar keine. Dieselbe Entscheidung wie bei Amazon und der Bank,
   nur andersherum.

   ABWEICHUNGEN VON DER VORLAGE, alle mit Absicht:

     * DER AKZENT IST GRÜN, NICHT TIPICO-ROT. Die Vorlage baut ihre ganze
       Ordnung auf einer Farbe: Grün heißt „hier wird gehandelt" und „das
       ist deine Seite". Das Markenrot an dieselbe Stelle zu setzen hieße,
       die Vorlage bloß umzufärben — genau das, was bei Amazon und der
       Bank aufgegeben wurde. Wer es anders will, ändert EINE Zeile:
       `--tp-akzent`. Das Rot bleibt, wo die Marke sitzt: auf dem
       App-Symbol des Home-Bildschirms.
     * QUOTEN KENNT DIE VORLAGE NICHT. ClutchCall verfolgt fremde Wetten,
       es nimmt keine an. Übernommen ist die Vergleichszeile der
       Team-Statistik: zwei Pillen links und rechts, ein grüner Punkt an
       der Seite, die heraussticht. Bei uns ist das die Seite, auf der man
       selbst steht.
     * KEIN DATUMSSTREIFEN. Die Vorlage wählt oben einen Spieltag; unsere
       Wetten laufen Stunden, nicht Tage. An seiner Stelle steht die
       Filterleiste nach Wettart — dieselbe Form, andere Frage.
     * KEINE WAPPEN. Statt Vereinslogos trägt jede Seite das Symbol ihrer
       Wettart in einer runden Scheibe.
     * „Current/Target" heißt „Stand/Ziel", und die große Zahl in der
       Kartenmitte ist nicht die Anstoßzeit, sondern die RESTZEIT: Sie
       entscheidet, wie lange überhaupt noch gesetzt werden kann. */

:root[data-app="tipico"] {
  color-scheme: dark;

  --tp-akzent: #5FAE53;
  /* Der Knopf unter dem Finger. Die Vorlage zeigt keinen gedrückten
     Zustand — heller statt dunkler, weil auf #18181B ein abdunkelnder
     Knopf im Grund verschwände. */
  --tp-akzent-hell: #74C067;
  --tp-spur: #D9D9D9;
  --tp-feldrand: #656464;

  --bg: #18181B;
  --bg-elev: #292828;
  --bg-elev-2: #2D2D2D;
  --fill: #2D2D2D;
  --fill-2: #313134;
  --seg-pille: #3A3A3C;
  --label: #F9FAFB;
  --label-2: #A4A4A4;
  --label-3: #898989;
  --separator: rgba(255, 255, 255, .09);
  /* Die Vorlage hat keine Glaskanten und keine Schatten: Flächen trennen
     sich allein durch ihre Helligkeit. Beides deshalb abgeschaltet statt
     nachgefärbt — ein Milchglaskopf über #18181B wäre wieder iOS. */
  --glass-stroke: transparent;
  --glass-highlight: transparent;
  --bar: #292828;
  --sheet: #292828;
  --shadow: none;
  --scrim: rgba(0, 0, 0, .6);

  /* Die Systemfarben auf die eine Farbe der Vorlage gezogen. Das ist der
     Hebel, mit dem alles Geerbte mitspricht: Jede Pille, jeder Haken und
     jeder getönte Knopf des Portals wird hier grün, ohne dass ich sie
     einzeln aufzählen muss.

     --red bleibt eigenständig — eine verlorene Wette muss sich von einer
     gewonnenen unterscheiden, und dafür hat die Vorlage keine Farbe. Der
     Ton ist gegenüber iOS abgesenkt, sonst schriee er auf dem ruhigen
     Grund der App. */
  --green: #5FAE53; --blue: #5FAE53; --teal: #5FAE53; --indigo: #5FAE53;
  --red: #E5484D; --pink: #E5484D;
  --grau: #3A3A3C;

  /* Radien der Vorlage: Karten 20, Felder und Pillen voll gerundet.
     Zwischen beiden liegt nichts — die 12 und 22 aus iOS gibt es hier
     nicht, und genau daran erkennt man die App wieder. */
  --r-card: 20px; --r-box: 14px; --r-ctl: 14px;
  --gutter: 20px;
}

/* ── Rahmen ─────────────────────────────────────────────────
   Kopf und Statusleiste sind deckend im Grundton: Die Vorlage kennt kein
   Milchglas, ihre Bildschirme sind eine durchgehende Fläche. Auch
   `is-scrolled` muss mit — sonst käme die Glaskante beim Scrollen
   zurück. */
[data-app="tipico"] .navbar,
[data-app="tipico"] .navbar.is-scrolled {
  background: var(--bg);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-bottom-color: transparent; box-shadow: none;
}
[data-app="tipico"] .statusbar { background: var(--bg); color: var(--label); }

/* Die Wortmarke. In der Vorlage steht CLUTCHCALL auf jedem Bildschirm
   oben in der Mitte: fett, gesperrt, in Versalien. Hier trägt der große
   Titel diese Form — auf dem ersten Bildschirm ist das die Marke, auf den
   anderen der Name des Bereichs. */
[data-app="tipico"] .large-title { text-align: center; }
[data-app="tipico"] .large-title h1 {
  font-size: 26px; font-weight: 800; line-height: 32px;
  letter-spacing: .6px; text-transform: uppercase;
}
[data-app="tipico"] .large-title.lang h1 { font-size: 22px; line-height: 28px; }
[data-app="tipico"] .navbar .navbar-title {
  font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
}
[data-app="tipico"] .large-title .sub { color: var(--label-2); }

/* Zurück-Knopf als leerer Kreis mit dünnem Rand — so steht er in der
   Vorlage über jedem Detailbildschirm. Die graue Glasscheibe des Portals
   fällt dafür weg; der Pfeil darin ist weiß, nicht in der Akzentfarbe.
   (Die Beschriftung im span bleibt unangetastet — sie ist für
   Vorlesewerkzeuge da und schon von der Grundregel versteckt.) */
[data-app="tipico"] .navbar-action.left {
  background: transparent; border: 1px solid var(--tp-feldrand);
  -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none;
}
[data-app="tipico"] .navbar-action { color: var(--label); }

/* Tab-Leiste: dieselbe schwebende Kapsel wie überall, aber in der Farbe
   der Vorlage und OHNE Pille hinter dem aktiven Tab. ClutchCall färbt
   dort nur Symbol und Wort grün; eine Pille zusätzlich wäre eine
   Auszeichnung zu viel. */
[data-app="tipico"] .tp-tabs {
  background: var(--bar); box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  margin-left: 10px; margin-right: 10px;
  width: calc(100% - 20px);
}
.tp-tab.an { color: var(--tp-akzent); }
[data-app="tipico"] .tp-tab.an { background: transparent; }

/* ── Filterleiste ───────────────────────────────────────────
   Die Sportartenzeile der Vorlage, auf unsere Wettarten gestellt: eine
   Karte, darin Pillen. Die aktive trägt einen grünen Rand statt einer
   Füllung — gefüllt wäre sie ein Knopf, und gedrückt ist sie schon. */
.tp-filter {
  display: flex; gap: var(--s2); overflow-x: auto; scrollbar-width: none;
  margin: 0 var(--gutter) var(--s4); padding: 10px;
  border-radius: var(--r-card); background: var(--bg-elev);
}
.tp-filter::-webkit-scrollbar { display: none; }
.tp-chip {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  min-height: 42px; padding: 0 16px; border-radius: var(--r-pill);
  border: 1px solid transparent; background: var(--fill);
  color: var(--label-2); font-size: 14px; font-weight: 500;
  text-decoration: none; white-space: nowrap;
}
.tp-chip.an {
  background: transparent; border-color: var(--tp-akzent); color: var(--label);
}
.tp-chip .ic { color: var(--label-3); }
.tp-chip.an .ic { color: var(--tp-akzent); }
.tp-chip-zahl { color: var(--label-3); font-variant-numeric: tabular-nums; }

/* ── Guthaben ───────────────────────────────────────────────
   In der Vorlage gibt es keine — sie verwaltet kein Geld. Die Zeile
   bleibt trotzdem, weil ohne sie niemand weiß, ob der nächste Einsatz
   überhaupt gedeckt ist; sie trägt nur das Kleid der Vorlage und führt
   in die Bank-App, wo das Geld wirklich liegt. */
.tp-guthaben {
  display: flex; align-items: center; gap: var(--s2);
  margin: 0 var(--gutter) var(--s4); padding: 14px 16px;
  border-radius: var(--r-card); background: var(--bg-elev);
  color: var(--label); text-decoration: none;
}
.tp-g-k { font-size: 13px; color: var(--label-2); }
.tp-g-v {
  font-size: 22px; font-weight: 700; letter-spacing: -.2px; margin-left: auto;
  color: var(--tp-akzent); font-variant-numeric: tabular-nums;
}
.tp-g-bank { font-size: 12px; color: var(--label-3); }
.tp-guthaben .chev { color: var(--label-3); }

/* ── Die Wettkarte ──────────────────────────────────────────
   Der Spielpaarung der Vorlage nachgebaut: Liga oben in der Mitte, links
   und rechts die Parteien, dazwischen die große Zahl. Bei uns steht dort
   die Restzeit — die einzige Zahl, die sich von selbst bewegt und über
   die es hier zu entscheiden gibt. */
.tp-spiel {
  background: var(--bg-elev); border-radius: var(--r-card);
  margin: 0 var(--gutter) var(--s3); padding: var(--s4);
}
.tp-oben { display: block; text-decoration: none; color: inherit; }
.tp-oben:active { opacity: .7; }

/* Kopfzeile: Wettart mittig, Zustandsmarke rechts. Der Chevron sitzt
   hinter der Marke — er gehört zum Link, nicht zur Art. */
.tp-kopf { display: flex; align-items: center; gap: var(--s2); min-height: 22px; }
.tp-art {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 auto; padding-left: 34px;
  font-size: 13px; font-weight: 600; color: var(--label);
  letter-spacing: .2px;
}
.tp-kopf-rechts { display: flex; align-items: center; gap: 6px; }
.tp-kopf-rechts .chev { color: var(--label-3); }

/* Die Paarung. Drei Spalten, die äußeren gleich breit — sonst rückt die
   große Zahl aus der Mitte, sobald ein Seitenname länger ist. */
.tp-duell {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: var(--s2); margin-top: var(--s4);
}
.tp-seite { display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 0; }
.tp-seite-sym {
  width: 46px; height: 46px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--fill); color: var(--label-2);
}
.tp-seite-name {
  font-size: 12px; color: var(--label-2); text-align: center; line-height: 1.25;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tp-seite.meine .tp-seite-sym { background: rgba(95, 174, 83, .18); color: var(--tp-akzent); }
.tp-seite.meine .tp-seite-name { color: var(--tp-akzent); }
.tp-mitte { text-align: center; }
.tp-mitte-zeit {
  font-size: 28px; font-weight: 700; letter-spacing: -.4px; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
/* Die große Zahl bleibt WEISS, auch wenn sie als Uhr läuft — in der
   Vorlage ist der Spielstand weiß und grün nur das, was man antippen
   kann. Ohne diese Zeile färbte `.tp-uhr` sie mit ein, und die Karte
   hätte drei grüne Stellen übereinander. */
.tp-mitte-zeit.tp-uhr { color: var(--label); }
.tp-mitte-zeit.aus, .tp-mitte-zeit.tp-uhr.aus { color: var(--label-3); }
/* Das Monogramm der Duell-Seiten — zwei Buchstaben statt eines Wappens. */
.tp-seite-mono { font-size: 17px; font-weight: 700; letter-spacing: -.2px; color: var(--label); }
/* Die unterlegene Seite einer entschiedenen Wette tritt zurück, damit der
   Pokal daneben etwas heißt. */
.tp-seite.blass { opacity: .45; }
.tp-mitte-k { margin-top: 3px; font-size: 12px; color: var(--label-3); }

/* Titel und Zahlen unter der Paarung. In der Vorlage steht dort der
   Spielort; hier die Frage, um die es geht, und was im Topf liegt. */
.tp-titel {
  display: block; margin-top: var(--s4); text-align: center;
  font-size: 16px; font-weight: 600; line-height: 1.3;
}
.tp-zahlen {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 6px; font-size: 13px; color: var(--label-2);
}
.tp-zahlen b { color: var(--label); font-variant-numeric: tabular-nums; }
/* Grün steht am Topf und nirgends sonst in dieser Zeile: Er ist das, was
   zu holen ist — der Einsatz ist nur der Preis dafür. */
.tp-zahlen b.topf { color: var(--tp-akzent); }

/* Die laufende Uhr in Listenzeilen. Ziffern gleicher Breite, sonst
   zappelt die Zeile im Sekundentakt. */
.tp-uhr { font-weight: 600; color: var(--tp-akzent); font-variant-numeric: tabular-nums; }
.tp-uhr.aus { color: var(--label-3); }

/* „LIVE" wie in einer Wett-App: kleiner Punkt, der langsam pulst. */
.tp-live {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: var(--r-pill);
  background: rgba(95, 174, 83, .16);
  color: var(--tp-akzent); font-size: 11px; font-weight: 700; letter-spacing: .4px;
}
.tp-live::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--tp-akzent); animation: tp-puls 2s ease-in-out infinite;
}
@keyframes tp-puls { 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .tp-live::before { animation: none; } }

/* ── Fortschritt ────────────────────────────────────────────
   Eins zu eins die Verlaufskarte der Vorlage („Current : 149 / Target :
   200"): Beschriftungen links und rechts, darunter ein 8 px hoher Balken
   auf HELLER Spur. Die helle Spur ist kein Versehen — sie ist die einzige
   helle Fläche der ganzen App und zieht den Blick genau dahin, wo sich
   etwas bewegt. */
.tp-fortschritt { margin-top: var(--s4); }
.tp-fort-kopf {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3);
  margin-bottom: 8px; font-size: 13px; color: var(--label);
}
.tp-fort-kopf b { font-weight: 600; font-variant-numeric: tabular-nums; }
.tp-balken { height: 8px; border-radius: var(--r-pill); background: var(--tp-spur); overflow: hidden; }
.tp-balken span { display: block; height: 100%; border-radius: var(--r-pill); background: var(--tp-akzent); }

/* ── Die Verlaufskarte ──────────────────────────────────────
   „Active Bets" der Vorlage: Sorte und Zustand oben, darunter worum es
   geht, darunter der Fortschritt. Sie steht unter „Meine Wetten" und
   unter „Ergebnisse" — beides sind Listen von Wetten, an denen nichts
   mehr zu bedienen ist, und deshalb ist die ganze Karte EIN Link.

   Anders als die Wettkarte vorn ist sie linksbündig: Dort steht eine
   Paarung, die Mitte braucht; hier stehen Sätze, und die liest man von
   links. */
.tp-lauf { display: block; text-decoration: none; color: inherit; }
.tp-lauf:active { opacity: .7; }
.tp-lauf-titel {
  display: block; margin-top: var(--s3);
  font-size: 15px; font-weight: 600; line-height: 1.35;
}
.tp-lauf-seite { display: block; margin-top: 3px; font-size: 13px; color: var(--label-2); }
/* Eigener Name statt des naheliegenden `.mitte`: Das ist im Portal
   längst die Vollbild-Zentrierung der Anmeldeseite — mit ihr wurde aus
   der Titelzeile ein 84 px hoher Kasten. */
.tp-lauf-titel.tp-zentriert, .tp-lauf-seite.tp-zentriert { text-align: center; }
.tp-lauf-fuss {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap; margin-top: var(--s4);
  font-size: 13px; color: var(--label-2);
}
.tp-lauf-zeile { display: inline-flex; align-items: baseline; gap: 6px; }
.tp-lauf-zeile b { font-weight: 600; color: var(--label); font-variant-numeric: tabular-nums; }
.tp-plus { color: var(--tp-akzent); }

/* Die Bilanz über „Meine Wetten": drei Zahlen nebeneinander in einer
   Karte — die Form, in der die Vorlage einen Spielstand nach Vierteln
   zeigt. */
.tp-bilanz {
  display: flex; margin: 0 var(--gutter) var(--s4); padding: var(--s4) var(--s3);
  border-radius: var(--r-card); background: var(--bg-elev);
}
.tp-bilanz-sp { flex: 1 1 0; min-width: 0; text-align: center; }
.tp-bilanz-sp + .tp-bilanz-sp { border-left: 1px solid var(--separator); }
.tp-bilanz-v {
  font-size: 17px; font-weight: 700; letter-spacing: -.2px;
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tp-bilanz-k { margin-top: 3px; font-size: 12px; color: var(--label-2); }

/* Der Satz unter dem Wettart-Feld erklärt die gewählte Art. Er gehört
   ins Feldgefüge und nicht in eine Fußnote am Formularende — dort läse
   ihn niemand, der gerade wählt. */
.tp-hinweis { margin: 8px 4px 0; font-size: 12px; color: var(--label-3); line-height: 1.4; }

/* ── Quotenknöpfe ───────────────────────────────────────────
   Das Bedienelement der App, gebaut aus der Vergleichszeile der Vorlage:
   zwei Pillen nebeneinander, die eigene Seite mit grünem Rand und grünem
   Punkt. Sie öffnen den Wettschein — gesetzt wird erst dort. */
.tp-quoten { display: flex; gap: var(--s2); margin-top: var(--s4); }
.tp-quote {
  flex: 1 1 0; min-width: 0; position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  min-height: 52px; padding: 8px 16px;
  border: 1px solid transparent; border-radius: var(--r-pill);
  background: var(--fill); color: var(--label); text-align: left;
}
.tp-quote:not(.zu):not(.meine):active { background: var(--fill-2); }
.tp-quote.meine { background: transparent; border-color: var(--tp-akzent); }
.tp-quote.zu { opacity: .5; }
.tp-q-text { min-width: 0; }
.tp-q-seite {
  display: block; font-size: 13px; font-weight: 500; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tp-q-zahl { display: block; margin-top: 2px; font-size: 11px; color: var(--label-3); }
.tp-q-wert {
  flex: none; font-size: 18px; font-weight: 700; letter-spacing: -.2px;
  font-variant-numeric: tabular-nums;
}
.tp-quote.meine .tp-q-wert { color: var(--tp-akzent); }
/* Der grüne Punkt der Vorlage: dort am besseren Wert, hier an der Seite,
   auf der man steht. Er steht direkt VOR dem Wert, wie in der
   Vergleichszeile der Team-Statistik. */
.tp-q-punkt {
  flex: none; width: 8px; height: 8px; margin-left: auto;
  border-radius: 50%; background: var(--tp-akzent);
}
.tp-grund { margin-top: var(--s3); font-size: 12px; color: var(--label-3); text-align: center; }

/* ── Die einzelne Wette ─────────────────────────────────────
   Der Kopf des Detailbildschirms, nach der Spielansicht der Vorlage: eine
   Karte, in der die Paarung groß steht, darunter der Topf mit Symbol —
   an der Stelle, an der die Vorlage den Spielort nennt. */
.tp-kanzel {
  margin: 0 var(--gutter) var(--s4); padding: var(--s4);
  border-radius: var(--r-card); background: var(--bg-elev);
}
.tp-kanzel-titel { font-size: 17px; font-weight: 600; text-align: center; line-height: 1.3; }
.tp-kanzel-marken {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  flex-wrap: wrap; margin-top: var(--s3);
}
.tp-kanzel-topf {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: var(--s4); font-size: 15px; font-weight: 600; color: var(--tp-akzent);
}
.tp-kanzel-topf .num { font-variant-numeric: tabular-nums; }

/* ── Wettschein ─────────────────────────────────────────────
   Das Blatt zwischen Quotenknopf und Abbuchung. */
.tp-schein-zeile {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3);
  padding: 9px 0; font-size: 14px; color: var(--label-2);
}
.tp-schein-zeile b { font-size: 16px; color: var(--label); text-align: right; }
.tp-schein-zeile.gross {
  border-top: 1px solid var(--separator); margin-top: 4px; padding-top: 12px;
}
.tp-schein-zeile.gross b { font-size: 22px; font-weight: 700; color: var(--tp-akzent); }

/* ── Formular ───────────────────────────────────────────────
   „Add Bet" der Vorlage: eine Karte, darin Beschriftung über Feld, jedes
   Feld eine voll gerundete Pille mit dünnem Rand. Die Beschriftung endet
   auf einem Doppelpunkt — auch das steht so in der Vorlage. */
.tp-form { margin: 0 var(--gutter) var(--s4); padding: var(--s4); border-radius: var(--r-card); background: var(--bg-elev); }
.tp-label { display: block; margin: var(--s4) 0 8px; font-size: 14px; font-weight: 500; color: var(--label); }
.tp-form > .tp-label:first-child { margin-top: 0; }
.tp-feld {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; min-height: 48px; padding: 0 18px;
  border: 1px solid var(--tp-feldrand); border-radius: var(--r-pill);
  background: var(--bg); color: var(--label); font: inherit; font-size: 15px;
  -webkit-appearance: none; appearance: none;
}
.tp-feld::placeholder { color: var(--label-3); }
.tp-feld:focus { outline: none; border-color: var(--tp-akzent); }
/* Auswahlfeld: dieselbe Pille, rechts der Chevron der Vorlage. Als Knopf
   gebaut, weil dahinter eine Liste im Blatt aufgeht — ein <select> würde
   auf dem Handy die Systemwalze zeigen und die App verlassen. */
button.tp-feld { text-align: left; justify-content: space-between; }
button.tp-feld:active { background: var(--bg-elev-2); }
.tp-feld .chev { transform: rotate(90deg); color: var(--label-2); flex: none; }
.tp-feld-wert { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-treffer { margin-top: var(--s2); }
.tp-treffer .row { border-radius: var(--r-box); }

/* Der Knopf, für den man die App öffnet. In der Vorlage steht er mittig
   und ist nur so breit wie nötig — die Formularknöpfe des Portals laufen
   über die ganze Breite, das ist der auffälligste Unterschied im Kleid. */
.tp-platzieren {
  display: flex; align-items: center; justify-content: center;
  min-height: 40px; margin: var(--s5) auto 0; padding: 0 32px;
  border-radius: var(--r-pill); background: var(--tp-akzent); color: #fff;
  font-size: 15px; font-weight: 700; width: auto;
}
.tp-platzieren:active { background: var(--tp-akzent-hell); }
.tp-platzieren[disabled] { opacity: .5; }

/* Leerer Zustand: in der Vorlage ein dünn umrandeter Kasten mit einem
   Satz darin, keine Zeichnung. */
[data-app="tipico"] .zustand {
  margin: 0 var(--gutter); padding: var(--s8) var(--s5);
  border: 1px solid var(--tp-feldrand); border-radius: var(--r-card);
  color: var(--label-2);
}
[data-app="tipico"] .zustand-ic { display: none; }

/* Listen und Gruppen erben die Palette von oben; nur die Rundung folgt
   der Vorlage, und die Kopfzeile einer Gruppe steht in Versalien wie
   „ACTIVE BETS" und „TOP PERFORMERS". */
[data-app="tipico"] .group { border-radius: var(--r-card); }
[data-app="tipico"] .group-header {
  font-size: 14px; font-weight: 700; color: var(--label);
  letter-spacing: .4px; text-transform: uppercase;
}

/* ── Bank ───────────────────────────────────────────────────
   Aufbau einer Banking-App: oben eine Zahl, die alles zusammenfasst, darunter
   die Konten als Karten, dann vier Schnellaktionen, dann alles Weitere als
   Liste.

   Die Bausteine dazu stehen in web/portal/bank.js. Symbole kommen
   ausnahmslos aus web/portal/icons.js — hier gibt es KEINE Emojis. */

/* ── Symbole ──────────────────────────────────────────────── */
/* `inline-block` statt `block`: Zeichnungen stehen auch MITTEN IM TEXT — in
   Pillen, Zeilen, Knopfbeschriftungen. Mit `block` broeche dort die Zeile um.
   In Flex-Behaeltern wird das ohnehin zu Block, dort schadet es nicht. Der
   kleine Versatz nach unten setzt sie auf die Schriftlinie. */
.ic { display: inline-block; vertical-align: -.15em; flex: none; }

/* Der farbige Kreis hinter einem Listensymbol. `data-ton` benennt eine
   ROLLE, keine Farbe: So steht der Zusammenhang zwischen Rolle und Farbwert
   an genau einer Stelle, und Hell/Dunkel bleibt regelbar. */
.ic-kreis {
  width: 30px; height: 30px; border-radius: 8px; flex: none;
  display: flex; align-items: center; justify-content: center;
  color: #fff; background: var(--grau);
}
.ic-kreis[data-ton="blau"]   { background: var(--blue); }
.ic-kreis[data-ton="gruen"]  { background: var(--green); }
.ic-kreis[data-ton="rot"]    { background: var(--red); }
.ic-kreis[data-ton="orange"] { background: var(--orange); }
.ic-kreis[data-ton="indigo"] { background: var(--indigo); }
.ic-kreis[data-ton="grau"]   { background: #8E8E93; }

/* Der Pfeil am Ende einer Listenzeile. Nie das Zeichen ">": Das traegt die
   Schriftart, sitzt zu hoch und laesst sich nicht in der Strichstaerke an
   die uebrigen Symbole angleichen. */
.ic-chev { color: var(--label-3); margin-left: 2px; }

/* ── Trefferflächen ─────────────────────────────────────────
   iOS verlangt mindestens 44x44 zum Antippen. Kleine Bedienelemente sollen
   deshalb GRÖSSER SEIN, ALS SIE AUSSEHEN: ein unsichtbares Feld über das
   Element hinaus. Sie einfach zu vergrößern wäre die schlechtere Lösung —
   ein 44 px hoher Schalter sprengt die Listenzeile, in der er sitzt.

   Beim Schalter ist ::after schon der Knauf, dort übernimmt ::before. */
/* Zwischen Apples Small (28, Innenmass 10) und Medium (34, Innenmass 12).
   Die Hoehe bleibt bei 32: Ein Knopf, der mit dem Finger getroffen wird,
   soll nicht unter Apples Small fallen. Radius erbt die Kapsel von `.btn`. */
.btn-mini {
  min-height: 32px; padding: 0 12px; font-size: 14px; position: relative;
}
.btn-mini::after,
.segmented button::after {
  content: ""; position: absolute; left: 0; right: 0;
  top: 50%; height: 44px; transform: translateY(-50%);
}
.switch::before {
  content: ""; position: absolute; left: -4px; right: -4px;
  top: 50%; height: 44px; transform: translateY(-50%);
}

/* ── Rueckmeldung auf Beruehrung ──────────────────────────────
   Eine Bank-App antwortet auf jeden Druck. `.tap` gibt genau das: leichtes
   Einsinken beim Druecken, sanftes Zurueckfedern beim Loslassen. Die Kurve
   ist bewusst kurz — was laenger als eine Fuenftelsekunde nachwippt, wirkt
   nicht mehr wie ein Knopf, sondern wie eine Verzoegerung. */
.tap {
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s cubic-bezier(.2, .8, .3, 1),
              background-color .18s ease, opacity .18s ease;
}
.tap:active { transform: scale(.97); }
.row.tap:active { background: var(--fill); transform: none; }

@media (prefers-reduced-motion: reduce) {
  .tap { transition: none; }
  .tap:active { transform: none; }
}

/* ── Die Bank: iBanks Kleid ─────────────────────────────────
   Nach der Figma-Vorlage „iBank / FinPay — E-Money Management App"
   (USrBopWIFJyqTCOjvruBi7, 89 Bildschirme, abgenommen am 31.08.2026). Alle
   Werte hier stammen aus deren Variablen, nicht aus meiner Schätzung:

     Primary/1   #3629B7   der Kopf, die aktive Fläche, jede positive Zahl
     Primary/2   #5655B9   die zweite Karte im Stapel
     Semantic/1  #FF4267   Ausgaben, Warnungen, die dritte Karte
     Semantic/2  #0890FE   Girokonto, Überweisung
     Semantic/3  #FFAF2A   Kredit
     Semantic/4  #52D5BA   Sparen, Bargeld
     Semantic/5  #FB6B18   Anforderungen
     Neutral/2   #898989   jede Beschriftung unter einer Zahl
     Neutral/4   #CACACA   Feldränder
     Card/1      0 4px 30px #3629B712
     Card/2      0 5px 30px #0000000D

   Die App ist IMMER HELL — dieselbe Entscheidung wie bei Amazon und aus
   demselben Grund: Die Vorlage kennt keinen Dunkelmodus, und eine halb
   umgefärbte iBank sähe schlechter aus als gar keine. Wer das ändern will,
   erfindet die dunklen Werte selbst; aus der Vorlage kommen sie nicht.

   ABWEICHUNGEN VON DER VORLAGE, alle mit Absicht:

     * Die Vorlage zeigt EINE Karte mit zwei Attrappen dahinter. Hier hat
       ein Spieler Bargeld plus beliebig viele Konten, also bleibt das
       Wischband — jede Karte bringt ihren eigenen Stapel mit.
     * Der Kopf ist lila, WO EINE KARTE DARUNTER STEHT (Start, Umsätze,
       Kredit, Karten), und sonst weiß. Genau so hält es die Vorlage:
       Home, Transaction report und Credit card tragen Lila, Message,
       Save online und Transfer nicht. Die Regel steht unten als Liste von
       data-bildschirm — wer einen Bildschirm ergänzt, trägt ihn dort ein.
     * Die Vorlage schreibt Beträge in Dollar. Hier stehen Coins, und die
       Zahl trägt tabular-nums — bei Beträgen, die untereinander stehen,
       ist das kein Geschmack, sondern Lesbarkeit. */

:root[data-app="bank"] {
  color-scheme: light;
  /* Der Grund ist nicht weiß, sondern ein Hauch Blau darin — sonst
     verschwänden die weißen Karten mit ihrem hellen Schatten darauf. */
  --bg: #F7F7FC;
  --bg-elev: #FFFFFF;
  --bg-elev-2: #F2F1F9;
  --fill: #F2F1F9;
  --fill-2: #E7E5F3;
  --seg-pille: #FFFFFF;
  --label: #1B1A2F;
  --label-2: #898989;
  --label-3: #CACACA;
  --separator: #EFEFF4;
  --glass-stroke: transparent;
  --glass-highlight: transparent;
  --bar: #FFFFFF;
  --sheet: #FFFFFF;
  --shadow: 0 5px 30px rgba(0, 0, 0, .05);
  --scrim: rgba(27, 26, 47, .45);

  /* Die Systemfarben auf die Palette der Vorlage umgestellt. Das ist der
     Hebel, mit dem die Bank in einem Zug ihr Aussehen wechselt: Alles im
     Portal, was --blue oder --red benutzt, spricht hier iBank. */
  --blue: #0890FE; --green: #52D5BA; --red: #FF4267;
  --orange: #FB6B18; --yellow: #FFAF2A; --purple: #5655B9;
  --pink: #FF4267; --teal: #52D5BA; --indigo: #3629B7;
  --grau: #898989;

  --ib-primaer: #3629B7;
  --ib-primaer-2: #5655B9;
  --ib-karte-grund: #221D5E;
  --ib-schatten: 0 4px 30px rgba(54, 41, 183, .07);
  --ib-schatten-2: 0 5px 30px rgba(0, 0, 0, .05);
  /* Die Radien der Vorlage: Karten 16, Felder 10, Kacheln 16. Deutlich
     kleiner als Apples 22 — das ist einer der Gründe, warum die App fremd
     wirkt und nicht nach umgefärbtem iOS. */
  --r-card: 16px; --r-box: 10px; --r-ctl: 10px;

  --font: var(--font-bank);
}

/* Poppins bringt eigene Sperrung mit; die enge iOS-Laufweite aus dem body
   würde sie zusammenquetschen. Auch die Grundgröße geht auf 16 zurück —
   Body/1 und Body/2 der Vorlage. */
[data-app="bank"] body { letter-spacing: 0; font-size: 16px; }

/* ── Kopf ───────────────────────────────────────────────────
   Lila und deckend, weiße Schrift, keine Glaskante. Die Glasregeln der
   Navigationsleiste müssen mit überschrieben werden — auch `is-scrolled`,
   sonst käme das Milchglas beim Scrollen zurück. */
[data-bildschirm="bank"] .navbar,
[data-bildschirm="bank"] .navbar.is-scrolled,
[data-bildschirm="bank-konto"] .navbar,
[data-bildschirm="bank-konto"] .navbar.is-scrolled,
[data-bildschirm="konto"] .navbar,
[data-bildschirm="konto"] .navbar.is-scrolled,
[data-bildschirm="bank-kredit"] .navbar,
[data-bildschirm="bank-kredit"] .navbar.is-scrolled,
[data-bildschirm="bank-karten"] .navbar,
[data-bildschirm="bank-karten"] .navbar.is-scrolled {
  background: var(--ib-primaer);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-bottom-color: transparent; box-shadow: none;
}
/* Der Streifen über der Leiste gehört zum selben Feld — ohne ihn säße die
   Uhrzeit auf hellem Grund über einem lila Kopf. */
[data-bildschirm="bank"] .statusbar,
[data-bildschirm="bank-konto"] .statusbar,
[data-bildschirm="konto"] .statusbar,
[data-bildschirm="bank-kredit"] .statusbar,
[data-bildschirm="bank-karten"] .statusbar { background: var(--ib-primaer); color: #fff; }

/* Auf dem Lila steht alles weiß. Der Zurück-Knopf verliert seine graue
   Scheibe: Auf gesättigtem Grund wirkt sie wie ein Fleck. */
[data-app="bank"] .navbar,
[data-app="bank"] .navbar .large-title h1,
[data-app="bank"] .navbar .navbar-title { color: #fff; }
[data-app="bank"] .navbar .large-title .sub { color: rgba(255, 255, 255, .72); }
[data-app="bank"] .navbar-action { color: #fff; }
[data-app="bank"] .navbar-action.left {
  background: rgba(255, 255, 255, .16);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  box-shadow: none;
}

/* Die Bildschirme OHNE Karte tragen einen weißen Kopf mit dunkler Schrift —
   Message, Save online, Transfer in der Vorlage. Die Regel steht nach der
   lila und hebt sie für diese Bildschirme wieder auf. */
[data-app="bank"]:not([data-bildschirm="bank"]):not([data-bildschirm="bank-konto"]):not([data-bildschirm="konto"]):not([data-bildschirm="bank-kredit"]):not([data-bildschirm="bank-karten"]) .navbar,
[data-app="bank"]:not([data-bildschirm="bank"]):not([data-bildschirm="bank-konto"]):not([data-bildschirm="konto"]):not([data-bildschirm="bank-kredit"]):not([data-bildschirm="bank-karten"]) .navbar.is-scrolled {
  background: var(--bg);
}
[data-app="bank"]:not([data-bildschirm="bank"]):not([data-bildschirm="bank-konto"]):not([data-bildschirm="konto"]):not([data-bildschirm="bank-kredit"]):not([data-bildschirm="bank-karten"]) .navbar,
[data-app="bank"]:not([data-bildschirm="bank"]):not([data-bildschirm="bank-konto"]):not([data-bildschirm="konto"]):not([data-bildschirm="bank-kredit"]):not([data-bildschirm="bank-karten"]) .navbar .large-title h1,
[data-app="bank"]:not([data-bildschirm="bank"]):not([data-bildschirm="bank-konto"]):not([data-bildschirm="konto"]):not([data-bildschirm="bank-kredit"]):not([data-bildschirm="bank-karten"]) .navbar .navbar-title { color: var(--label); }
[data-app="bank"]:not([data-bildschirm="bank"]):not([data-bildschirm="bank-konto"]):not([data-bildschirm="konto"]):not([data-bildschirm="bank-kredit"]):not([data-bildschirm="bank-karten"]) .navbar-action { color: var(--ib-primaer); }
[data-app="bank"]:not([data-bildschirm="bank"]):not([data-bildschirm="bank-konto"]):not([data-bildschirm="konto"]):not([data-bildschirm="bank-kredit"]):not([data-bildschirm="bank-karten"]) .navbar-action.left { background: var(--fill); }

/* Der große Titel der Vorlage ist kleiner und fetter als Apples: Title/2
   ist 20/28 SemiBold, die Kopfzeile der Unterseiten 24 Bold. Apples 34 mit
   feiner Sperrung wäre hier eine andere App. */
[data-app="bank"] .large-title h1 {
  font-size: 24px; font-weight: 700; letter-spacing: 0; line-height: 32px;
}
[data-app="bank"] .navbar.collapsed .large-title h1 {
  font-size: 17px; line-height: 22px; font-weight: 600;
}

/* Der weiße Inhaltsbereich zieht sich mit großer Rundung über den lila Kopf.
   Das ist die auffälligste Form der Vorlage — ohne sie wäre der Kopf nur ein
   farbiger Balken.

   Die Rundung sitzt am Scrollbereich, der Grund dahinter an der Bühne: Ein
   `border-radius` allein zeigte nichts, weil dahinter dieselbe Farbe läge. */
[data-bildschirm="bank"] .buehne,
[data-bildschirm="bank-konto"] .buehne,
[data-bildschirm="konto"] .buehne,
[data-bildschirm="bank-kredit"] .buehne,
[data-bildschirm="bank-karten"] .buehne { background: var(--ib-primaer); }
[data-bildschirm="bank"] .scroll,
[data-bildschirm="bank-konto"] .scroll,
[data-bildschirm="konto"] .scroll,
[data-bildschirm="bank-kredit"] .scroll,
[data-bildschirm="bank-karten"] .scroll {
  border-radius: 28px 28px 0 0;
  padding-top: var(--s5);
}

/* ── Die Bankkarte ──────────────────────────────────────────
   Das Herzstück der Vorlage: dunkelblauer Grund, ein leuchtender Bogen, der
   von rechts hereinschwingt, und darüber eine hellere Scheibe. Nachgebaut
   aus drei Ebenen radialer Verläufe statt aus einem Bild — so trägt jede
   Kontoart ihre eigene Farbe, ohne dass jemand acht PNG pflegen muss.

   Die harten Kanten (`… 0 100%, transparent 0`) sind Absicht: Ein weicher
   Verlauf ergäbe eine Wolke, kein Kreissegment. */
.bk-karten {
  display: flex; gap: var(--s3); overflow-x: auto; scroll-snap-type: x mandatory;
  padding: 2px var(--gutter) var(--s5);
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
  /* OHNE DAS KLEBT DIE ERSTE KARTE AM BILDSCHIRMRAND.
     `scroll-snap-align: start` richtet die Karte am Anfang des Scrollfensters
     aus - und der liegt VOR dem Innenabstand. Der Browser scrollt die 16 px
     also gleich wieder weg, und die Karte sitzt buendig links, waehrend alles
     darunter eingerueckt ist. `scroll-padding` verschiebt den Anfang des
     Scrollfensters mit. */
  scroll-padding-left: var(--gutter);
}
.bk-karten::-webkit-scrollbar { display: none; }

.bk-karte, .bk-kk {
  position: relative;
  scroll-snap-align: start; flex: 0 0 88%; max-width: 340px; min-height: 186px;
  border-radius: var(--r-card); padding: 22px 22px 20px;
  display: flex; flex-direction: column;
  color: #fff; text-decoration: none;
  background: var(--ib-karte-grund);
  /* Platz für die zwei Karten darunter — sie liegen außerhalb der Karte und
     brauchen ihn im Fluss, sonst überdeckten sie den nächsten Block. */
  margin-bottom: 14px;
}

/* Der Stapel: zwei Bänder unter der Karte, jedes schmaler und weiter unten.
   Sie liegen HINTER der Karte (z-index -1) und schauen nur mit ihrer
   unteren Rundung hervor. */
.bk-karte::before, .bk-karte::after,
.bk-kk::before, .bk-kk::after {
  content: ""; position: absolute; z-index: -1;
  left: 10px; right: 10px; top: 8px; bottom: -7px;
  border-radius: var(--r-card);
  background: var(--ib-primaer-2);
}
/* Das dritte Band liegt HINTER dem zweiten (z-index -2 statt -1). Ohne das
   deckte das schmalere rote das breitere lila in der Mitte ab, und vom
   Stapel blieben zwei Zipfel an den Seiten übrig statt zwei Baendern
   untereinander. */
.bk-karte::after, .bk-kk::after {
  left: 22px; right: 22px; bottom: -14px; z-index: -2;
  background: #FF4267;
}
/* `isolation` erzwingt einen eigenen Stapelkontext: Ohne ihn schöben die
   negativen z-index die Bänder hinter den Seitengrund und sie verschwänden. */
.bk-karten, .bk-kk-block { isolation: isolate; }

/* Der Farbbogen je Kontoart. Zwei Scheiben: die große schwingt von rechts
   herein, die kleine sitzt oben rechts darüber. */
.bk-karte[data-art="bargeld"] {
  background:
    radial-gradient(circle 70px at 90% 8%, rgba(255, 255, 255, .20) 0 100%, transparent 0),
    radial-gradient(circle 168px at 116% 50%, #52D5BA 0 100%, transparent 0),
    var(--ib-karte-grund);
}
.bk-karte[data-art="giro"] {
  background:
    radial-gradient(circle 70px at 90% 8%, rgba(255, 255, 255, .22) 0 100%, transparent 0),
    radial-gradient(circle 168px at 116% 50%, #0890FE 0 100%, transparent 0),
    var(--ib-karte-grund);
}
.bk-karte[data-art="spar"] {
  background:
    radial-gradient(circle 70px at 90% 8%, rgba(255, 255, 255, .20) 0 100%, transparent 0),
    radial-gradient(circle 168px at 116% 50%, #5655B9 0 100%, transparent 0),
    var(--ib-karte-grund);
}
.bk-karte[data-art="gemeinschaft"] {
  background:
    radial-gradient(circle 70px at 90% 8%, rgba(255, 255, 255, .20) 0 100%, transparent 0),
    radial-gradient(circle 168px at 116% 50%, #FB6B18 0 100%, transparent 0),
    var(--ib-karte-grund);
}

.bk-karte.gesperrt, .bk-kk.gesperrt { filter: grayscale(.7); opacity: .75; }

.bk-karte-kopf, .bk-kk-kopf {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s2);
}
/* Der Kontoname steht groß und allein oben — in der Vorlage der Name des
   Karteninhabers, die größte Schrift auf der Karte. */
.bk-karte-art {
  display: flex; align-items: center; gap: 8px;
  font-size: 20px; font-weight: 600; line-height: 28px;
}
.bk-karte-art b { font-weight: 600; }
.bk-karte-sperre { opacity: .9; margin-top: 4px; }
/* Kontoart und Nummer stehen UNTEREINANDER, wie „Amazon Platinium" und die
   Kartennummer darunter in der Vorlage. In einer Zeile war die Nummer auf
   einem schmalen Telefon abgeschnitten — und eine halbe Kontonummer ist
   schlimmer als keine, weil man sie für vollständig hält.

   `margin-top: auto` sitzt an der ERSTEN der beiden Zeilen: Sie schiebt den
   Block nach unten, die zweite folgt ihr. Stünde es an beiden, rissen sie
   auseinander. */
.bk-karte-typ {
  font-size: 12px; opacity: .8; margin-top: auto;
}
.bk-karte-iban {
  font-size: 12px; opacity: .8; font-variant-numeric: tabular-nums;
  letter-spacing: .8px; margin-top: 2px; white-space: nowrap;
}
.bk-karte-fuss {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--s3); margin-top: 6px;
}
.bk-karte-wert {
  font-size: 22px; font-weight: 700; letter-spacing: 0;
  font-variant-numeric: tabular-nums; line-height: 1.2;
}
/* Die Marke unten rechts. In der Vorlage steht dort VISA; hier der Name der
   Bank — eine echte Kartenmarke wäre eine fremde. */
.bk-karte-marke {
  font-size: 15px; font-weight: 700; letter-spacing: 1.2px; opacity: .95;
  align-self: flex-end;
}

/* ── Zahlungskarte ──────────────────────────────────────────
   Dasselbe Format mit Nummernzeile statt Kontostand. Die Punkte sind
   Zierde — es gibt keine vollständige Nummer, siehe den Kopf von bank.js. */
.bk-kk {
  background:
    radial-gradient(circle 70px at 90% 8%, rgba(255, 255, 255, .18) 0 100%, transparent 0),
    radial-gradient(circle 168px at 116% 50%, #3629B7 0 100%, transparent 0),
    var(--ib-karte-grund);
  min-height: 190px;
}
.bk-kk-kopf { font-size: 17px; font-weight: 600; }
.bk-kk-chip { display: block; margin: var(--s3) 0 auto; color: #E8C87A; opacity: .9; }
.bk-kk-funk { opacity: .85; }
.bk-kk-sperre { opacity: .9; }
.bk-kk-nr {
  font-size: 17px; letter-spacing: 2.5px; font-variant-numeric: tabular-nums;
  margin: 0 0 var(--s3); opacity: .95;
}
.bk-kk-fuss {
  display: flex; justify-content: space-between; font-size: 12px; opacity: .8;
}
.bk-kk-block { margin: 0 var(--gutter) var(--s5); }
.bk-kk-block .bk-kk { flex: none; max-width: none; width: 100%; }
.bk-kk-aktionen { display: flex; gap: var(--s2); margin-top: var(--s5); }
.bk-kk-aktionen .btn { flex: 1; gap: 7px; }

/* ── Kopfzahl ───────────────────────────────────────────────
   Das Gesamtvermögen über den Karten. Auf dem lila Kopf steht es weiß, sonst
   in der Hausfarbe — dieselbe Zahl, zwei Gründe. */
.bk-kopf { text-align: center; padding: 0 var(--gutter) var(--s5); }
.bk-kopf-k {
  font-size: 12px; color: var(--label-2); font-weight: 500; line-height: 16px;
}
.bk-kopf-v {
  font-size: 34px; font-weight: 700; margin-top: 2px; color: var(--ib-primaer);
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.bk-kopf-iban {
  font-size: 12px; color: var(--label-2); margin-top: 6px;
  font-variant-numeric: tabular-nums; letter-spacing: .8px;
}

/* ── Das Kachelraster ───────────────────────────────────────
   Neun weiße Kacheln zu dritt — der Bildschirm, an dem man die Vorlage
   sofort erkennt. Symbol oben, Beschriftung darunter, beides mittig.

   `align-content: start` und feste Mindesthöhe: Deutsche Wörter sind länger
   als englische („Daueraufträge" gegen „Transfer"), und ohne feste Höhe
   stünde jede Reihe anders hoch. */
.bk-kacheln {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s3);
  padding: 0 var(--gutter) var(--s5);
}
.bk-kachel {
  background: var(--bg-elev); border-radius: var(--r-card);
  box-shadow: var(--ib-schatten);
  padding: 16px 8px 14px; min-height: 108px;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  gap: 10px; text-decoration: none; color: var(--label);
  position: relative;
}
.bk-kachel-sym {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: none;
}
.bk-kachel-name {
  font-size: 12px; font-weight: 500; line-height: 16px; text-align: center;
  color: var(--label-2); overflow-wrap: anywhere;
}
/* Der Zähler an der Ecke, wie an einem App-Symbol. */
.bk-kachel-punkt {
  position: absolute; top: 8px; right: 8px; min-width: 18px; height: 18px;
  border-radius: 9px; background: var(--red); color: #fff; font-size: 11px;
  font-weight: 600; font-style: normal; display: flex; align-items: center;
  justify-content: center; padding: 0 5px; line-height: 1;
}

/* Die Farbrollen der Kacheln. Das Symbol steht hier OHNE Fläche, es ist
   selbst die Farbe — deshalb eine eigene Tabelle und nicht die von
   .ic-kreis, die Hintergründe vergibt. Die Tonnamen sind dieselben, damit
   ein Symbol auf Kachel und in der Liste gleich eingefärbt bleibt. */
.bk-kachel-sym { color: var(--ib-primaer); }
.bk-kachel-sym[data-ton="indigo"] { color: #3629B7; }
.bk-kachel-sym[data-ton="lila"]   { color: #5655B9; }
.bk-kachel-sym[data-ton="rot"]    { color: #FF4267; }
.bk-kachel-sym[data-ton="blau"]   { color: #0890FE; }
.bk-kachel-sym[data-ton="gelb"]   { color: #FFAF2A; }
.bk-kachel-sym[data-ton="gruen"]  { color: #52D5BA; }
.bk-kachel-sym[data-ton="orange"] { color: #FB6B18; }
.bk-kachel-sym[data-ton="grau"]   { color: #898989; }

/* ── Farbiges Symbolquadrat ─────────────────────────────────
   Das Erkennungszeichen der Listen in der Vorlage: ein gefülltes Quadrat mit
   Radius 12 und weißem Symbol darin. Aus dem runden grauen Kreis des
   übrigen Portals wird hier ein Quadrat — deshalb hängt die Regel an
   [data-app] und nicht am Bauteil: Außerhalb der Bank bleibt .ic-kreis, was
   es ist.

   Die FARBEN kommen weiter aus den .ic-kreis[data-ton]-Regeln weiter oben:
   Die zeigen auf --blue, --green, --red und so fort, und die stellt der
   Variablenblock am Kopf dieses Abschnitts bereits auf die Palette der
   Vorlage um. Zwei Töne fehlen dort und stehen deshalb hier. */
[data-app="bank"] .ic-kreis {
  width: 40px; height: 40px; border-radius: 12px;
}
[data-app="bank"] .ic-kreis[data-ton="lila"] { background: var(--purple); }
[data-app="bank"] .ic-kreis[data-ton="gelb"] { background: var(--yellow); }

/* ── Listen als Karten ──────────────────────────────────────
   Die Vorlage kennt keine randlosen iOS-Listen: Jede Zeile ist eine weiße
   Karte mit Schatten, oder mehrere Zeilen stehen in einer gemeinsamen. Der
   Unterschied ist größer, als er klingt — er macht aus einer Einstellungen-
   Liste eine Banking-App. */
[data-app="bank"] .group {
  background: var(--bg-elev); border-radius: var(--r-card);
  box-shadow: var(--ib-schatten); overflow: hidden;
  margin: 0 var(--gutter) var(--s5);
}
[data-app="bank"] .group-header {
  font-size: 12px; font-weight: 600; color: var(--label-2);
  text-transform: none; letter-spacing: 0;
  padding: 0 var(--gutter) 10px; margin: 0;
}
[data-app="bank"] .group-footer {
  font-size: 12px; color: var(--label-2); line-height: 16px;
  padding: 10px var(--gutter) 0;
}
[data-app="bank"] .row { padding: 14px var(--s4); gap: var(--s3); min-height: 0; }
/* Die Trennlinie liegt im Portal als Pseudoelement an der Zeile, nicht als
   border — sie wird hier nur umgefärbt und auf volle Breite gezogen, NICHT
   durch ein border-top ersetzt: Beides zusammen zeichnete doppelt. */
[data-app="bank"] .row + .row::before {
  left: 0; height: 1px; background: var(--separator);
}
/* `display: block` ist hier kein Schoenheitsfehler-Fix, sondern Pflicht:
   listenZeile() setzt Titel und Unterzeile als <span>, und inline stehen
   „Northside Rangers“ und „Fraktionskasse“ ohne Trennung
   hintereinander. Im uebrigen Portal faellt das nicht auf, weil die
   Unterzeile dort fast immer fehlt. */
[data-app="bank"] .row-title {
  font-size: 16px; font-weight: 500; letter-spacing: 0; display: block;
}
[data-app="bank"] .row-sub {
  font-size: 12px; color: var(--label-2); letter-spacing: 0; margin-top: 2px;
  display: block;
}
[data-app="bank"] .row-value {
  font-size: 16px; font-weight: 600; color: var(--ib-primaer);
  font-variant-numeric: tabular-nums;
}
[data-app="bank"] .ic-chev { color: var(--label-3); }
[data-app="bank"] .card {
  border-radius: var(--r-card); box-shadow: var(--ib-schatten);
  margin: 0 var(--gutter) var(--s5);
}

/* ── Umsätze ────────────────────────────────────────────────
   Betrag rechts, Stand darunter. Ausgaben rot, Eingänge in der Hausfarbe —
   in der Vorlage steht dort „+$1200" in Lila und „− $280" in Rot. */
.um-betrag { flex: none; text-align: right; }
.um-delta {
  font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.um-delta.plus { color: var(--green); }
.um-delta.minus { color: var(--label); }
[data-app="bank"] .um-delta.plus { color: var(--ib-primaer); }
[data-app="bank"] .um-delta.minus { color: #FF4267; }
.um-stand { font-size: 12px; color: var(--label-2); font-variant-numeric: tabular-nums; margin-top: 2px; }

/* ── Das Balkendiagramm ─────────────────────────────────────
   „Balance / 1000 USD" mit sechs Monatssäulen darunter. Jede Säule besteht
   aus drei Abschnitten (Eingang, Mitte, Ausgang) — in der Vorlage sind das
   drei Farben übereinander, hier Eingang und Ausgang eines Monats.

   Die Höhe kommt als Inline-Stil aus bank.js. Das ist die eine Stelle, an
   der eine Zahl in den Stil muss: Ein Balken IST seine Höhe. */
.bk-diagramm {
  background: var(--bg-elev); border-radius: var(--r-card);
  box-shadow: var(--ib-schatten);
  margin: 0 var(--gutter) var(--s5); padding: var(--s5) var(--s4) var(--s4);
}
.bk-dia-k { font-size: 12px; font-weight: 600; color: var(--label-2); }
.bk-dia-v {
  font-size: 30px; font-weight: 700; color: var(--ib-primaer);
  font-variant-numeric: tabular-nums; line-height: 1.2;
}
.bk-dia-v small { font-size: 12px; font-weight: 500; color: var(--label-2); margin-left: 6px; }
.bk-dia-feld {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 4px; height: 132px; margin-top: var(--s4);
  /* Die drei Hilfslinien der Vorlage. Als Hintergrund statt als Elemente:
     Sie tragen keine Bedeutung, nur Orientierung. */
  background-image: repeating-linear-gradient(
    to bottom, var(--separator) 0 1px, transparent 1px 33.33%);
}
.bk-dia-saeule {
  flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
  align-items: center; gap: 3px; height: 100%; min-width: 0;
}
.bk-dia-ein, .bk-dia-aus {
  width: 8px; border-radius: 4px; flex: none; min-height: 4px;
}
.bk-dia-ein { background: var(--ib-primaer); }
.bk-dia-aus { background: #FF4267; }
.bk-dia-mon {
  display: flex; justify-content: space-between; gap: 4px; margin-top: 10px;
}
.bk-dia-mon span {
  flex: 1; text-align: center; font-size: 12px; font-weight: 500;
  color: var(--label-3); min-width: 0;
}
.bk-dia-mon span.an { color: var(--ib-primaer); font-weight: 600; }

/* ── Schaltflächen ──────────────────────────────────────────
   Kapsel raus, Rechteck mit Radius 10 rein. Die Vorlage setzt den Knopf über
   die volle Breite, 48 hoch, mit halbtransparenter Fläche im gesperrten
   Zustand. */
[data-app="bank"] .btn {
  border-radius: var(--r-ctl); min-height: 48px;
  font-size: 16px; font-weight: 600; letter-spacing: 0;
}
[data-app="bank"] .btn-primary { background: var(--ib-primaer); color: #fff; }
[data-app="bank"] .btn-primary:disabled,
[data-app="bank"] .btn-primary[aria-disabled="true"] { background: #AEA9DC; }
[data-app="bank"] .btn-gray { background: var(--fill); color: var(--ib-primaer); }
[data-app="bank"] .btn-danger { background: #FFE7EC; color: #FF4267; }
[data-app="bank"] .btn-block { margin: 0 var(--gutter) var(--s5); }
[data-app="bank"] .btn-mini { min-height: 34px; font-size: 13px; padding: 0 14px; }

/* Eingabefelder: weißer Kasten mit dünnem Rand statt der grauen iOS-Füllung.

   Der Selektor zielt auf `input.btn` und nicht auf `input`: Die Eingabeblätter
   der Bank hängen ihren Feldern seit jeher `class="btn btn-gray"` an, damit
   sie ohne eigenes Bauteil aussehen wie der Rest. Ohne diese Regel erbten sie
   hier die lila Schrift des grauen Knopfes — ein Betrag in Lila auf grauem
   Grund, während daneben ein echter Knopf genauso aussieht. */
[data-app="bank"] input.btn,
[data-app="bank"] select.btn,
[data-app="bank"] textarea.btn,
[data-app="bank"] input[type="text"],
[data-app="bank"] input[type="number"],
[data-app="bank"] input[type="search"],
[data-app="bank"] textarea {
  background: var(--bg-elev); border: 1px solid #EAEAEA; border-radius: var(--r-ctl);
  color: var(--label); font-weight: 500;
}
[data-app="bank"] input::placeholder,
[data-app="bank"] textarea::placeholder { color: var(--label-3); }

/* Segmentierter Umschalter: aktives Feld voll ausgefüllt, nicht als weiße
   Pille auf grauer Spur. */
[data-app="bank"] .segmented {
  background: var(--fill); border-radius: var(--r-ctl); padding: 4px;
  margin: 0 var(--gutter) var(--s5);
}
[data-app="bank"] .segmented button {
  border-radius: 8px; font-size: 15px; font-weight: 600; min-height: 40px;
  color: var(--label-2);
}
[data-app="bank"] .segmented button[aria-selected="true"] {
  background: var(--ib-primaer); color: #fff; box-shadow: none;
}

/* Fortschrittsbalken (Sparziel, Kredit) in der Hausfarbe. */
[data-app="bank"] .bar-fort { background: var(--fill); border-radius: 999px; height: 8px; }
[data-app="bank"] .bar-fort i { background: var(--ib-primaer); border-radius: 999px; }
.bk-ziel.voll .bar-fort i { background: var(--green); }
.bk-ziel-kopf { display: flex; align-items: center; gap: var(--s3); }
.bk-ziel-kopf b { flex: 1; font-weight: 600; }
.bk-ziel-kopf .num {
  font-variant-numeric: tabular-nums; font-size: 14px; font-weight: 600;
  color: var(--ib-primaer);
}

/* Der leere Zustand: In der Vorlage ein großes Bild, hier das Symbol im
   hellen Feld — ohne Illustrationen, die es nicht gibt. */
[data-app="bank"] .zustand-ic {
  border-radius: 20px; background: var(--fill); color: var(--ib-primaer);
}
[data-app="bank"] .hint { font-size: 12px; color: var(--label-2); line-height: 17px; }

/* ── Zähler und Kleinkram ───────────────────────────────────
   Bleiben, weil bank.js sie benutzt. `bk-stand` und `bk-aktionen` standen
   hier bis zum 31.08.2026 ohne einen einzigen Nutzer und sind entfallen. */
.row-zaehler {
  flex: none; min-width: 20px; height: 20px; border-radius: 10px;
  background: var(--red); color: #fff; font-size: 12px; font-weight: 600;
  display: flex; align-items: center; justify-content: center; padding: 0 6px;
  font-variant-numeric: tabular-nums;
}
.matt { opacity: .5; }
.mt3 { margin-top: var(--s3); }
.zustand-ic {
  display: flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; margin: 0 auto var(--s3);
  border-radius: 50%; background: var(--fill); color: var(--label-3);
}

/* ── Die Tab-Leiste der Bank ────────────────────────────────
   Flach, weiß, über die volle Breite — nicht Apples Glaskapsel. Der aktive
   Tab ist eine lila Pille mit Symbol UND Text NEBENEINANDER; die übrigen
   zeigen nur ihr Symbol. Das ist das auffälligste Bedienelement der Vorlage.

   Das Grundgerüst (sticky, flex, das Zusammenschieben beim Scrollen) kommt
   von .az-tabs weiter unten mit; hier steht nur, was anders ist. */
[data-app="bank"] .bk-tabs {
  background: var(--bg-elev);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-radius: 999px; padding: 6px;
  box-shadow: 0 6px 24px rgba(54, 41, 183, .12);
}
[data-app="bank"] .bk-tab {
  flex-direction: row; gap: 8px; min-height: 44px; color: var(--label-2);
  padding: 0 10px;
}
[data-app="bank"] .bk-tab.an { background: var(--ib-primaer); color: #fff; }
[data-app="bank"] .bk-tab-name {
  font-size: 14px; font-weight: 600; max-height: none;
}
/* Nur der aktive Tab trägt seinen Namen — die anderen sind reine Symbole. */
[data-app="bank"] .bk-tab:not(.an) .bk-tab-name {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
[data-app="bank"] .bk-tab-sym { font-size: 22px; }

/* ── Wertetafel ─────────────────────────────────────────────
   Der Bildschirm „Card" der Vorlage: links die Bezeichnung grau, rechts der
   Wert in der Hausfarbe, dazwischen nichts als eine dünne Linie. Für
   Kreditkonditionen und Kartendaten. */
.bk-tafel {
  margin: 0 var(--gutter) var(--s5);
  background: var(--bg-elev); border-radius: var(--r-card);
  box-shadow: var(--ib-schatten); padding: 4px var(--s4);
}
.bk-tafel-z {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); padding: 14px 0;
}
.bk-tafel-z + .bk-tafel-z { border-top: 1px solid var(--separator); }
.bk-tafel-k { font-size: 15px; color: var(--label-2); }
.bk-tafel-v {
  font-size: 16px; font-weight: 600; color: var(--ib-primaer);
  font-variant-numeric: tabular-nums; text-align: right;
}
/* Die Summenzeile darunter — „TOTAL" auf dem Kreditbildschirm. */
.bk-tafel-z.summe { border-top: 1px solid var(--separator); }
.bk-tafel-z.summe .bk-tafel-k {
  font-size: 16px; font-weight: 700; color: var(--label); text-transform: uppercase;
  letter-spacing: .5px;
}
.bk-tafel-z.summe .bk-tafel-v { font-size: 24px; font-weight: 700; color: #FF4267; }

/* ── Killfeed ─────────────────────────────────────────────── */
.kill-row {
  display: flex; gap: var(--s3); align-items: center; padding: 11px var(--s4);
  position: relative; width: 100%; text-align: left;
}
/* Die Trennlinie sitzt am Detailkasten, nicht an der nächsten Zeile: Zwischen
   zwei Zeilen steht immer ein Kasten, auch wenn er zugeklappt ist —
   `.kill-row + .kill-row` würde nie greifen. */
.kill-detail + .kill-row::before {
  content: ""; position: absolute; top: 0; left: var(--s4); right: 0; height: .5px; background: var(--separator);
}
.kill-row:active { background: var(--fill); }
.kill-txt { flex: 1; min-width: 0; font-size: 15px; letter-spacing: -.23px; display: block; }
.kill-txt b { font-weight: 600; }
.kill-meta { font-size: 13px; color: var(--label-2); margin-top: 3px; letter-spacing: -.08px; display: block; }
.kill-time { font-size: 13px; color: var(--label-3); flex: none; font-variant-numeric: tabular-nums; }
/* Der Pfeil zeigt nach unten, sobald die Zeile offen ist — dieselbe Drehung
   wie bei einer aufgeklappten Liste in iOS. */
.kill-pfeil { transition: transform .2s ease; }
.kill-row[aria-expanded="true"] .kill-pfeil { transform: rotate(90deg); }

.kill-detail { background: var(--fill); padding: var(--s2) var(--s4) var(--s3); }
.kd-block + .kd-block { margin-top: var(--s3); }
.kd-kopf {
  font-size: 13px; font-weight: 600; color: var(--label-2);
  letter-spacing: -.08px; margin-bottom: 4px;
}
.kd-zeile {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3);
  font-size: 15px; letter-spacing: -.23px; padding: 3px 0;
}
.kd-zeile span { color: var(--label-2); }
.kd-zeile b { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.kd-leer { font-size: 14px; color: var(--label-2); padding: var(--s2) 0; }

/* ── Rangliste ────────────────────────────────────────────── */
.rank { width: 24px; text-align: center; font-size: 15px; font-weight: 600; color: var(--label-2); flex: none; font-variant-numeric: tabular-nums; }
.rank.g1 { color: #FFD700; } .rank.g2 { color: #C0C0C0; } .rank.g3 { color: #CD7F32; }
.row.selbst { background: color-mix(in srgb, var(--blue) 10%, transparent); }

/* ── Gerätestreifen: Statusleiste, Tab-Leiste, Home-Anzeige ──
   Die drei Streifen, die ein iPhone-Bildschirm oben und unten hat.

   WICHTIG — im eigenständigen Modus verschwinden Statusleiste und
   Home-Anzeige: Ist das Portal über „Zum Home-Bildschirm" installiert, zeigt
   iOS seine ECHTEN darüber, und unsere wären doppelt zu sehen. Im Browser-Tab,
   wo es keine gibt, stehen sie. */
.statusbar {
  height: calc(var(--statusbar-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) 22px 0;
  flex: none; display: flex; align-items: center; justify-content: space-between;
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  color: var(--label);
  /* Die Uhrzeit steht in iOS unten im Streifen, nicht mittig. */
  padding-bottom: 8px;
}
.sb-zeit { font-size: 17px; font-weight: 600; letter-spacing: -.43px; font-variant-numeric: tabular-nums; }
.sb-rechts { display: flex; align-items: center; gap: 5px; }
.sb-rechts svg { display: block; }

/* Das Dock — der abgerundete, durchscheinende Block über der Home-Anzeige.

   KEINE Tab-Leiste: Eine Tab-Leiste sitzt innerhalb einer App, schaltet
   zwischen gleichrangigen Bereichen um, trägt Beschriftungen und hebt den
   ausgewählten Bereich hervor. Das Dock gehört zum Home-Bildschirm, trägt
   dieselben App-Symbole wie das Raster darüber und beschriftet sie nicht.

   Deshalb ist es NUR auf dem Home-Bildschirm zu sehen — innerhalb einer App
   gibt es auf einem iPhone kein Dock. */
.dock {
  display: none;
  flex: none;
  margin: 0 var(--gutter) var(--s2);
  padding: var(--s3) var(--s2);
  justify-content: space-around; align-items: center;
  border-radius: 34px;
  background: rgba(120,120,128,.28);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
  backdrop-filter: saturate(180%) blur(24px);
  /* Das Dock schwebt, also laeuft die Kante ringsum — und das Licht sitzt
     oben, wo ein schwebender Koerper es faengt. Vorher stand hier ein
     eigener Wert (.16); jetzt die Tokens der Vorlage. */
  box-shadow: inset 0 0 0 .5px var(--glass-stroke),
              inset 0 1px 0 -.5px var(--glass-highlight),
              0 8px 24px rgba(0,0,0,.35);
}
[data-bildschirm="start"] .dock { display: flex; }

/* ── Tab-Leiste der Apps ────────────────────────────────────
   Ein Bauteil, drei Anwender: Amazon, Tipico, Kleinanzeigen. Es stand bis
   zum 30.08.2026 DREIMAL wortgleich im Stylesheet — und lief prompt
   auseinander: `.mk-tab` wurde auf 64px gehoben, `.az-tab` und `.tp-tab`
   blieben bei 49. Deshalb steht es jetzt einmal hier.

   App-eigen ist nur die AKTIVFARBE; die bleibt im Abschnitt der jeweiligen
   App, wo man sie sucht. Der Markt bringt zusaetzlich seinen
   hervorgehobenen Mittelknopf und das Abzeichen mit.

   Form: schwebende Kapsel (iOS 26), nicht randlos klebend. `bottom` haelt
   8px Abstand zum unteren Rand; `overflow: hidden` beschneidet die Tabs auf
   die Kapselform, sonst stossen ihre Ecken durch die Rundung. Die Glaskante
   laeuft ringsum statt nur oben — es gibt keine angewachsene Seite mehr.
   Baugleich mit dem Dock. `sticky` statt `fixed`: So bleibt die Leiste im
   Scrollbereich und muss die Home-Anzeige des Rahmens nicht nachrechnen. */
.az-tabs, .tp-tabs, .mk-tabs, .bk-tabs {
  position: sticky; bottom: var(--s2); z-index: 40;
  display: flex; margin: var(--s5) var(--gutter) var(--s2);
  /* Apple: Glas 360x62 ueber einer Knopfreihe 352x54 — also 4px Luft
     ringsum. Die Breite steht ausdruecklich da, damit sie sich beim
     Minimieren auf 48px FAHREN kann; aus `auto` heraus gaebe es keine
     Bewegung, nur einen Sprung. */
  width: calc(100% - 2 * var(--gutter));
  padding: 4px;
  border-radius: var(--r-pill); overflow: hidden;
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: inset 0 0 0 .5px var(--glass-stroke),
              inset 0 1px 0 -.5px var(--glass-highlight),
              0 8px 24px rgba(0,0,0,.35);
  /* Die Hoehe folgt den Tabs; die BREITE muss mitfahren, seit die Kapsel
     beim Minimieren auf 48px zusammengeht. */
  transition: width .28s cubic-bezier(.32,.72,0,1);
}
/* Masse aus Apples Komponente: Tab 76x54, Innenmass 6/8/7/8, Abstand
   zwischen Symbol und Beschriftung 1. Mit den 4px Luft der Kapsel ergibt
   das 62 Gesamthoehe. Die Breite kommt hier aus `flex: 1` statt fester
   76px — im Portal teilen sich zwei bis fuenf Tabs die Bildschirmbreite,
   nicht Apples feste 402pt. */
.az-tab, .tp-tab, .mk-tab, .bk-tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; min-height: 54px; padding: 6px 8px 7px;
  border-radius: var(--r-pill);
  color: var(--label-2); text-decoration: none;
  transition: min-height .28s cubic-bezier(.32,.72,0,1),
              padding .28s cubic-bezier(.32,.72,0,1),
              gap .28s cubic-bezier(.32,.72,0,1);
}
/* Der aktive Tab traegt bei Apple eine helle Pille hinter sich — die
   Faerbung allein war zu wenig. Der Mittelknopf des Marktes ist davon
   ausgenommen: Er bringt seine eigene gruene Flaeche mit. */
.az-tab.an, .tp-tab.an, .mk-tab.an:not(.mitte), .bk-tab.an { background: var(--fill); }
.az-tab:active, .tp-tab:active, .mk-tab:active, .bk-tab:active { opacity: .6; }
.az-tab-sym, .tp-tab-sym, .mk-tab-sym, .bk-tab-sym { font-size: 20px; line-height: 1; }
.az-tab-name, .tp-tab-name, .mk-tab-name, .bk-tab-name {
  font-size: 10px; font-weight: 500; letter-spacing: -.08px;
  max-height: 16px; overflow: hidden;
  transition: opacity .18s ease, max-height .28s cubic-bezier(.32,.72,0,1);
}

/* ── Tab-Leisten: kompakter Zustand (iOS 26, Schritt 4) ─────
   Beim Scrollen nach unten schrumpft die Leiste und legt ihre
   Beschriftungen ab; beim Zurueckscrollen kommt beides wieder. Das ist der
   auffaelligste Bewegungseffekt des Systems — der Inhalt bekommt Platz,
   solange man liest, und die Bedienung meldet sich zurueck, sobald man
   umkehrt.

   Geschaltet von scroll-edge.js ueber die Klasse `kompakt` auf der Leiste.
   Die Regeln stehen hier EINMAL fuer alle drei Leisten, statt wie der Rest
   des Bauteils dreifach kopiert — genau diese Kopiererei hatte die Hoehen
   auseinanderlaufen lassen (49 gegen 64).

   NACH APPLES ORIGINAL: Die Leiste schrumpft nicht nur — sie
   VERSCHWINDET bis auf einen runden Knopf mit dem Symbol des aktiven
   Tabs. In der Komponente stehen die uebrigen Tabs im Zustand
   `Minimized=True` auf `visible=false`, das Glas geht von 360x62 auf
   48x48. Meine erste Fassung liess alle Tabs stehen und nahm ihnen nur
   die Beschriftung — das war eine Erfindung, kein iOS.

   Die Beschriftung faehrt ueber `max-height` weg, nicht ueber `display`:
   sonst spraenge sie, statt sich zu bewegen. Die Fahrtwerte stehen oben
   beim Bauteil, hier nur die Zielwerte. */
.az-tabs.kompakt,
.tp-tabs.kompakt,
.mk-tabs.kompakt { width: 48px; }
/* Nur der aktive Tab bleibt; die uebrigen verschwinden wie im Original. */
.az-tabs.kompakt .az-tab:not(.an),
.tp-tabs.kompakt .tp-tab:not(.an),
.mk-tabs.kompakt .mk-tab:not(.an) { display: none; }
.az-tabs.kompakt .az-tab,
.tp-tabs.kompakt .tp-tab,
.mk-tabs.kompakt .mk-tab { min-height: 40px; padding: 0; gap: 0; background: none; }
.az-tabs.kompakt .az-tab-name,
.tp-tabs.kompakt .tp-tab-name,
.mk-tabs.kompakt .mk-tab-name { opacity: 0; max-height: 0; }

/* Wer Bewegung reduziert haben moechte, bekommt den Wechsel ohne Fahrt —
   die Leiste ist dann sofort klein bzw. gross. */
@media (prefers-reduced-motion: reduce) {
  .az-tab, .tp-tab, .mk-tab, .bk-tab,
  .az-tab-name, .tp-tab-name, .mk-tab-name, .bk-tab-name { transition: none; }
}

/* Die Suchpille über dem Dock — wie das Dock nur auf dem Home-Bildschirm.
   Klein, durchscheinend, mittig: Sie soll das Hintergrundbild nicht
   zerschneiden, sondern darauf schweben. */
.suchpille {
  display: none;
  flex: none; align-self: center; align-items: center; gap: 5px;
  margin-bottom: var(--s2); padding: 6px 12px;
  border-radius: var(--r-pill);
  background: rgba(120,120,128,.32);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  color: #fff; font-size: 14px; letter-spacing: -.2px;
  box-shadow: inset 0 0 0 .5px rgba(255,255,255,.18);
}
[data-bildschirm="start"] .suchpille { display: flex; }
[data-theme="light"] .suchpille { background: rgba(255,255,255,.42); color: #000; }
.suchpille:active { opacity: .6; }

/* ── Suche über die Apps (Spotlight) ────────────────────────
   Legt sich über den ganzen Bildschirm — aber NICHT über die Statusleiste.
   In iOS bleiben Uhrzeit und Akku über der Suche sichtbar und ungetrübt.

   Deshalb beginnt die Fläche unterhalb der Statusleiste, statt sie mit
   `inset: 0` zu überdecken. Ein höherer z-index hätte es nicht getan: `.app`
   ist `position: fixed` und bildet damit einen eigenen Stapelkontext — die
   Statusleiste darin kommt gegen eine Ebene außerhalb nicht an. */
.spot {
  position: fixed;
  top: calc(env(safe-area-inset-top) + var(--statusbar-h));
  left: 0; right: 0; bottom: 0; z-index: 200;
  display: flex; flex-direction: column;
  max-width: 520px; margin: 0 auto;
  background: var(--scrim);
  -webkit-backdrop-filter: saturate(180%) blur(28px);
  backdrop-filter: saturate(180%) blur(28px);
}
.spot[hidden] { display: none; }
.spot-kopf { display: flex; align-items: center; gap: var(--s3); padding: var(--s3) var(--gutter); }
/* Maße der Suchleiste wie beim Marktplatz (Kit: 36 px hoch, Radius 10 px). */
.spot-feld {
  flex: 1; height: 36px; border: 0; border-radius: 10px;
  background: var(--fill-2); color: var(--label); font: inherit;
  font-size: 17px; line-height: 22px; padding: 0 12px 0 34px;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgba(142,142,147,1)'%3E%3Cpath d='M6.5 1a5.5 5.5 0 1 0 3.383 9.836l3.14 3.141a.75.75 0 1 0 1.061-1.06l-3.14-3.141A5.5 5.5 0 0 0 6.5 1zm0 1.5a4 4 0 1 1 0 8 4 4 0 0 1 0-8z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: 10px center; background-size: 16px 16px;
}
.spot-feld:focus { outline: none; }
.spot-ab { color: var(--blue); font-size: 17px; letter-spacing: -.43px; flex: none; }
.spot-treffer { flex: 1; overflow-y: auto; padding-bottom: var(--s6); }
.spot-hinweis { text-align: center; color: var(--label-2); font-size: 15px; padding: var(--s6) var(--gutter); }
/* Kleine Ausgabe der App-Kachel: dieselbe Bauform wie im Raster, auf
   Zeilenhöhe geschrumpft (29 px mit Radius 7 — das Maß der Symbolkacheln
   in iOS-Listen). */
.spot-kachel {
  position: relative; width: 29px; height: 29px; flex: none; border-radius: 7px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.spot-glyphe { font-size: 15px; line-height: 1; }
[data-theme="light"] .dock { background: rgba(255,255,255,.34); }
/* Im Dock trägt das Symbol keinen Namen — die Kachel steht für sich. */
.dock .hs-app { gap: 0; }

/* ── Rückfallebenen für das Glas ──────────────────────────────
   Wer Transparenz reduziert hat oder einen Browser ohne backdrop-filter
   benutzt, bekommt statt Glas eine deckende Fläche. `--sheet` ist die
   deckende Flächenfarbe des Themes (dunkel #1C1C1E, hell weiß) — ohne das
   stünde hier durchscheinendes Nichts und der Text läge auf dem Inhalt. */
@media (prefers-reduced-transparency: reduce) {
  .navbar.is-scrolled,
  .dock {
    background: var(--sheet);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .navbar.is-scrolled,
  .dock { background: var(--sheet); }
}

.homebar {
  flex: none; height: var(--homebar-h);
  display: flex; align-items: center; justify-content: center;
  background: var(--bar);
  /* Auf iPhones mit Home-Indicator sitzt der Strich sonst zu tief — unter
     der Leiste liegt noch der sichere Bereich des Geräts. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* 144x5 nach Apples „Home Indicator" (vorher 140). */
.homebar-strich {
  width: 144px; height: 5px; border-radius: 2.5px;
  background: var(--label); opacity: .9;
}

@media (display-mode: standalone) {
  .statusbar, .homebar { display: none; }
}

/* ── Blatt von unten ──────────────────────────────────────── */
/* Schwarz bei 20 % nach Apples Blatt-Bauteil (#00000033) — vorher .55 im
   Dunkeln bzw. .40 im Hellen. In iOS ist die Abdunklung hinter einem Blatt
   deutlich zurueckhaltender, als man sie in Erinnerung hat.
   Der Wert steht hier direkt und nicht in `--scrim`: Dieselbe Variable
   bedient auch die Spotlight-Suche, und die braucht mit ihrer Unschaerfe
   von 28 eine andere Deckung als ein Blatt. */
.scrim {
  position: fixed; inset: 0; background: rgba(0,0,0,.20); z-index: 90;
  opacity: 0; pointer-events: none; transition: opacity .3s ease;
}
.scrim.open { opacity: 1; pointer-events: auto; }
/* Maße aus Apples „Sheet - iPhone" (iOS 27): Ecken oben 38, Abdunklung
   schwarz bei 20 % (siehe `.scrim`), Schatten schwarz bei 18 %, 15 nach
   unten versetzt und 75 weich. Titel 20 px in SF-Pro-Semibold mit 25 px
   Zeilenhöhe. Das Blatt ist durchscheinend mit starker
   Hintergrundunschärfe — nicht deckend.

   ACHTUNG, Widerspruch: Die Foundations des Betreibers geben
   `radius/sheet` mit 28 an, Apples tatsächliches Bauteil benutzt 38. Hier
   gewinnt das Bauteil, weil die Ansage „nach Apple Original" lautete.
   Wer das umdreht, ändert es an dieser Stelle. */
.sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 100;
  max-width: 520px; margin: 0 auto;
  background: var(--sheet);
  -webkit-backdrop-filter: blur(68px) saturate(180%);
  backdrop-filter: blur(68px) saturate(180%);
  border-radius: 38px 38px 0 0;
  /* Freie Kante ist hier die Oberkante — dort sitzt das Licht. Der
     Schlagschatten hebt das Blatt vom Inhalt darunter ab. */
  box-shadow: inset 0 .5px 0 0 var(--glass-highlight),
              0 -.5px 0 0 var(--glass-stroke),
              0 -15px 75px rgba(0,0,0,.18);
  padding: var(--s2) 0 calc(env(safe-area-inset-bottom) + var(--s4));
  transform: translateY(100%);
  transition: transform .38s cubic-bezier(.32,.72,0,1);
  max-height: 88vh; overflow-y: auto;
}
.sheet.open { transform: translateY(0); }
/* Solange der Finger zieht, folgt das Blatt ohne Zeitkurve — sonst hinkt es
   hinterher. Der Griff ist die Ansage dafür, dass das geht. */
.sheet.zieht { transition: none; }
.grabber { touch-action: none; }
/* 58x4 nach Apples „Grabber" (vorher 36x5). */
.grabber { width: 58px; height: 4px; border-radius: var(--r-pill); background: var(--label-3); margin: var(--s2) auto var(--s4); }
.sheet h3 { margin: 0 var(--gutter) var(--s2); font-size: 20px; font-weight: 600; line-height: 25px; letter-spacing: -.45px; }
.sheet p.lead { margin: 0 var(--gutter) var(--s4); font-size: 15px; color: var(--label-2); line-height: 1.4; }

/* ── Zustände: laden, leer, Fehler ─────────────────────────
   Jede Liste braucht alle drei. Im Entwurf waren die Daten immer da — im
   Betrieb sind sie es nicht. */
.zustand { padding: var(--s8) var(--gutter); text-align: center; color: var(--label-2); font-size: 15px; }
.zustand .gross { font-size: 34px; margin-bottom: var(--s2); }
.spinner {
  width: 28px; height: 28px; margin: 0 auto var(--s3);
  border: 2.5px solid var(--fill-2); border-top-color: var(--label-2);
  border-radius: 50%; animation: dreh .8s linear infinite;
}
@keyframes dreh { to { transform: rotate(360deg); } }

/* ── Anmeldung ────────────────────────────────────────────── */
.mitte { min-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--s8) var(--gutter); text-align: center; }
.mitte .marke { font-size: 34px; font-weight: 700; letter-spacing: .37px; }
.mitte p { color: var(--label-2); font-size: 15px; line-height: 1.4; max-width: 320px; }

/* ── Casino ─────────────────────────────────────────────────
   Die Spielfläche ist ein GERÄT, keine Seite. Das ist die Entscheidung,
   aus der hier alles folgt: Die Bühne bleibt in beiden Erscheinungsbildern
   dunkel, weil ein Automat dunkel ist — und weil die Walzensymbole nur auf
   dunklem Grund die Leuchtkraft haben, von der ein Casino lebt. Rundherum
   bleibt das Portal, was es ist: eine helle iOS-App mit Listen.

   Bewegt werden ausschließlich `transform` und `opacity`. Jede andere
   Eigenschaft (top, height, width) zwingt den Browser, den Seitenaufbau neu
   zu rechnen — bei fünf laufenden Walzen ist das der Unterschied zwischen
   60 Bildern je Sekunde und einem Ruckeln.

   Feste Bühnenhöhe: Das Ergebnis erscheint an einer reservierten Stelle,
   damit beim Gewinn nichts springt und der Aktionsknopf dort bleibt, wo der
   Daumen ihn erwartet. */
/* Die Farben des Geräts. An der Wurzel und NICHT an der Bühne: Der
   Drehknopf liegt außerhalb der Bühne, und ein `var()`, das dort ins Leere
   zeigt, macht die ganze Angabe ungültig — der goldene Knopf war
   durchsichtig, obwohl die Regel griff. */
:root {
  --cs-gold: #E9B949;
  --cs-gold-hell: #FFE9A8;
  --cs-filz: #10261C;
  --cs-holz: #241A12;
}

.cs-buehne {
  position: relative; isolation: isolate; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 208px; padding: var(--s3);
  margin: 0 var(--gutter) var(--s3);
  border-radius: var(--r-card);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,.07), transparent 60%),
    linear-gradient(#14301F, var(--cs-filz) 55%, #0B1D14);
  box-shadow: inset 0 0 0 1px rgba(233,185,73,.22), 0 8px 24px rgba(0,0,0,.28);
  color: #fff;
}
.cs-buehne.automat, .cs-buehne.bj { justify-content: flex-start; }
.cs-gross-zeichen { font-size: 44px; font-weight: 700; line-height: 1.1; text-align: center; }
.cs-meldung { min-height: 22px; text-align: center; font-size: 14px; margin: 0 var(--gutter) var(--s3); }
.cs-meldung.ok { color: var(--green); }
.cs-meldung.err { color: var(--red); }
.cs-mitte { text-align: center; margin: var(--s2) 0 0; }
.cs-tisch { width: 100%; position: relative; }

/* Einsatz: großes Feld zwischen zwei Tasten — auf dem Handy tippt niemand
   gern Zahlen, aber jeder trifft ein 56-px-Ziel. */
.cs-einsatz { display: flex; gap: var(--s2); align-items: stretch; margin: 0 var(--gutter) var(--s3); }
.cs-schritt {
  width: 56px; min-height: 56px; border-radius: var(--r-ctl);
  background: var(--fill); color: var(--label); font-size: 24px; font-weight: 600;
  transition: transform .12s cubic-bezier(.2,.8,.3,1), background-color .12s ease;
}
.cs-schritt:active { transform: scale(.94); background: var(--fill-2); }
.cs-betrag { flex: 1; background: var(--bg-elev); border-radius: var(--r-ctl); padding: 4px 8px; text-align: center; }
.cs-betrag input {
  width: 100%; border: 0; background: none; color: var(--label);
  font: inherit; font-size: 22px; font-weight: 700; text-align: center;
  font-variant-numeric: tabular-nums; padding: 2px 0 0;
}
.cs-betrag input:focus { outline: none; }
.cs-grenzen { font-size: 11px; color: var(--label-2); }

.cs-zwei { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); margin: 0 var(--gutter) var(--s4); }
.cs-zuege { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s2); margin: 0 var(--gutter) var(--s2); }
.btn.cs-rot { background: linear-gradient(#d43b46, #a5151f); color: #fff; }
.btn.cs-schwarz { background: linear-gradient(#3f3f46, #18181b); color: #fff; border: 1px solid var(--separator); }

/* Der Auslöser. Ein Automatenknopf antwortet auf den Druck, bevor irgendein
   Netzaufruf zurück ist — sonst fragt sich der Daumen, ob er getroffen hat. */
.cs-aktion { transition: transform .1s cubic-bezier(.2,.8,.3,1), opacity .15s ease; }
.cs-aktion:not(:disabled):active { transform: scale(.965); }
.cs-dreh {
  background: linear-gradient(#FFD873, var(--cs-gold) 45%, #C4901F);
  color: #2A1C05; font-weight: 700; letter-spacing: .3px;
  box-shadow: 0 3px 0 #8A5F0B, 0 6px 16px rgba(233,185,73,.28);
}
.cs-dreh:not(:disabled):active { transform: translateY(2px) scale(.99); box-shadow: 0 1px 0 #8A5F0B; }
.cs-dreh:disabled { box-shadow: none; }

/* ── Walzwerk ───────────────────────────────────────────────
   Der Rahmen ist das Gehäuse, die Walze das Fenster, das Band der Streifen
   dahinter. Nur das Band bewegt sich. */
.cs-rahmen {
  position: relative; padding: 8px; border-radius: 14px;
  background: linear-gradient(#2E2117, var(--cs-holz) 60%, #150E08);
  box-shadow: inset 0 0 0 1.5px rgba(233,185,73,.55), 0 6px 18px rgba(0,0,0,.4);
}
.cs-maschine {
  display: grid; grid-template-columns: repeat(var(--cs-spalten, 3), 1fr); gap: 6px;
  --cs-tile: 56px;
}
.cs-walze {
  position: relative; overflow: hidden; border-radius: 8px;
  height: calc(var(--cs-tile) * var(--cs-reihen, 1));
  background: linear-gradient(#FFFFFF, #EBECF0 46%, #FDFDFE);
  box-shadow: inset 0 8px 10px -8px rgba(0,0,0,.65), inset 0 -8px 10px -8px rgba(0,0,0,.65),
              inset 0 0 0 1px rgba(0,0,0,.12);
  transition: box-shadow .12s ease;
}
/* Der Anschlag: ein kurzer Aufblitzer, wenn die Walze sitzt. Billiger und
   ruhiger als ein Verformen der ganzen Walze. */
.cs-walze.cs-anschlag {
  box-shadow: inset 0 8px 10px -8px rgba(0,0,0,.65), inset 0 -8px 10px -8px rgba(0,0,0,.65),
              inset 0 0 0 2px var(--cs-gold);
}
.cs-band { will-change: transform; }
.cs-kachel {
  height: var(--cs-tile);
  display: flex; align-items: center; justify-content: center;
  border-bottom: 1px solid rgba(0,0,0,.06);
}
.cs-sym { width: 74%; height: 74%; display: block; }
.cs-kachel.cs-treffer {
  background: radial-gradient(circle at 50% 50%, rgba(255,213,74,.75), rgba(255,213,74,0) 70%);
}

/* ── Die Walze als Körper ───────────────────────────────────
   Ein verschobenes Band ist eine Rolltreppe; eine Walze ist ein Zylinder.
   Die Flächen sitzen außen auf einer Trommel, die mittlere zeigt zum
   Betrachter, die obere und untere kippen weg.

   Drei Dinge müssen dafür zusammenkommen, und alle drei sind Pflicht:
   `perspective` am Fenster (sonst ist die Drehung eine flache Stauchung),
   `transform-style: preserve-3d` an der Trommel (sonst wird sie plattgedrückt)
   und `backface-visibility: hidden` an den Flächen (sonst scheinen die
   Rückseiten durch die Vorderseiten). */
.cs-maschine.raum .cs-walze {
  perspective: 900px;
  perspective-origin: 50% 50%;
  background: linear-gradient(#0D0906, #1A130C 50%, #0D0906);
}
/* Der Halter schiebt die Trommel um ihren Radius nach hinten. Ohne ihn läge
   die vordere Fläche um den Radius NÄHER am Auge und würde von der
   Perspektive vergrößert (bei 900 px Abstand und 234 px Radius um 35 %) —
   die obere und untere Reihe wären abgeschnitten. */
.cs-halter {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  transform: translateZ(calc(-1 * var(--cs-radius)));
}
.cs-trommel {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  will-change: transform;
}
.cs-flaeche {
  position: absolute; left: 0; right: 0;
  top: 50%; height: var(--cs-tile); margin-top: calc(var(--cs-tile) / -2);
  display: flex; align-items: center; justify-content: center;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  background: linear-gradient(#FFFFFF, #ECEDF1 50%, #FDFDFE);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.1);
}
.cs-flaeche .cs-sym { width: 74%; height: 74%; display: block; }
.cs-flaeche.cs-treffer {
  background: radial-gradient(circle at 50% 50%, #FFE9A8, #FFFFFF 72%);
  box-shadow: inset 0 0 0 2px var(--cs-gold);
}
/* Während die Trommel läuft, verwischt sie leicht — das ist der Unterschied
   zwischen „dreht sich" und „springt". */
.cs-walze.cs-rollt .cs-flaeche { filter: blur(.6px); }
.cs-walze.cs-rollt::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 3;
  background: linear-gradient(rgba(0,0,0,.5), transparent 22%, transparent 78%, rgba(0,0,0,.5));
}
/* Die Rundung des Zylinders: oben und unten etwas Schatten, in der Mitte
   ein Lichtband. Ohne das sieht die Trommel flach aus, obwohl sie es nicht
   ist — die Flächen selbst sind ja hell. */
.cs-maschine.raum .cs-walze::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background:
    linear-gradient(rgba(0,0,0,.45), rgba(0,0,0,.06) 26%, rgba(255,255,255,.14) 50%,
                    rgba(0,0,0,.06) 74%, rgba(0,0,0,.45));
}

@media (prefers-reduced-motion: reduce) {
  .cs-walze.cs-rollt .cs-flaeche { filter: none; }
}

/* Gewinnlinien liegen ÜBER den Walzen und lassen jede Berührung durch. */
.cs-linien {
  position: absolute; left: 8px; top: 8px;
  width: calc(100% - 16px); height: calc(100% - 16px);
  pointer-events: none; overflow: visible;
}
.cs-linie {
  stroke-dasharray: 1200; stroke-dashoffset: 1200;
  filter: drop-shadow(0 0 4px currentColor);
  animation: cs-linie-zieh .45s ease-out forwards, cs-linie-puls 1.1s .45s ease-in-out 2;
}
@keyframes cs-linie-zieh { to { stroke-dashoffset: 0; } }
@keyframes cs-linie-puls { 50% { opacity: .3; } }

/* Die Mittellinie des Dreiwalzers: im Ruhezustand angedeutet, beim Gewinn an. */
.cs-linie-mitte {
  position: absolute; left: 10px; right: 10px; top: 50%; height: 2px; margin-top: -1px;
  background: var(--cs-gold); opacity: .22; pointer-events: none; border-radius: 2px;
}
.cs-linie-mitte.an { opacity: 1; box-shadow: 0 0 12px var(--cs-gold); animation: cs-linie-puls 1s ease-in-out 3; }

/* Das Gewinnband unter der Maschine — dort zählt der Betrag hoch. */
.cs-gewinnband {
  margin: 10px auto 0; display: flex; gap: 10px; align-items: baseline; justify-content: center;
  padding: 5px 16px; border-radius: var(--r-pill);
  background: rgba(255,255,255,.07); color: rgba(255,255,255,.5);
  font-size: 12px; opacity: .55; transition: opacity .2s ease, background-color .25s ease;
}
.cs-gewinnband.an {
  opacity: 1; background: rgba(52,199,89,.18); color: #6FE08A;
  box-shadow: inset 0 0 0 1px rgba(52,199,89,.45);
}
.cs-gewinnband-zahl { font-size: 21px; font-weight: 700; font-variant-numeric: tabular-nums; color: #fff; }

/* ── Große Gewinne ──────────────────────────────────────────
   Abdunkeln, Betrag hochzählen, Funken. Der Moment, für den gespielt wird —
   und der einzige, der den Bildschirm kurz übernehmen darf. */
.cs-ueberlagerung {
  position: absolute; inset: 0; z-index: 5; border-radius: inherit;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.68);
}
.cs-ueber-karte { text-align: center; padding: 0 var(--s4); }
.cs-ueber-titel {
  font-size: 14px; font-weight: 700; letter-spacing: 5px; color: var(--cs-gold-hell);
  text-shadow: 0 0 16px rgba(233,185,73,.65);
}
.cs-ueber-betrag {
  font-size: 46px; font-weight: 800; line-height: 1.05; color: #fff;
  font-variant-numeric: tabular-nums; letter-spacing: -1px;
  text-shadow: 0 0 28px rgba(255,213,74,.7);
}
.cs-ueber-unter { font-size: 13px; color: rgba(255,255,255,.6); letter-spacing: 1px; }
.cs-ueberlagerung.jackpot { background: rgba(20,8,0,.78); }
.cs-ueberlagerung.jackpot .cs-ueber-titel { font-size: 17px; animation: cs-linie-puls .9s ease-in-out infinite; }
.cs-ueberlagerung.jackpot .cs-ueber-betrag { font-size: 52px; color: var(--cs-gold-hell); }

.cs-funken { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.cs-funken i {
  position: absolute; left: 50%; top: 50%; width: 8px; height: 8px;
  margin: -4px 0 0 -4px; border-radius: 2px; display: block;
}

/* ── Das Gehäuse ────────────────────────────────────────────
   Ein Geldspielgerät hat kein Formular, sondern eine Konsole: links, was man
   hat, in der Mitte, was gerade passiert, rechts, was zuletzt kam — darunter
   eine Reihe echter Tasten. Diese Aufteilung ist bei Automaten seit
   Jahrzehnten dieselbe, weil sie funktioniert: Beim Drehen fällt der Blick in
   die Mitte, beim Abrechnen nach außen.

   Die Anordnung ist Bedienkonzept, kein Gestaltungsgut — Zeichnungen, Namen
   und Beschriftungen sind in diesem Projekt entstanden. */
.cs-kabinett {
  display: flex; align-items: stretch; gap: 4px;
  margin: 0 var(--gutter) var(--s2);
}
.cs-kabinett-mitte { flex: 1; min-width: 0; }
.cs-kabinett-mitte .cs-buehne { margin: 0; }

/* Die Liniennummern an beiden Rändern. Sie leuchten auf, wenn ihre Linie
   trifft — der einzige Weg, auf dem ein Spieler sieht, WELCHE Linie gezahlt
   hat. */
.cs-linienleiste {
  display: flex; flex-direction: column; justify-content: space-evenly;
  gap: 3px; padding: var(--s3) 0; flex: 0 0 22px;
}
.cs-liniennr {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 5px;
  font-size: 11px; font-weight: 700; color: #12100C;
  background: var(--f, #8E8E93); opacity: .38;
  transition: opacity .18s ease, transform .18s cubic-bezier(.34,1.56,.64,1);
}
.cs-liniennr.an {
  opacity: 1; transform: scale(1.16);
  box-shadow: 0 0 12px var(--f, #fff);
}

/* Die Konsole */
.cs-konsole {
  margin: 0 var(--gutter) var(--s3);
  border-radius: var(--r-card);
  background: linear-gradient(#2E2117, var(--cs-holz) 55%, #170F09);
  box-shadow: inset 0 0 0 1.5px rgba(233,185,73,.45), 0 6px 16px rgba(0,0,0,.35);
  padding: var(--s2);
  color: #fff;
}
.cs-konsole-oben {
  display: flex; align-items: center; gap: var(--s2);
  padding: 4px 6px var(--s2);
}
.cs-konsole-unten {
  display: flex; align-items: stretch; gap: 6px; flex-wrap: wrap;
}
/* Zwei Gruppen: Funktionstasten und Hauptreihe. Die Hauptreihe fordert
   240 px — bekommt sie die nicht, rutschen die Funktionstasten in eine
   eigene Zeile, statt das Einsatzfeld zu zerdrücken. */
/* Umbrechend, seit Hot Fruits fünf Funktionstasten hat (Tabelle · Automatik ·
   Turbo · Ton · Vibration): Zusammen sind das 366 px, die Konsole ist auf
   einem 375-px-Gerät aber nur 327 px breit — ohne Umbruch stand „Vibration"
   über den Rand hinaus. Die übrigen Spiele haben höchstens drei Tasten und
   merken davon nichts. */
.cs-funktionstasten { display: flex; flex-wrap: wrap; gap: 6px; flex: 0 1 auto; }
.cs-hauptreihe { display: flex; gap: 6px; flex: 1 1 240px; min-width: 240px; }
/* Zwei Aktionstasten (Coinflip) brauchen mehr Grundbreite — sonst bleibt für
   den Betrag nichts übrig, statt dass die Reihe umbricht. */
.cs-hauptreihe.breit { flex-basis: 300px; min-width: 300px; }
.cs-anzeige {
  flex: 0 0 auto; min-width: 78px; text-align: left;
  padding: 4px 10px; border-radius: 8px;
  background: rgba(0,0,0,.45); box-shadow: inset 0 0 0 1px rgba(233,185,73,.25);
}
.cs-anzeige.rechts { text-align: right; }
.cs-anzeige.gross { flex: 1; display: flex; align-items: center; justify-content: center; font-size: 15px; }
.cs-anzeige-k {
  display: block; font-size: 9.5px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--cs-gold-hell); opacity: .75;
}
.cs-anzeige-v {
  display: block; font-size: 17px; font-weight: 700; color: #fff;
  font-variant-numeric: tabular-nums; line-height: 1.2;
}
/* Das Laufband in der Mitte: Es sagt, was gerade Sache ist. Feste Höhe,
   damit die Konsole beim Wechsel der Meldung nicht springt. */
.cs-konsole .cs-meldung {
  flex: 1; min-width: 0; margin: 0; min-height: 34px;
  display: flex; align-items: center; justify-content: center; text-align: center;
  padding: 0 6px; border-radius: 8px; font-size: 13.5px; font-weight: 500;
  background: rgba(0,0,0,.3); color: var(--cs-gold-hell);
}
.cs-konsole .cs-meldung.ok { color: #6FE08A; }
.cs-konsole .cs-meldung.err { color: #FF8A80; }

/* Die Tasten. Ein Automatenknopf sitzt tief im Gehäuse und kommt beim
   Drücken mit — deshalb der harte Schatten darunter statt eines Rahmens. */
.cs-taste {
  min-height: 46px; padding: 0 12px; border-radius: 9px;
  font-size: 14px; font-weight: 600; color: #F4EEE2;
  background: linear-gradient(#4A382A, #2A1E14);
  box-shadow: 0 3px 0 #150E09, inset 0 1px 0 rgba(255,255,255,.14);
  transition: transform .1s cubic-bezier(.2,.8,.3,1), box-shadow .1s ease;
}
.cs-taste:not(:disabled):active { transform: translateY(2px); box-shadow: 0 1px 0 #150E09; }
.cs-taste:disabled { opacity: .45; box-shadow: none; }
.cs-taste.neben { flex: 0 0 auto; }
.cs-taste.rund { flex: 0 0 46px; font-size: 22px; font-weight: 700; padding: 0; }
.cs-taste.start {
  flex: 1 1 76px; min-width: 76px;
  background: linear-gradient(#FFD873, var(--cs-gold) 45%, #C4901F);
  color: #2A1C05; font-weight: 700; letter-spacing: .3px;
  box-shadow: 0 3px 0 #8A5F0B, inset 0 1px 0 rgba(255,255,255,.4);
}
.cs-taste.start:not(:disabled):active { box-shadow: 0 1px 0 #8A5F0B; }
.cs-taste.start.warm { background: linear-gradient(#FFB25E, #E07B1F); color: #2A1405; }
.cs-taste.rot { flex: 1; background: linear-gradient(#D43B46, #A5151F); color: #fff;
  box-shadow: 0 3px 0 #6B0D14, inset 0 1px 0 rgba(255,255,255,.2); }
.cs-taste.schwarz { flex: 1; background: linear-gradient(#3F3F46, #18181B); color: #fff;
  box-shadow: 0 3px 0 #08080A, inset 0 1px 0 rgba(255,255,255,.12); }

/* Was unter der Konsole steht: Risikoleiter, gezogene Karten, Hinweise. */
#csAutExtra:empty { display: none; }
#csAutExtra { margin-top: var(--s2); }

/* Das Einsatzfeld sitzt zwischen den Tasten, nicht darüber — und es wiegt
   SCHWERER als die Start-Taste. Bei `flex: 1` auf beiden teilten sie sich den
   Platz zur Hälfte, und vom Betrag blieben vierzehn Pixel übrig. */
.cs-konsole .cs-einsatz { flex: 3 1 150px; display: flex; gap: 5px; margin: 0; min-width: 0; }
.cs-konsole .cs-betrag {
  /* Untergrenze statt `min-width: 0`: Lieber bricht die Reihe um, als dass
     der Betrag auf null Pixel zusammenfällt. */
  flex: 1; min-width: 56px; background: rgba(0,0,0,.45); border-radius: 8px;
  box-shadow: inset 0 0 0 1px rgba(233,185,73,.25); padding: 2px 4px; text-align: center;
}
.cs-konsole .cs-betrag input {
  color: #fff; font-size: 19px; padding: 1px 0 0;
}
.cs-konsole .cs-grenzen { font-size: 9.5px; color: var(--cs-gold-hell); opacity: .8; }

/* Die Auszahlungstabelle kommt als Blatt hoch, nicht als Anhängsel. */
.cs-tabelle.offen { margin: 0 var(--gutter) var(--s4); background: var(--fill); }
.cs-tabelle[hidden] { display: none; }

@media (max-width: 360px) {
  .cs-linienleiste { flex-basis: 18px; }
  .cs-liniennr { width: 18px; height: 18px; font-size: 10px; }
  .cs-anzeige { min-width: 64px; padding: 3px 7px; }
  .cs-anzeige-v { font-size: 15px; }
  .cs-taste { font-size: 13px; padding: 0 9px; }
  .cs-taste.rund { flex-basis: 40px; }
}

/* ── Spannung ───────────────────────────────────────────────
   Die Walze, an der es hängt, wird langsamer UND sichtbar heiß: goldener
   Rahmen, pulsierender Schein, leicht angehoben. Ohne die Auszeichnung wäre
   das Langsamerwerden nur ein Ruckler. */
.cs-walze.cs-spannung {
  box-shadow: inset 0 0 0 2.5px var(--cs-gold),
              0 0 18px rgba(233,185,73,.75), 0 0 42px rgba(233,185,73,.35);
  animation: cs-spannung-puls .62s ease-in-out infinite alternate;
  z-index: 3;
}
@keyframes cs-spannung-puls {
  to { box-shadow: inset 0 0 0 3px #FFE9A8,
                   0 0 26px rgba(255,233,168,.95), 0 0 60px rgba(233,185,73,.55); }
}
.cs-walze.cs-spannung::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 4;
  background: linear-gradient(rgba(233,185,73,.28), transparent 40%,
                              transparent 60%, rgba(233,185,73,.28));
}

/* ── Gewinnstufen ───────────────────────────────────────────
   Drei Auftritte statt zweier. Der häufige mittlere Gewinn bekommt einen
   eigenen, damit „groß" groß bleiben kann. */
.cs-ueberlagerung.schoen { background: rgba(0,0,0,.55); }
.cs-ueberlagerung.schoen .cs-ueber-titel { letter-spacing: 3px; color: #BFF3CC; }
.cs-ueberlagerung.schoen .cs-ueber-betrag {
  font-size: 38px; color: #DFFBE6; text-shadow: 0 0 22px rgba(52,199,89,.6);
}
.cs-ueberlagerung.gross .cs-ueber-titel { color: var(--cs-gold-hell); }
.cs-ueberlagerung.mega { background: rgba(20,8,0,.80); }
.cs-ueberlagerung.mega .cs-ueber-titel {
  font-size: 17px; animation: cs-linie-puls .9s ease-in-out infinite;
}
.cs-ueberlagerung.mega .cs-ueber-betrag { font-size: 52px; color: var(--cs-gold-hell); }
/* Der Strahlenkranz hinter dem Mega-Auftritt: dreht langsam, damit die
   Fläche nicht tot steht, während der Zähler läuft. */
.cs-ueberlagerung.mega .cs-ueber-karte::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 460px; height: 460px; margin: -230px 0 0 -230px; z-index: -1;
  border-radius: 50%; opacity: .20; pointer-events: none;
  background: repeating-conic-gradient(from 0deg, var(--cs-gold) 0deg 7deg,
                                       transparent 7deg 14deg);
  animation: dreh 9s linear infinite;
}
.cs-ueber-karte { position: relative; }

/* ── Turbo ──────────────────────────────────────────────────
   Eine Taste, die eingerastet bleibt — Zustand am Knopf, nicht in einem
   Menü. */
.cs-taste.turbo { flex: 0 0 auto; font-size: 12.5px; letter-spacing: .3px; }
.cs-taste.turbo.an {
  background: linear-gradient(#5EE0A0, #21A468);
  color: #06301D;
  box-shadow: 0 3px 0 #0E5C39, inset 0 1px 0 rgba(255,255,255,.4);
}

/* Die Automatik. Bernstein statt Grün: Turbo ändert nur das Tempo,
   die Automatik setzt selbstständig Geld — die beiden dürfen im
   Augenwinkel nicht verwechselbar sein. Im eingeschalteten Zustand
   pulst sie langsam, damit man sie auch dann bemerkt, wenn man
   gerade auf die Walzen schaut. */
.cs-taste.auto { flex: 0 0 auto; font-size: 12.5px; letter-spacing: .3px; }
.cs-taste.auto.an {
  background: linear-gradient(#FFD54A, #E09A16);
  color: #3A2506;
  box-shadow: 0 3px 0 #9A6A0C, inset 0 1px 0 rgba(255,255,255,.45);
  animation: cs-auto-puls 1.8s ease-in-out infinite;
}
@keyframes cs-auto-puls {
  0%, 100% { box-shadow: 0 3px 0 #9A6A0C, inset 0 1px 0 rgba(255,255,255,.45),
                         0 0 0 0 rgba(255,213,74,.55); }
  50%      { box-shadow: 0 3px 0 #9A6A0C, inset 0 1px 0 rgba(255,255,255,.45),
                         0 0 0 6px rgba(255,213,74,0); }
}
@media (prefers-reduced-motion: reduce) {
  .cs-taste.auto.an { animation: none; }
}

/* ── Leben im Ruhezustand ───────────────────────────────────
   Ein Automat, an dem nichts leuchtet, sieht kaputt aus. Solange keine
   Runde läuft, wandert ein Lichtstreifen über den Rahmen und die
   Start-Taste atmet — beides langsam genug, um nicht zu stören. */
.cs-rahmen::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; overflow: hidden;
  background: linear-gradient(105deg, transparent 38%, rgba(255,233,168,.13) 50%,
                              transparent 62%);
  background-size: 260% 100%;
  animation: cs-streifen 7s linear infinite;
}
.cs-laeuft .cs-rahmen::after, .cs-freispiel .cs-rahmen::after { animation: none; opacity: 0; }
@keyframes cs-streifen {
  from { background-position: 160% 0; }
  to   { background-position: -60% 0; }
}
.cs-taste.start:not(:disabled) { animation: cs-atmen 3.4s ease-in-out infinite; }
.cs-laeuft ~ .cs-konsole .cs-taste.start { animation: none; }
@keyframes cs-atmen {
  50% { box-shadow: 0 3px 0 #8A5F0B, inset 0 1px 0 rgba(255,255,255,.4),
                    0 0 20px rgba(233,185,73,.45); }
}

@media (prefers-reduced-motion: reduce) {
  .cs-walze.cs-spannung { animation: none; }
  .cs-rahmen::after, .cs-taste.start { animation: none; }
  .cs-ueberlagerung.mega .cs-ueber-karte::before { animation: none; }
}

/* ── Coinflip ───────────────────────────────────────────────
   Zwei Ebenen: außen der Wurf (auf und ab), innen die Drehung. Getrennt,
   weil beide ihre eigene Beschleunigung brauchen. */
.cs-tisch-muenze {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding-top: 10px; min-height: 176px;
}
.cs-muenz-schatten {
  position: absolute; bottom: 30px; left: calc(50% - 42px); width: 84px; height: 12px;
  border-radius: 50%; background: rgba(0,0,0,.6); filter: blur(5px); opacity: .35;
}
.cs-tisch-muenze { perspective: 900px; perspective-origin: 50% 55%; }
.cs-wurf { width: 112px; height: 112px; perspective: 720px; transform-style: preserve-3d; }
.cs-muenze { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; }
.cs-muenz-flaeche {
  position: absolute; inset: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.cs-muenz-flaeche.zahl { transform: rotateX(180deg); }
.cs-muenz-seite { width: 100%; height: 100%; display: block;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,.45)); }
.cs-muenz-ergebnis { font-size: 20px; font-weight: 700; min-height: 26px; }
.cs-muenz-ergebnis.ok { color: #6FE08A; }
.cs-muenz-ergebnis.err { color: #FF6B60; }

/* ── Crash ──────────────────────────────────────────────────
   Die Kurve wird gemalt, nicht gebaut: Jede Bildzeit kommt ein Punkt dazu,
   und der Maßstab wächst mit. Als SVG wären das Hunderte Knoten je Sekunde. */
.cs-tisch-crash { position: relative; width: 100%; height: 178px; }
.cs-kurve { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.cs-crash-zahl {
  position: absolute; left: 50%; top: 44%; transform: translate(-50%,-50%);
  font-size: 40px; font-weight: 800; letter-spacing: -1px;
  font-variant-numeric: tabular-nums; color: #6FE08A;
  text-shadow: 0 0 24px rgba(52,199,89,.45); pointer-events: none;
  contain: layout style;
}
.cs-kassiert .cs-crash-zahl { color: #6FE08A; }
.cs-geplatzt .cs-crash-zahl { color: #FF6B60; text-shadow: 0 0 24px rgba(255,59,48,.5); }
.cs-crash-hinweis {
  position: absolute; left: 0; right: 0; bottom: 6px; text-align: center;
  font-size: 12px; color: rgba(255,255,255,.5);
}
.cs-crash-funke { position: absolute; width: 0; height: 0; }

/* ── Roulette ───────────────────────────────────────────────
   Scheibe und Kugel drehen sich gegeneinander, jede als eigenes Element:
   Nur so hat jede ihre eigene Geschwindigkeit — und beide laufen über
   `transform`, also im Verdichter. */
.cs-tisch-rad { display: flex; justify-content: center; padding: 2px 0 6px; }
.cs-rad {
  position: relative; width: min(258px, 74vw); aspect-ratio: 1 / 1;
  --cs-bahn: 92px; --cs-fach: 74px;
  perspective: 760px; perspective-origin: 50% 44%;
}
/* Der Kessel liegt schräg vor dem Betrachter, nicht flach auf dem Papier.
   Die Neigung umfasst Scheibe UND Kugelarm — sonst liefe die Kugel auf einem
   Kreis über ein gekipptes Rad hinaus. */
.cs-rad-neigung {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(54deg);
}
.cs-rad-dreh, .cs-rad-arm { position: absolute; inset: 0; will-change: transform; }
.cs-rad-scheibe { width: 100%; height: 100%; display: block;
  filter: drop-shadow(0 6px 16px rgba(0,0,0,.5)); }
.cs-rad-kugel {
  position: absolute; left: 50%; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%; display: block;
  background: radial-gradient(circle at 34% 30%, #fff, #d7dae1 55%, #8d919b);
  box-shadow: 0 2px 5px rgba(0,0,0,.65);
  transform: translateY(calc(-1 * var(--cs-bahn)));
}
.cs-rad-zeiger {
  position: absolute; left: 50%; top: -2px; margin-left: -7px;
  width: 0; height: 0; border-left: 7px solid transparent; border-right: 7px solid transparent;
  border-top: 12px solid var(--cs-gold); filter: drop-shadow(0 1px 2px rgba(0,0,0,.5));
}
.cs-rad-feld {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  min-width: 46px; padding: 5px 10px; border-radius: 10px; text-align: center;
  background: rgba(0,0,0,.55); color: #fff; font-size: 22px; font-weight: 800;
  font-variant-numeric: tabular-nums; opacity: 0; pointer-events: none;
}
.cs-rad-feld.an { opacity: 1; }
.cs-rad-feld.rot { background: #B3202C; box-shadow: 0 0 18px rgba(179,32,44,.7); }
.cs-rad-feld.schwarz { background: #15161A; box-shadow: 0 0 18px rgba(0,0,0,.8); }
.cs-rad-feld.gruen { background: #0E7C3A; box-shadow: 0 0 18px rgba(14,124,58,.7); }

.cs-wetten { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 0 var(--gutter) 6px; }
.cs-wette {
  min-height: 44px; border-radius: 8px; background: var(--fill); color: var(--label);
  font-size: 13px; font-weight: 500;
  transition: transform .1s cubic-bezier(.2,.8,.3,1), background-color .15s ease;
}
.cs-wette:active { transform: scale(.96); }
.cs-wette.active { background: color-mix(in srgb, var(--blue) 20%, transparent); color: var(--blue); font-weight: 600; }
.cs-wette.rot { box-shadow: inset 3px 0 0 #b91c1c; }
.cs-wette.schwarz { box-shadow: inset 3px 0 0 #71717a; }
.cs-zahlwette { display: flex; gap: 6px; margin: 0 var(--gutter) var(--s3); }
.cs-zahlwette .cs-wette { flex: 0 0 40%; }
.cs-zahlwette input:disabled { opacity: .45; }

/* ── Blackjack ──────────────────────────────────────────────
   Karten sind eigene Plättchen mit Vorder- und Rückseite. Die Rückseite ist
   um 180° gedreht und beide Seiten sind rückseitenblind — deshalb ist das
   Umdrehen eine echte Drehung und kein Bildtausch. */
.cs-tisch-bj {
  position: relative; width: 100%; min-height: 188px; padding-top: 2px;
  perspective: 1100px; perspective-origin: 50% 30%;
}
.cs-bj-karten, .cs-bj-seite { transform-style: preserve-3d; }
.cs-stapel { position: absolute; right: 0; top: 0; width: 30px; opacity: .9; }
.cs-stapel .cs-kartenblatt {
  width: 100%; height: auto; display: block; border-radius: 4px;
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.5));
}
.cs-bj-seite { margin-bottom: var(--s3); }
.cs-bj-kopf { display: flex; gap: 8px; align-items: baseline; margin-bottom: 4px; }
.cs-bj-wer { font-size: 12px; color: rgba(255,255,255,.55); }
.cs-bj-punkte { font-size: 14px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.cs-bj-karten { display: flex; gap: 5px; flex-wrap: wrap; min-height: 62px; align-items: flex-start; }
.cs-bj-haende { display: flex; flex-direction: column; gap: var(--s2); }
.cs-bj-hand { padding: 4px 6px; border-radius: 10px; border: 1.5px solid transparent; }
.cs-bj-hand.aktiv { border-color: rgba(233,185,73,.75); background: rgba(233,185,73,.1); }
.cs-bj-ausgang { font-size: 11px; min-height: 14px; color: rgba(255,255,255,.55); }
.cs-bj-ausgang.gewonnen, .cs-bj-ausgang.blackjack { color: #6FE08A; font-weight: 600; }
.cs-bj-ausgang.verloren, .cs-bj-ausgang.bust { color: #FF6B60; }
.cs-karte3d { width: 44px; height: 62px; perspective: 560px; flex: 0 0 auto; }
.cs-karte-innen { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; }
.cs-karte3d.zu .cs-karte-innen { transform: rotateY(180deg); }
.cs-karte-vorne, .cs-karte-hinten {
  position: absolute; inset: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.cs-karte-hinten { transform: rotateY(180deg); }
.cs-kartenblatt { width: 100%; height: 100%; display: block;
  filter: drop-shadow(0 2px 4px rgba(0,0,0,.45)); }
.cs-karte3d.cs-matt { opacity: .5; }
.cs-karte3d.cs-treffer .cs-kartenblatt { filter: drop-shadow(0 0 8px rgba(255,213,74,.9)); }

/* ── Risikoleiter ───────────────────────────────────────────
   Waagerecht statt senkrecht: Fünf Stufen untereinander schöben auf dem
   Handy den Kassieren-Knopf aus dem Bild — und der ist der wichtigste
   Knopf des ganzen Spiels. */
.cs-leiter { display: flex; gap: 4px; margin: 0 var(--gutter) var(--s3); }
.cs-leiter-stufe {
  flex: 1; text-align: center; padding: 6px 2px; border-radius: 8px;
  background: var(--fill); color: var(--label-2); font-size: 11px; line-height: 1.25;
  transition: transform .18s cubic-bezier(.34,1.56,.64,1), background-color .2s ease, color .2s ease;
}
.cs-leiter-nr { display: block; font-size: 9px; opacity: .65; letter-spacing: .4px; }
.cs-leiter-betrag { display: block; font-weight: 700; font-variant-numeric: tabular-nums; }
.cs-leiter-stufe.erreicht { background: color-mix(in srgb, var(--green) 22%, transparent); color: var(--green); }
.cs-leiter-stufe.jetzt {
  background: linear-gradient(#FFD873, #E9B949); color: #2A1C05; font-weight: 700;
  transform: translateY(-3px) scale(1.06); box-shadow: 0 4px 12px rgba(233,185,73,.35);
}
.cs-leiter-stufe.verloren { background: color-mix(in srgb, var(--red) 20%, transparent); color: var(--red); }
/* Stufen jenseits des Gewinndeckels: sichtbar, aber erkennbar unerreichbar —
   sonst hofft jemand auf einen Betrag, den es gar nicht geben kann. */
.cs-leiter-stufe.gesperrt { opacity: .35; }

/* Die gezogene Karte: liegt verdeckt, dreht sich um, wenn der Server
   geantwortet hat. */
.cs-risiko { display: flex; flex-direction: column; align-items: center; gap: var(--s2); }
.cs-risiko-karte { width: 62px; height: 88px; perspective: 700px; }
.cs-risiko-karte .cs-karte-innen { width: 100%; height: 100%; }
.cs-risiko-karte.zittert { animation: cs-zittern .28s ease-in-out 2; }
@keyframes cs-zittern {
  25% { transform: translateX(-3px) rotate(-2deg); }
  75% { transform: translateX(3px) rotate(2deg); }
}
.cs-risiko-kopf { font-size: 13px; line-height: 1.35; text-align: center; margin: 0 var(--gutter) var(--s3); }
.cs-risiko-verlauf { text-align: center; font-size: 15px; margin-top: var(--s3); color: var(--label-2);
  display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; }
.cs-risiko-verlauf .cs-kartenblatt { width: 26px; height: 37px; }
.cs-risiko-verlauf span { display: inline-flex; border-radius: 4px; padding: 2px; }
.cs-risiko-verlauf .ok { background: color-mix(in srgb, var(--green) 25%, transparent); }
.cs-risiko-verlauf .err { background: color-mix(in srgb, var(--red) 25%, transparent); }

/* ── Gratis-Dreh ────────────────────────────────────────────
   Der Bonus muss anders aussehen als ein bezahlter Dreh — sonst ist er
   keiner. Deshalb Gold statt Holz, Strahlenkranz und eine einzelne, große
   Walze aus Beträgen. */
.cs-tisch-bonus {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: var(--s2);
  padding: var(--s2) 0;
}
.cs-bonus-strahlen {
  position: absolute; left: 50%; top: 50%; width: 300px; height: 300px; margin: -150px 0 0 -150px;
  border-radius: 50%; pointer-events: none; opacity: .16;
  background: repeating-conic-gradient(from 0deg, var(--cs-gold) 0deg 9deg, transparent 9deg 18deg);
  animation: dreh 26s linear infinite;
}
.cs-bonus-laeuft .cs-bonus-strahlen { animation-duration: 5s; opacity: .26; }
.cs-bonus-schild {
  font-size: 12px; font-weight: 700; letter-spacing: 4px; text-transform: uppercase;
  color: var(--cs-gold-hell); text-shadow: 0 0 14px rgba(233,185,73,.5); z-index: 1;
}
.cs-rahmen.gold {
  background: linear-gradient(#3E2E11, #241A08 65%, #150F04);
  box-shadow: inset 0 0 0 2px var(--cs-gold), 0 0 26px rgba(233,185,73,.3);
  z-index: 1; width: min(240px, 72%);
}
.cs-maschine.bonus .cs-walze { background: linear-gradient(#FFF6DC, #F2E2B4 50%, #FFFBEF); }
.cs-bonus-zahl {
  font-size: clamp(22px, 8vw, 32px); font-weight: 800; color: #2A1C05;
  font-variant-numeric: tabular-nums; letter-spacing: -.5px;
}
.cs-bonus-fertig .cs-rahmen.gold { box-shadow: inset 0 0 0 2px var(--cs-gold-hell), 0 0 40px rgba(233,185,73,.6); }

/* Der Knopf, solange der Gratis-Dreh offen ist: atmet leise, damit man ihn
   nicht übersieht. */
.cs-bonus-knopf { position: relative; overflow: hidden; }
.cs-bonus-knopf::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,.45) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: cs-glanz 2.6s ease-in-out infinite;
}
@keyframes cs-glanz { 55%, 100% { transform: translateX(120%); } }

/* Auszahlungstabelle */
.cs-tabelle { margin: 0 var(--gutter) var(--s5); background: var(--bg-elev);
  border-radius: var(--r-box); padding: var(--s3) var(--s4); }
.cs-tabelle summary { cursor: pointer; font-size: 15px; }
.cs-tabelle-zeile { display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 6px 0; font-size: 14px; border-bottom: .5px solid var(--separator); }
.cs-tabelle-zeile:last-of-type { border-bottom: 0; }
.cs-tabelle-sym { display: flex; gap: 3px; align-items: center; }
.cs-tabelle-sym .cs-sym { width: 24px; height: 24px; }
.cs-tabelle-zeile b { font-variant-numeric: tabular-nums; }

/* ── Das Goldene Buch ───────────────────────────────────────
   Derselbe Walzenkasten wie beim anderen Automaten — was ihn unterscheidet,
   sind der Freispiel-Balken und die Ausdehnung. Beides tritt nur auf, wenn es
   etwas zu sagen hat: Im Grundspiel ist der Balken nicht da. */
.cs-tisch-buch { position: relative; }
.cs-frei {
  display: none; align-items: center; gap: var(--s3);
  margin: 0 2px 8px; padding: 6px 12px; border-radius: var(--r-ctl);
  background: linear-gradient(90deg, rgba(233,185,73,.22), rgba(233,185,73,.08));
  box-shadow: inset 0 0 0 1px rgba(233,185,73,.5);
}
.cs-frei.an { display: flex; }
.cs-frei-sym { width: 36px; height: 36px; flex: 0 0 auto; }
.cs-frei-sym .cs-sym { width: 100%; height: 100%; filter: drop-shadow(0 0 6px rgba(233,185,73,.8)); }
.cs-frei-mitte { flex: 1; min-width: 0; }
.cs-frei-titel {
  font-size: 10px; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--cs-gold-hell); opacity: .8;
}
.cs-frei-zaehler { font-size: 15px; color: rgba(255,255,255,.75); }
.cs-frei-zaehler b { color: #fff; font-variant-numeric: tabular-nums; }
.cs-frei-summe { text-align: right; }
.cs-frei-betrag {
  font-size: 17px; font-weight: 700; color: #6FE08A; font-variant-numeric: tabular-nums;
}

/* Solange Freispiele laufen, wechselt der Kasten auf Gold — man soll auf
   einen Blick sehen, dass gerade nichts kostet. */
.cs-freispiel .cs-rahmen {
  background: linear-gradient(#3E2E11, #241A08 65%, #150F04);
  box-shadow: inset 0 0 0 1.5px var(--cs-gold), 0 0 22px rgba(233,185,73,.25);
}

/* Die Ausdehnung liegt ÜBER der Walze. Das Band darunter bleibt stehen —
   es trägt weiter genau das Bild, das der Server geschickt hat. */
.cs-dehnung {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column;
  transform-origin: 50% 50%;
  background: linear-gradient(#FFF6DC, #F2E2B4 50%, #FFFBEF);
  border-radius: 8px;
}
.cs-dehnung-feld {
  flex: 1; display: flex; align-items: center; justify-content: center;
}
.cs-dehnung-feld .cs-sym { width: 74%; height: 74%; }
.cs-walze.cs-dehnt {
  box-shadow: inset 0 0 0 2px var(--cs-gold), 0 0 16px rgba(233,185,73,.55);
}

/* ── Bildwalzen: Sandstein und Gold ─────────────────────────
   Ab hier gilt alles NUR für „Das Goldene Buch" (`.cs-buch-welt`). Die
   anderen sieben Spiele behalten ihre weißen Walzen und ihre Vektorsymbole —
   ein Automat, der aussieht wie die anderen, ist kein eigener Automat.

   Die Zuordnung Symbol → Datei steht in `web/portal/casino-bilder.js`; hier
   sind nur die beiden Flächen eingebunden, die CSS selbst lädt. */
:root {
  --cs-bild-hintergrund: url("/assets/casino/hintergrund.png");
  --cs-bild-rahmen: url("/assets/casino/rahmen.png");
}

/* Die Bildkachel. `contain` ist die eine Zusicherung, die eigene Dateien
   brauchen: Ein Bild mit abweichendem Seitenverhältnis sitzt dann kleiner in
   seinem Feld, aber es wird NIE verzerrt. Gestauchte Symbole sind der
   sicherste Weg, einen Automaten billig aussehen zu lassen.

   88 % gegen 74 % beim Vektor: Die PNG bringen ihren Rand schon mit (Motiv
   85 %, Rest Luft für Leuchten und Schlagschatten). Mit derselben Zahl wie
   der Vektor säßen sie sichtbar zu klein im Feld. */
.cs-bild {
  width: 88%; height: 88%;
  object-fit: contain; object-position: center;
  display: block; -webkit-user-drag: none; user-select: none;
}
.cs-flaeche .cs-bild, .cs-kachel .cs-bild { width: 88%; height: 88%; }

/* Die Wand hinter den Walzen. Zwei Verläufe darüber: einer, der die Mitte
   frei lässt, und einer, der die Ränder absenkt. Der Stein soll tragen, nicht
   mitreden. */
.cs-buch-welt.mit-bildern .cs-buehne {
  background:
    radial-gradient(120% 85% at 50% 8%, rgba(255,206,120,.16), transparent 62%),
    linear-gradient(rgba(24,14,4,.52), rgba(9,5,2,.80)),
    var(--cs-bild-hintergrund) center / cover no-repeat,
    linear-gradient(#2A1D0E, #120B04);
  box-shadow: inset 0 0 0 1px rgba(233,185,73,.32), 0 8px 24px rgba(0,0,0,.45);
}

/* Walzen aus dunklem Stein statt aus weißem Kunststoff. Der Kontrast dreht
   sich damit um: Vorher war das Symbol dunkel auf hell, jetzt leuchtet es aus
   dem Dunkeln — und genau davon leben goldene Symbole. */
.cs-buch-welt.mit-bildern .cs-walze {
  background: linear-gradient(#231708, #150D03 52%, #241809);
}
.cs-buch-welt.mit-bildern .cs-flaeche,
.cs-buch-welt.mit-bildern .cs-kachel {
  background: linear-gradient(#33240F, #1D1206 52%, #35260F);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.55);
  border-bottom-color: rgba(0,0,0,.4);
}

/* Der Treffer: Das Feld wird warm, und das Bild bekommt einen Schein, der
   SEINER FORM folgt. `drop-shadow` nimmt dafür den Alphakanal — anders als
   `box-shadow`, das nur das Rechteck kennt. Deshalb funktioniert das auch mit
   eigenen Dateien, ohne dass jemand eine Gewinnfassung malen müsste. */
.cs-buch-welt.mit-bildern .cs-flaeche.cs-treffer,
.cs-buch-welt.mit-bildern .cs-kachel.cs-treffer {
  background: radial-gradient(circle at 50% 45%, #7A5514, #2C1C07 76%);
  box-shadow: inset 0 0 0 2px var(--cs-gold);
}
.cs-buch-welt.mit-bildern .cs-treffer .cs-bild {
  filter: drop-shadow(0 0 5px rgba(255,240,196,.95))
          drop-shadow(0 0 13px rgba(233,185,73,.72));
}

/* Der Rahmen als Auflage. `border-image` schneidet die Vorlage in vier Ecken
   und vier Kanten: Die Ecken bleiben scharf, die Kanten wiederholen sich —
   deshalb sitzt der Rahmen bei jeder Bildschirmbreite richtig, ohne dass
   irgendetwas gestreckt aussieht. Die Mitte ist durchsichtig, die Walzen
   laufen darunter durch. */
.cs-rahmen-bild {
  position: absolute; inset: 0; z-index: 5; pointer-events: none;
  border: 18px solid transparent;
  border-image: var(--cs-bild-rahmen) 96 round;
}
.cs-buch-welt:not(.mit-bildern) .cs-rahmen-bild { display: none; }
/* Der gemalte Kasten darunter wird überflüssig, sobald der Rahmen liegt. */
.cs-buch-welt.mit-bildern .cs-rahmen {
  background: #0D0803; padding: 12px;
  box-shadow: 0 8px 22px rgba(0,0,0,.55);
}

/* ── Freispiele: dieselbe Kammer, anderes Licht ─────────────
   Im Grundspiel steht der Automat im warmen Sandlicht. In den Freispielen
   kippt alles ins Kühle — man sieht auf einen Blick, dass gerade ein anderes
   Spiel läuft, ohne dass es irgendwo geschrieben stünde. */
.cs-buch-welt.mit-bildern .cs-buehne.cs-freispiel {
  background:
    radial-gradient(120% 85% at 50% 8%, rgba(150,190,255,.20), transparent 62%),
    linear-gradient(rgba(14,12,48,.62), rgba(4,4,18,.86)),
    var(--cs-bild-hintergrund) center / cover no-repeat,
    linear-gradient(#161238, #070518);
  box-shadow: inset 0 0 0 1px rgba(150,190,255,.35), 0 8px 24px rgba(0,0,0,.5);
}
.cs-buch-welt.mit-bildern .cs-freispiel .cs-flaeche,
.cs-buch-welt.mit-bildern .cs-freispiel .cs-kachel {
  background: linear-gradient(#241E4A, #120E2A 52%, #262052);
}
.cs-buch-welt.mit-bildern .cs-freispiel .cs-walze {
  background: linear-gradient(#1A1638, #0C0A20 52%, #1C1840);
}
.cs-buch-welt.mit-bildern .cs-freispiel .cs-rahmen {
  background: #08061A;
  box-shadow: 0 8px 22px rgba(0,0,0,.6);
}
/* Der Rahmen bekommt den kühlen Stich mit — sonst hinge ein goldenes Gerät
   in einem blauen Raum. */
.cs-buch-welt.mit-bildern .cs-freispiel .cs-rahmen-bild {
  filter: hue-rotate(-28deg) saturate(.78) brightness(.92);
}
.cs-buch-welt.mit-bildern .cs-freispiel .cs-frei {
  background: linear-gradient(90deg, rgba(150,190,255,.24), rgba(150,190,255,.08));
  box-shadow: inset 0 0 0 1px rgba(150,190,255,.55);
}

/* Die Ausdehnung trägt in der Bildfassung ihre eigene Fläche — heller Stein
   statt Papier, damit das Sondersymbol darauf steht wie eine Tafel. */
.cs-buch-welt.mit-bildern .cs-dehnung {
  background: linear-gradient(#6B4A16, #3A2708 52%, #6B4A16);
  box-shadow: inset 0 0 0 2px var(--cs-gold-hell);
}
.cs-dehnung-feld .cs-bild { width: 84%; height: 84%; }
.cs-frei-sym .cs-bild {
  width: 100%; height: 100%;
  filter: drop-shadow(0 0 6px rgba(233,185,73,.8));
}

/* ── Die Auszahlungstafel ───────────────────────────────────
   Der Aufbau echter Geräte: Symbolkarten um ein Mittelfeld, Liniennummern
   an beiden Rändern, dunkle Felder mit Goldfassung vor Sandstein.

   Ein eigener Bildschirm statt einer Klappzeile, weil eine Tabelle dieser
   Art nicht gelesen, sondern überflogen wird — man sucht ein Symbol und
   will die Zahl daneben. */
.cs-tafel { position: fixed; inset: 0; z-index: 90; display: flex; }
.cs-tafel[hidden] { display: none; }
.cs-tf-grund { position: absolute; inset: 0; background: rgba(0,0,0,.72); }
/* Solange die Tafel liegt, darf die Seite darunter nicht mitscrollen. */
body.cs-tafel-offen { overflow: hidden; }

.cs-tf-blatt {
  position: relative; margin: auto;
  width: 100%; max-width: 980px; max-height: 100%;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: var(--s3) var(--s3) var(--s5);
  color: #F6EEDC;
  background:
    linear-gradient(rgba(26,16,5,.80), rgba(10,6,2,.90)),
    var(--cs-bild-hintergrund) center / cover no-repeat,
    linear-gradient(#2A1D0E, #120B04);
}
.cs-tf-blatt:focus { outline: none; }
@media (min-width: 700px) {
  .cs-tf-blatt {
    max-height: calc(100% - 2 * var(--s5));
    border-radius: var(--r-card);
    box-shadow: inset 0 0 0 2px rgba(233,185,73,.55), 0 18px 50px rgba(0,0,0,.6);
  }
}

.cs-tf-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); margin-bottom: var(--s3);
}
.cs-tf-kopf h2 {
  margin: 0; font-size: 21px; font-weight: 800; letter-spacing: .3px;
  color: var(--cs-gold-hell); text-shadow: 0 2px 0 rgba(0,0,0,.6);
}

/* Feld = Nummernstreifen · Raster · Nummernstreifen */
.cs-tf-feld { display: flex; align-items: stretch; gap: 6px; }

.cs-tf-linien {
  flex: 0 0 20px; display: flex; flex-direction: column; gap: 4px;
}
.cs-tf-linie {
  flex: 1; min-height: 22px; border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #1A1206;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.35);
}
/* Neun Farben, damit dieselbe Nummer links und rechts wiedererkennbar ist.
   Bewusst kräftig: Sie sind Wegweiser, keine Zierde. */
.cs-tf-linie.f0 { background: #4FC3F7; }
.cs-tf-linie.f1 { background: #FFD54A; }
.cs-tf-linie.f2 { background: #E05A5A; }
.cs-tf-linie.f3 { background: #7ED07E; }
.cs-tf-linie.f4 { background: #B98AE0; }
.cs-tf-linie.f5 { background: #F0913C; }
.cs-tf-linie.f6 { background: #4DD0C4; }
.cs-tf-linie.f7 { background: #E8E0D0; }
.cs-tf-linie.f8 { background: #D9A0C4; }

.cs-tf-raster {
  flex: 1; min-width: 0;
  display: grid; grid-template-columns: 1fr; gap: var(--s2);
}
@media (min-width: 760px) {
  .cs-tf-raster { grid-template-columns: 1fr 1fr; }
  .cs-tf-mitte { grid-column: 1 / -1; }
}

/* Eine Symbolkarte: Bilder links, Auszahlungen rechts. Das dunkle Feld mit
   Goldfassung ist das Motiv des ganzen Geräts, hier im Kleinen. */
.cs-tf-karte {
  display: flex; align-items: center; gap: var(--s3);
  padding: 10px 12px; border-radius: 10px;
  background: linear-gradient(#141008, #070502);
  box-shadow: inset 0 0 0 2px rgba(233,185,73,.75), 0 4px 12px rgba(0,0,0,.45);
}
.cs-tf-symbole {
  flex: 0 0 auto; display: flex; align-items: center; gap: 2px;
}
.cs-tf-symbole .cs-bild, .cs-tf-symbole .cs-sym {
  width: 52px; height: 52px;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,.5));
}
/* Mehrere Symbole auf einer Karte (gleiche Tabelle) rücken zusammen — sonst
   sprengt „Dame König" die Karte auf schmalen Geräten. */
.cs-tf-symbole .cs-bild + .cs-bild,
.cs-tf-symbole .cs-sym + .cs-sym { margin-left: -12px; }

.cs-tf-werte { flex: 1; min-width: 0; }
.cs-tf-zeile {
  display: flex; align-items: center; gap: 8px;
  font-variant-numeric: tabular-nums; line-height: 1.45;
}
.cs-tf-lauf {
  flex: 0 0 14px; text-align: right;
  font-size: 15px; font-weight: 700; color: #fff;
}
.cs-tf-punkt {
  flex: 0 0 7px; height: 7px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #FFB84D, #C2410C);
  box-shadow: 0 0 5px rgba(255,150,40,.8);
}
.cs-tf-wert {
  flex: 1; text-align: right;
  font-size: 15px; font-weight: 700; color: var(--cs-gold);
}

/* Das Mittelfeld. Es bekommt mehr Luft als die Karten, weil hier drei Dinge
   zusammenkommen, die sonst niemand erklärt: Scatter, Wild, Freispiele. */
.cs-tf-mitte {
  display: flex; flex-direction: column; align-items: center;
  gap: 6px; padding: var(--s3) var(--s4);
  border-radius: 10px; text-align: center;
  background: linear-gradient(#141008, #070502);
  box-shadow: inset 0 0 0 2px var(--cs-gold), 0 4px 14px rgba(0,0,0,.5);
}
.cs-tf-scatter {
  font-size: 12px; font-weight: 800; letter-spacing: 3px; text-transform: uppercase;
  color: #6ECBFF; text-shadow: 0 0 10px rgba(110,203,255,.55);
}
.cs-tf-buchbild .cs-bild, .cs-tf-buchbild .cs-sym {
  width: 76px; height: 76px;
  filter: drop-shadow(0 0 12px rgba(233,185,73,.65));
}
.cs-tf-werte.breit { width: 100%; max-width: 180px; }
.cs-tf-ersetzt {
  margin: 4px 0 0; font-size: 12px; font-weight: 700; letter-spacing: 1.2px;
  text-transform: uppercase; color: #F6EEDC;
}
.cs-tf-plus { font-size: 20px; font-weight: 800; color: var(--cs-gold); line-height: 1; }
.cs-tf-frei {
  margin: 0; font-size: 17px; font-weight: 800; letter-spacing: 1px;
  text-transform: uppercase; color: var(--cs-gold-hell);
  text-shadow: 0 0 12px rgba(233,185,73,.5);
}
/* Der Pfeil nach unten: reines CSS-Dreieck, kein Bild und kein Zeichen —
   eine Schriftart-Glyphe säße auf jedem Gerät anders. */
.cs-tf-pfeil {
  width: 0; height: 0;
  border-left: 9px solid transparent; border-right: 9px solid transparent;
  border-top: 11px solid var(--cs-gold);
}
.cs-tf-streifen {
  display: flex; gap: 2px; padding: 6px 10px; border-radius: 6px;
  background: linear-gradient(#F6ECD2, #D9C79B);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.3);
}
.cs-tf-seite { display: block; width: 40px; height: 40px; }
.cs-tf-seite .cs-bild, .cs-tf-seite .cs-sym { width: 100%; height: 100%; }
.cs-tf-hinweis {
  margin: 2px 0 0; font-size: 11.5px; line-height: 1.4;
  color: rgba(246,238,220,.72);
}

.cs-tf-fuss {
  margin-top: var(--s3); font-size: 12.5px; line-height: 1.55;
  color: rgba(246,238,220,.78);
}
.cs-tf-fuss p { margin: 0 0 var(--s2); }
.cs-tf-fuss b { color: #F6EEDC; }

@media (max-width: 380px) {
  .cs-tf-blatt { padding: var(--s2) var(--s2) var(--s4); }
  .cs-tf-feld { gap: 4px; }
  .cs-tf-linien { flex-basis: 16px; }
  .cs-tf-linie { font-size: 10px; min-height: 18px; }
  .cs-tf-karte { padding: 8px 9px; gap: var(--s2); }
  .cs-tf-symbole .cs-bild, .cs-tf-symbole .cs-sym { width: 44px; height: 44px; }
  .cs-tf-lauf, .cs-tf-wert { font-size: 14px; }
  .cs-tf-kopf h2 { font-size: 18px; }
}

/* ── Die Konsole des Buch-Slots ─────────────────────────────
   Am Gerät sind die drei Anzeigen abgesetzte Kästen und die Tasten farbig
   codiert: Grün startet, Blau erklärt. Man greift dort nach der Farbe, nicht
   nach der Beschriftung — und genau darum geht es bei einer Konsole, die man
   im Halbdunkeln bedient. Gilt nur hier; die anderen sieben Spiele behalten
   ihre goldene Reihe. */
.cs-buch-welt .cs-konsole {
  background: linear-gradient(#3A2A18, #1B1209 55%, #0D0804);
  box-shadow: inset 0 0 0 2px rgba(233,185,73,.55), 0 8px 20px rgba(0,0,0,.45);
}
.cs-buch-welt .cs-konsole-oben { gap: var(--s3); }
.cs-buch-welt .cs-anzeige {
  background: linear-gradient(#0B0702, #050301);
  box-shadow: inset 0 0 0 1.5px rgba(233,185,73,.5);
  padding: 5px 12px;
}
.cs-buch-welt .cs-konsole .cs-meldung {
  background: linear-gradient(#0B0702, #050301);
  box-shadow: inset 0 0 0 1.5px rgba(233,185,73,.35);
  color: var(--cs-gold-hell); font-weight: 600;
}
.cs-buch-welt .cs-taste.start {
  background: linear-gradient(#7BD86A, #2E9B34 55%, #1C6B21);
  color: #06240A; text-shadow: 0 1px 0 rgba(255,255,255,.35);
  box-shadow: 0 3px 0 #114415, inset 0 1px 0 rgba(255,255,255,.45);
}
.cs-buch-welt .cs-taste.start:not(:disabled):active { box-shadow: 0 1px 0 #114415; }
/* Der Erklärknopf blau: Er tut nichts am Geld, und das soll man sehen. */
.cs-buch-welt .cs-taste.neben[data-act="cs-regeln"] {
  background: linear-gradient(#6FA8E8, #2C5FA8 55%, #1C3F72);
  color: #F2F7FF; text-shadow: 0 1px 0 rgba(0,0,0,.35);
  box-shadow: 0 3px 0 #14294A, inset 0 1px 0 rgba(255,255,255,.35);
}
.cs-buch-welt .cs-taste.neben[data-act="cs-regeln"]:not(:disabled):active {
  box-shadow: 0 1px 0 #14294A;
}

@media (max-height: 700px) {
  .cs-buehne { min-height: 168px; }
  .cs-gross-zeichen { font-size: 34px; }
  .cs-tisch-crash { height: 148px; }
  .cs-wurf { width: 92px; height: 92px; }
  .cs-rad { width: min(196px, 60vw); }
  .cs-tisch-bj { min-height: 168px; }
  .cs-frei { padding: 4px 10px; }
  .cs-frei-sym { width: 30px; height: 30px; }
}

/* Wer „Bewegung reduzieren" gesetzt hat, bekommt dasselbe Spiel in kurz:
   Die Walzen laufen weiterhin (sonst wäre das Ergebnis wieder nur ein
   ausgetauschtes Symbol), aber alles Schmückende steht still. */
@media (prefers-reduced-motion: reduce) {
  .cs-linie { animation: cs-linie-zieh .2s ease-out forwards; }
  .cs-bonus-strahlen, .cs-bonus-knopf::after { animation: none; }
  .cs-linie-mitte.an, .cs-ueberlagerung.jackpot .cs-ueber-titel { animation: none; }
  .cs-risiko-karte.zittert { animation: none; }
  .cs-aktion, .cs-schritt, .cs-wette, .cs-leiter-stufe { transition: none; }
}

/* ── Karte (Lieferort) ──────────────────────────────────────
   Feste Höhe statt Anteil der Bildschirmhöhe: Leaflet misst beim Aufbau, und
   eine Höhe in vh ist während des Seitenwechsels noch nicht bekannt — die
   Karte bliebe grau. */
.karte {
  height: 340px; margin: 0 var(--gutter) var(--s4);
  border-radius: var(--r-card); overflow: hidden;
  background: var(--bg-elev);
}
.karte .leaflet-container { background: var(--bg-elev); }
.pick-pin { background: none; border: 0; }
.pick-pin svg { display: block; filter: drop-shadow(0 2px 3px rgba(0,0,0,.5)); }

/* ── Kleinkram ────────────────────────────────────────────── */
.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--label-2); }
.hint { font-size: 13px; color: var(--label-2); text-align: center; padding: 0 var(--gutter) var(--s6); line-height: 1.4; }
.flex { display: flex; align-items: center; }
.between { justify-content: space-between; }
.gap2 { gap: var(--s2); } .gap3 { gap: var(--s3); }
.mt2 { margin-top: var(--s2); } .mt3 { margin-top: var(--s3); }
.bar-fort { height: 6px; border-radius: 3px; background: var(--fill); overflow: hidden; }
.bar-fort i { display: block; height: 100%; border-radius: 3px; background: var(--blue); }

/* ── Mitspieler finden: Kartenstapel ────────────────────────
   Die einzige Stelle im Portal, an der eine Geste die Bedienung trägt.
   Deshalb gilt hier zweierlei:

     * `touch-action: pan-y` statt `none` — senkrecht muss die Seite weiter
       scrollen, sonst sitzt der Nutzer auf einer Karte fest. Waagerechte Züge
       kommen trotzdem als pointermove an.
     * Feste Höhe statt Anteil der Bildschirmhöhe: Die Karten liegen absolut
       übereinander und bräuchten sonst eine Höhe, die während des
       Seitenwechsels noch nicht feststeht.

   Die Knöpfe ✕/♥ machen dasselbe wie das Wischen — auf dem Desktop und für
   alle, denen Gesten nicht liegen, ist das der einzige Weg. */
.mt-zaehler {
  text-align: center; font-size: 13px; color: var(--label-2);
  padding: 0 var(--gutter) var(--s2);
}
.mt-stapel {
  position: relative; height: 430px;
  margin: 0 var(--gutter) var(--s4);
}
.mt-karte {
  position: absolute; inset: 0;
  background: var(--bg-elev); border-radius: var(--r-card);
  box-shadow: 0 8px 24px rgba(0,0,0,.28);
  padding: var(--s5) var(--s4); overflow: hidden;
  touch-action: pan-y; user-select: none; -webkit-user-select: none;
  cursor: grab;
  transition: transform .22s ease, opacity .22s ease;
  will-change: transform;
}
/* Nur die vorderste Karte ist bedienbar; die dahinter sind Andeutung. */
.mt-karte:nth-last-child(2) { transform: scale(.955) translateY(10px); }
.mt-karte:nth-last-child(3) { transform: scale(.91) translateY(20px); }
.mt-karte:not(:last-child) { pointer-events: none; }
.mt-karte.greift { transition: none; cursor: grabbing; }
.mt-karte.weg-rechts { transform: translateX(130%) rotate(18deg); opacity: 0; }
.mt-karte.weg-links  { transform: translateX(-130%) rotate(-18deg); opacity: 0; }

/* Die beiden Stempel blenden sich mit dem Zug ein (--ja/--nein setzt das
   Skript beim Ziehen). */
.mt-marke {
  position: absolute; top: var(--s4); font-size: 22px; font-weight: 800;
  letter-spacing: 1px; padding: 4px 12px; border-radius: var(--r-ctl);
  border: 3px solid currentColor; pointer-events: none;
}
.mt-marke.ja   { right: var(--s4); color: var(--green); transform: rotate(12deg);  opacity: var(--ja, 0); }
.mt-marke.nein { left: var(--s4);  color: var(--red);   transform: rotate(-12deg); opacity: var(--nein, 0); }

.mt-kopf { text-align: center; padding-bottom: var(--s3); }
.mt-kopf .avatar.lg { margin: 0 auto; }
.mt-name { font-size: 22px; font-weight: 700; letter-spacing: -.5px; margin-top: var(--s3); }
.mt-kopfzeile {
  font-size: 17px; font-weight: 600; color: var(--label);
  padding-top: var(--s3); border-top: 1px solid var(--separator);
}
.mt-text {
  font-size: 15px; color: var(--label-2); line-height: 1.45;
  margin-top: var(--s2); white-space: pre-wrap;
  /* Lange Texte dürfen die Karte nicht sprengen — der Rest steht im Match. */
  max-height: 132px; overflow: hidden;
}
.mt-leer {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  gap: var(--s2); padding: var(--s6); color: var(--label-2);
  background: var(--bg-elev); border-radius: var(--r-card);
}
.mt-leer .gross { font-size: 44px; }
.mt-leer p { font-size: 14px; max-width: 34ch; }

.mt-knoepfe {
  display: flex; justify-content: center; gap: var(--s6);
  padding: 0 var(--gutter) var(--s4);
}
.mt-knopf {
  width: 64px; height: 64px; border-radius: 50%; border: 0;
  font-size: 26px; line-height: 1; cursor: pointer;
  background: var(--bg-elev); box-shadow: 0 4px 12px rgba(0,0,0,.25);
  display: flex; align-items: center; justify-content: center;
  transition: transform .12s ease;
}
.mt-knopf:active { transform: scale(.92); }
.mt-knopf.nein { color: var(--red); }
.mt-knopf.ja   { color: var(--green); }

/* ── Marktplatz ─────────────────────────────────────────────
   Der Marktplatz kommt mit den vorhandenen Bausteinen aus (Gruppen, Zeilen,
   Karten, Pillen). Nur der gesperrte Knopf braucht eine eigene Regel: Er
   bleibt sichtbar und trägt den Grund darunter — ein verschwundener Knopf
   wirft die Frage auf, wo er hin ist. */
.btn[disabled] { opacity: .45; cursor: not-allowed; }

/* ── Marktplatz: Kachelraster ───────────────────────────────
   Die einzige Ansicht im Portal, die bewusst NICHT wie die iOS-Einstellungen
   aussieht. Kleinanzeigen leben vom Bild: zwei Spalten, quadratisches Foto,
   Preis fett darüber — die Form, die jeder von Kleinanzeigenportalen kennt und
   in der man auf einem Handy zwanzig Angebote überblickt.

   Die Kachel ist ein <a>, kein Kasten mit Knopf darin: Ein Link lässt sich in
   einem neuen Tab öffnen, lange antippen, teilen. */
/* ── Kleinanzeigen: App-Aufbau nach dem Vorbild ─────────────
   Eigene Tab-Leiste, runde Kategorien, Streifen mit dem Neuesten, Raster.
   Die Marke des Vorbilds ist grün — deshalb hier ein eigener Akzent statt des
   Portal-Blaus. Er gilt NUR in dieser App, deshalb steht er nicht bei den
   Tokens oben, sondern als Literal in den Regeln dieses Abschnitts:

     #6CB33F   die Marke — als Tönung (aktive Tab-Leiste) und als Fläche
               (mittlerer Tab-Knopf, runde Kategorie)
     #558F31   dieselbe Farbe dunkler — gedrückter Zustand des Tab-Knopfes
               und Fläche des ausgewählten Filters, wo weiße 14px-Schrift
               darauf steht und die helle Fassung zu wenig Kontrast böte

   Hier stand bis zum 30.08.2026 `.mk-app { --mk-gruen: #6CB33F; }`. Die
   Klasse `mk-app` kam in keiner einzigen JS-Datei vor, die Variable löste
   also nirgends auf — wer sie benutzt hätte, hätte eine Regel ohne Wirkung
   geschrieben. */

/* Tab-Leiste der App: Aufbau siehe „Tab-Leiste der Apps" weiter oben.
   App-eigen ist hier mehr als bei den Geschwistern — das Markt-Gruen, der
   hervorgehobene Mittelknopf und das Abzeichen am Symbol. */
.mk-tab.an { color: #6CB33F; }
/* Anker fuer `.mk-tab-punkt`, das absolut darin sitzt. */
.mk-tab-sym { position: relative; }
/* Der Einstellen-Knopf ist im Vorbild hervorgehoben — er ist die eine
   Handlung, für die man die App überhaupt öffnet. */
.mk-tab.mitte .mk-tab-sym {
  width: 30px; height: 30px; border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  background: #6CB33F; color: #fff; font-size: 19px; font-weight: 600;
}
.mk-tab.mitte.an .mk-tab-sym { background: #558F31; }
.mk-tab-punkt {
  position: absolute; top: -4px; right: -8px; min-width: 16px; height: 16px;
  padding: 0 4px; border-radius: 8px; background: var(--red); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}

/* Suchfeld des Start-Bildschirms: ein Knopf, der in die Suche führt. */
.mk-suchknopf {
  display: flex; align-items: center; gap: var(--s2);
  width: calc(100% - var(--gutter) * 2); margin: 0 var(--gutter) var(--s4);
  min-height: 36px; padding: 0 12px; border-radius: 10px;
  background: var(--fill); color: var(--label-2);
  font-size: 17px; letter-spacing: -.43px; text-align: left;
}
.mk-suchknopf:active { opacity: .6; }
.mk-lupe { font-size: 14px; }

.mk-kat:active { opacity: .6; }
.mk-kat.an .mk-kat-kreis { background: #6CB33F; }

.mk-abschnitt {
  font-size: 17px; font-weight: 600; letter-spacing: -.43px;
  padding: 0 var(--gutter) var(--s2);
}

/* Waagerechter Streifen mit dem Neuesten — scrollt für sich, wie im Vorbild. */
.mk-streifen {
  display: flex; gap: var(--s3); overflow-x: auto; scrollbar-width: none;
  padding: 0 var(--gutter) var(--s5);
  scroll-snap-type: x proximity;
}
.mk-streifen::-webkit-scrollbar { display: none; }
.mk-kachel.klein { flex: 0 0 132px; scroll-snap-align: start; }

/* ── Kleinanzeigen: Meins ───────────────────────────────────
   Kopf mit Anbieterangaben, darunter die eigenen Anzeigen als breite Zeilen
   mit Bild links und den Aktionen darunter — die Form des Vorbilds. */
.mk-meins-kopf {
  display: flex; align-items: center; gap: var(--s3);
  padding: 0 var(--gutter) var(--s5);
}
.mk-meins-name { font-size: 20px; font-weight: 600; letter-spacing: -.45px; }
.mk-meins-zeile {
  display: flex; gap: var(--s3); align-items: flex-start;
  background: var(--bg-elev); border-radius: var(--r-card);
  margin: 0 var(--gutter) var(--s3); padding: var(--s3);
}
.mk-meins-bild {
  width: 84px; height: 84px; flex: none; border-radius: var(--r-ctl);
  overflow: hidden; background: var(--fill);
  display: flex; align-items: center; justify-content: center;
}
.mk-meins-bild img { width: 100%; height: 100%; object-fit: cover; }
.mk-meins-mitte { flex: 1; min-width: 0; }
.mk-meins-titel {
  font-size: 15px; font-weight: 600; line-height: 1.3; letter-spacing: -.23px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.mk-meins-aktionen { display: flex; gap: var(--s2); margin-top: var(--s2); flex-wrap: wrap; }
.mk-meins-knopf {
  min-height: 32px; padding: 0 10px; border-radius: 8px;
  display: inline-flex; align-items: center;
  background: var(--fill); color: var(--label);
  font-size: 13px; text-decoration: none;
}
.mk-meins-knopf.rot { color: var(--red); }
.mk-meins-knopf.aus { color: var(--label-3); }
.mk-meins-knopf:active { opacity: .6; }

.mk-suchleiste {
  display: flex; align-items: center; gap: var(--s2);
  padding: 0 var(--gutter) var(--s3);
}
/* Suchleiste nach Bars/Navigation Bars/x/Light/Search Field (Knoten 0:7400):
   36 px hoch, Radius 10 px, Spurfarbe rgba(118,118,128,.12), Text 17 px bei
   22 px Zeilenhöhe. Die Lupe steckt als Hintergrundbild im Feld — ein
   <input> kann keine Kindelemente tragen, und ein zusätzliches Element um
   jedes Suchfeld wäre Aufwand ohne Gegenwert. */
.mk-suchfeld {
  flex: 1; height: 36px; border: 0; border-radius: 10px;
  background: var(--fill); color: var(--label); font: inherit;
  font-size: 17px; line-height: 22px;
  padding: 0 12px 0 34px; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='rgba(60,60,67,0.6)'%3E%3Cpath d='M6.5 1a5.5 5.5 0 1 0 3.383 9.836l3.14 3.141a.75.75 0 1 0 1.061-1.06l-3.14-3.141A5.5 5.5 0 0 0 6.5 1zm0 1.5a4 4 0 1 1 0 8 4 4 0 0 1 0-8z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 10px center;
  background-size: 16px 16px;
}
.mk-suchfeld::placeholder { color: var(--label-2); }
/* Eingabefelder in Listenzeilen: Platzhalter in rgba(60,60,67,.3) — der Wert
   aus Controls/Text Fields/Compact/Light (Knoten 0:3832). */
input::placeholder, textarea::placeholder { color: var(--label-3); }
.mk-postfach {
  position: relative; width: 44px; height: 44px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-ctl); background: var(--fill);
  font-size: 20px; text-decoration: none;
}
.mk-punkt, .mn-punkt {
  position: absolute; top: 2px; right: 2px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 9px; background: var(--red); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
}

.mk-chips {
  display: flex; gap: var(--s2); overflow-x: auto; scrollbar-width: none;
  padding: 0 var(--gutter) var(--s3);
}
.mk-chips::-webkit-scrollbar { display: none; }
.mk-chip {
  flex: none; min-height: 34px; padding: 0 14px; border: 0;
  border-radius: var(--r-pill); background: var(--fill); color: var(--label);
  font: inherit; font-size: 14px; white-space: nowrap; cursor: pointer;
}
/* Der ausgewählte Filter trägt das Markt-Grün, nicht das Portal-Blau. Das
   Blau war der einzige Bruch der Marke INNERHALB ihrer eigenen App — daneben
   steht die aktive Tab-Leiste in #6CB33F.

   Genommen wird der dunklere der beiden Grüntöne (#558F31, sonst der
   gedrückte Zustand des mittleren Tab-Knopfes), nicht #6CB33F: Die Schrift
   auf dem Chip ist 14px in Weiß. Auf #6CB33F käme sie auf ein Kontrastmaß
   von 2,6:1 und wäre schlechter lesbar als heute; #558F31 liegt bei 3,8:1
   und damit gleichauf mit dem Blau, das hier bisher stand (3,9:1). Die
   Lesbarkeit bleibt also, wie sie war, und die Farbe stimmt wieder. */
.mk-chip.an { background: #558F31; color: #fff; }

.mk-zeile { display: flex; gap: var(--s2); padding: 0 var(--gutter) var(--s3); }
.mk-mini {
  flex: 1; text-align: center; min-height: 38px; line-height: 38px;
  border-radius: var(--r-ctl); background: var(--fill); color: var(--label);
  font-size: 14px; text-decoration: none;
}

.mk-raster {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3);
  padding: 0 var(--gutter) var(--s4);
}
/* Auf breiten Anzeigen mehr Spalten — dieselbe Kachel, nur mehr davon. */
@media (min-width: 620px) { .mk-raster { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 900px) { .mk-raster { grid-template-columns: repeat(4, 1fr); } }

.mk-kachel {
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: var(--bg-elev); border-radius: var(--r-card); overflow: hidden;
  box-shadow: var(--shadow);
}
.mk-kachel:active { opacity: .7; }
/* 4:3 statt quadratisch: So sind Anzeigenfotos aufgenommen, und die Kachel
   wird dadurch rund 33px flacher — auf einen Blick passen mehr davon ins
   Raster. Das Bild füllt weiterhin per `cover`, nichts wird verzerrt. */
.mk-bild {
  position: relative; aspect-ratio: 4 / 3; background: var(--bg-elev-2);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.mk-bild img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mk-kein { font-size: 40px; opacity: .55; }
.mk-kein.gross { font-size: 72px; }
.mk-band {
  position: absolute; left: 0; top: 8px; padding: 3px 10px;
  background: var(--red); color: #fff; font-size: 11px; font-weight: 700;
  border-radius: 0 var(--r-pill) var(--r-pill) 0;
}
.mk-blitz {
  position: absolute; right: 6px; top: 6px; width: 26px; height: 26px;
  border-radius: 50%; background: var(--orange); color: #fff;
  font-size: 14px; display: flex; align-items: center; justify-content: center;
}
.mk-info { padding: var(--s3); display: flex; flex-direction: column; gap: 2px; }
.mk-preis { font-size: 16px; font-weight: 700; letter-spacing: -.3px; }
.mk-titel {
  font-size: 14px; color: var(--label-2); line-height: 1.3;
  /* Zwei Zeilen, danach abschneiden — sonst wird das Raster löchrig. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.mk-meta { font-size: 12px; color: var(--label-3); }

/* ── Marktplatz: einzelne Anzeige ───────────────────────────
   Galerie ohne Bibliothek: ein waagerechter Scrollbereich mit Einrastpunkten.
   Das kann der Browser selbst, und es fühlt sich richtiger an als jedes
   nachgebaute Karussell. */
.mk-galerie {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; background: var(--fill);
}
.mk-galerie::-webkit-scrollbar { display: none; }
.mk-gbild {
  flex: 0 0 100%; scroll-snap-align: center; aspect-ratio: 4 / 3;
  display: flex; align-items: center; justify-content: center;
}
.mk-gbild img { width: 100%; height: 100%; object-fit: contain; }
.mk-punkte { display: flex; justify-content: center; gap: 6px; padding: var(--s2) 0; }
.mk-punkte i { width: 6px; height: 6px; border-radius: 50%; background: var(--label-3); }
.mk-punkte i.an { background: var(--blue); }

.mk-kopf { padding: var(--s4) var(--gutter) var(--s2); }
.mk-gpreis { font-size: 26px; font-weight: 800; letter-spacing: -.6px; }
.mk-gtitel { font-size: 19px; font-weight: 600; line-height: 1.3; margin-top: 4px; }
.mk-block {
  background: var(--bg-elev); border-radius: var(--r-card);
  margin: 0 var(--gutter) var(--s4); padding: var(--s4);
}
.mk-block h3 { font-size: 15px; font-weight: 600; color: var(--label-2); margin-bottom: var(--s2); }
.mk-text { font-size: 16px; line-height: 1.45; white-space: pre-wrap; }
.mk-schritt {
  text-align: center; font-size: 13px; color: var(--label-2);
  padding: 0 var(--gutter) var(--s3);
}

/* Bild-Verwaltung */
.mk-fotos { display: flex; gap: var(--s2); flex-wrap: wrap; }
.mk-foto {
  position: relative; width: 92px; height: 92px; border-radius: var(--r-ctl);
  overflow: hidden; background: var(--fill); flex: none;
}
.mk-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mk-foto.neu {
  display: flex; align-items: center; justify-content: center;
  font-size: 30px; color: var(--label-2); cursor: pointer;
  border: 2px dashed var(--separator);
}
.mk-weg {
  position: absolute; top: 4px; right: 4px; width: 24px; height: 24px;
  border: 0; border-radius: 50%; background: rgba(0,0,0,.6); color: #fff;
  font-size: 13px; line-height: 1; cursor: pointer;
}
.mk-items {
  display: flex; gap: var(--s2); overflow-x: auto; scrollbar-width: none;
  padding-top: var(--s2);
}
.mk-items::-webkit-scrollbar { display: none; }
.mk-item {
  flex: none; width: 84px; border: 0; background: none; color: var(--label);
  font: inherit; font-size: 11px; cursor: pointer; text-align: center;
}
.mk-item img {
  width: 84px; height: 84px; object-fit: contain; background: var(--fill);
  border-radius: var(--r-ctl); display: block; margin-bottom: 4px;
}
.mk-item span {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mk-itembild {
  width: 56px; height: 56px; object-fit: contain; background: var(--fill);
  border-radius: var(--r-ctl);
}

/* ── Nachrichten ────────────────────────────────────────────
   Postfach als Liste, Unterhaltung als Sprechblasen. Der Verlauf scrollt in
   sich, damit das Eingabefeld immer sichtbar bleibt — auf dem Handy die
   einzige Anordnung, die mit eingeblendeter Tastatur funktioniert. */
.mn-liste { margin: 0 var(--gutter) var(--s4); }
.mn-zeile {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3); background: var(--bg-elev);
  border-radius: var(--r-card); margin-bottom: var(--s2);
  text-decoration: none; color: inherit;
}
.mn-zeile.neu { box-shadow: inset 3px 0 0 var(--blue); }
.mn-bild {
  width: 52px; height: 52px; flex: none; border-radius: var(--r-ctl);
  object-fit: cover; background: var(--fill);
  display: flex; align-items: center; justify-content: center; font-size: 22px;
}
.mn-mitte { flex: 1; min-width: 0; }
.mn-kopf { display: flex; justify-content: space-between; gap: var(--s2); }
.mn-name { font-size: 16px; font-weight: 600; }
.mn-zeit { font-size: 12px; color: var(--label-3); flex: none; }
.mn-anzeige { font-size: 12px; color: var(--blue); }
.mn-vorschau {
  font-size: 14px; color: var(--label-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mn-zeile .mn-punkt { position: static; flex: none; }

.mn-anzeigenkopf {
  display: flex; align-items: center; gap: var(--s3);
  margin: 0 var(--gutter) var(--s3); padding: var(--s3);
  background: var(--bg-elev); border-radius: var(--r-card);
  text-decoration: none; color: inherit;
}
.mn-verlauf {
  margin: 0 var(--gutter); padding: var(--s3);
  background: var(--bg-elev); border-radius: var(--r-card);
  height: 52vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--s2);
}
.mn-blase {
  max-width: 78%; padding: 8px 12px; border-radius: 18px;
  font-size: 16px; line-height: 1.35; word-wrap: break-word;
  display: flex; align-items: flex-end; gap: var(--s2);
}
.mn-blase.eigen { align-self: flex-end; background: var(--blue); color: #fff; border-bottom-right-radius: 5px; }
.mn-blase.fremd { align-self: flex-start; background: var(--fill); color: var(--label); border-bottom-left-radius: 5px; }
.mn-text { white-space: pre-wrap; }
.mn-uhr { font-size: 10px; opacity: .7; flex: none; }
.mn-system {
  align-self: center; text-align: center; font-size: 13px;
  color: var(--label-2); background: var(--fill);
  padding: 5px 12px; border-radius: var(--r-pill); max-width: 90%;
}
.mn-eingabe {
  display: flex; align-items: flex-end; gap: var(--s2);
  margin: var(--s3) var(--gutter) var(--s4);
}
.mn-eingabe textarea {
  flex: 1; border: 0; border-radius: 20px; background: var(--fill);
  color: var(--label); font: inherit; font-size: 16px; line-height: 1.35;
  padding: 11px 14px; resize: none; max-height: 120px; -webkit-appearance: none;
}
.mn-senden {
  width: 44px; height: 44px; flex: none; border: 0; border-radius: 50%;
  background: var(--blue); color: #fff; font-size: 18px; cursor: pointer;
}
.mn-senden:disabled { opacity: .5; }

/* ── Karten-App ─────────────────────────────────────────────
   Wie Apple Karten: Die Karte füllt den Bildschirm, die Bedienung schwebt
   darüber, und was man einstellen kann, steht im Blatt von unten. Kein
   Bedienfeld am Rand wie im Dashboard — auf einem Telefon ist der Platz die
   knappste Ressource. */
.ka-flaeche { position: absolute; inset: 0; background: var(--bg-elev); }
.ka-flaeche .leaflet-container { background: var(--bg-elev); }

.ka-knoepfe {
  position: absolute; right: var(--gutter); bottom: var(--gutter);
  display: flex; flex-direction: column; gap: var(--s2); z-index: 500;
}
.ka-knopf {
  width: 44px; height: 44px; border-radius: var(--r-ctl);
  display: flex; align-items: center; justify-content: center;
  font-size: 19px; color: var(--label);
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 2px 8px rgba(0,0,0,.28);
}
.ka-knopf:active { opacity: .6; }

/* Zoomknöpfe als zusammenhängende Doppeltaste — wie die schwebenden
   Bedienelemente von Apple Karten: eine Fläche, feine Trennlinie. */
.ka-zoom {
  display: flex; flex-direction: column;
  border-radius: var(--r-ctl); overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,.28);
}
.ka-zoom .ka-knopf { border-radius: 0; box-shadow: none; }
.ka-zoom .ka-knopf + .ka-knopf { border-top: .5px solid var(--separator); }

/* ── Ortssuche über der Karte ──────────────────────────────
   Feld und Trefferliste schweben oben auf der Karte (wie bei iZurvive und
   Apple Karten), im Material der Leisten: durchscheinend mit Weichzeichner.
   z-index über den Leaflet-Ebenen (max. 700), unter Scrim/Blatt (1000+). */
.ka-suche {
  position: absolute; top: var(--s3); left: var(--gutter); right: var(--gutter);
  z-index: 800; display: flex; flex-direction: column; gap: var(--s2);
}
.ka-suchfeld {
  display: flex; align-items: center; gap: var(--s2);
  height: 44px; padding: 0 var(--s3);
  border-radius: var(--r-ctl);
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 2px 8px rgba(0,0,0,.28);
  color: var(--label-2);
}
.ka-suchfeld input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none;
  font: inherit; font-size: 17px; color: var(--label);
  -webkit-appearance: none; appearance: none;
}
.ka-suchfeld input::placeholder { color: var(--label-2); }
.ka-suchfeld input::-webkit-search-cancel-button { display: none; }
.ka-suchfeld button { display: flex; color: var(--label-2); padding: 8px; margin: -8px; }
/* `display: flex` würde das hidden-Attribut überstimmen — explizit ausblenden. */
.ka-suchfeld button[hidden] { display: none; }
.ka-treffer {
  border-radius: var(--r-box); overflow: hidden auto; max-height: 352px;
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
}
.ka-treffer-zeile {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  min-height: 44px; padding: 0 var(--s4); text-align: left;
  color: var(--label); position: relative;
}
.ka-treffer-zeile + .ka-treffer-zeile::before {
  content: ""; position: absolute; top: 0; left: 46px; right: 0;
  height: .5px; background: var(--separator);
}
.ka-treffer-zeile:active { background: var(--fill); }
.ka-treffer-zeile svg { color: var(--label-2); flex: none; }
.ka-treffer-name { flex: 1; font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ka-treffer-art { font-size: 13px; color: var(--label-2); flex: none; }
.ka-treffer-leer { padding: var(--s4); font-size: 15px; color: var(--label-2); text-align: center; }

/* Blauer Puls auf dem gefundenen Ort: ein stehender Kern, ein auslaufender
   Ring. Bewegt wird nur transform/opacity. */
.ka-puls span {
  position: absolute; left: -11px; top: -11px; width: 22px; height: 22px;
  border-radius: 50%; border: 2.5px solid var(--blue);
  background: color-mix(in srgb, var(--blue) 30%, transparent);
  box-shadow: 0 0 0 1.5px rgba(255,255,255,.85);
}
.ka-puls span + span {
  background: none; box-shadow: none;
  animation: ka-puls 1.6s ease-out infinite;
}
@keyframes ka-puls {
  from { transform: scale(.6); opacity: .9; }
  to   { transform: scale(2.8); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .ka-puls span + span { animation: none; } }

/* Maßstabsleiste (Leaflet-Control) im Kartenlook: Die Karte ist immer hell,
   also dunkle Schrift auf halbtransparentem Papier — unabhängig vom
   Farbschema des Portals, wie die Ortsnamen (.ka-schrift). */
.ka-flaeche .leaflet-control-scale { margin: 0 0 var(--s3) var(--gutter); }
.ka-flaeche .leaflet-control-scale-line {
  background: rgba(249,249,249,.72); color: #14181d;
  border: 1.5px solid rgba(20,24,29,.55); border-top: none;
  border-radius: 0 0 5px 5px;
  font-family: var(--font); font-size: 10.5px; font-weight: 600;
  padding: 1px 6px 0; text-shadow: none;
}

/* Infokarte eines angetippten Ortes (Leaflet-Popup). Auch sie gehört zur
   hellen Karte, nicht zum Portal-Farbschema: helles Glas, dunkle Schrift. */
.ka-flaeche .leaflet-popup-content-wrapper {
  background: rgba(249,249,249,.94); color: #14181d;
  border-radius: var(--r-box);
  box-shadow: 0 8px 24px rgba(0,0,0,.3);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
.ka-flaeche .leaflet-popup-content { margin: 10px 12px; line-height: 1.3; }
.ka-flaeche .leaflet-popup-tip { background: rgba(249,249,249,.94); }

/* Ortsnamen werden seit 29.08.2026 abends direkt auf den CANVAS gezeichnet
   (NameMarker in karte.js), nicht mehr als DOM-Schrift: Der „Dunkelmodus für
   Webseiten“ (Samsung Internet, Chrome Auto-Dark) invertierte die dunkle
   DOM-Schrift auf Handys still zu heller — Canvas-Pixel fasst kein
   Invertierer an. Farben, Größen und Zoom-Sichtbarkeit stehen deshalb
   in karte.js (NAMEN_STIL / nameSichtbar). */
.ka-pop { display: flex; align-items: center; gap: 10px; font-family: var(--font); }
.ka-pop-bild { width: 34px; height: 34px; flex: none; }
.ka-pop-text b { display: block; font-size: 15px; font-weight: 600; letter-spacing: -.23px; }
.ka-pop-text span { display: block; margin-top: 1px; font-size: 12.5px; color: rgba(60,60,67,.65); }

/* Ebenenzeile im Blatt: Haken rechts, wenn sie an ist — wie in iOS-Listen mit
   Mehrfachauswahl. */
.ka-zeile { background: none; }
.ka-punkt {
  width: 29px; height: 29px; flex: none; border-radius: 7px;
  display: flex; align-items: center; justify-content: center; font-size: 14px;
}
/* Kachel mit dem echten Kartensymbol: Papiergrund wie die Karte selbst, damit
   Badge-Ring und Landmarken-Silhouetten so wirken wie draußen auf der Karte. */
.ka-punkt-papier { background: #F7F3E3; }
.ka-punkt-papier img { width: 25px; height: 25px; display: block; }
.ka-haken { flex: none; width: 20px; text-align: center; color: var(--blue); font-weight: 600; opacity: 0; }
.ka-zeile[aria-pressed="true"] .ka-haken { opacity: 1; }

/* ── Fraktionsmitglieder ───────────────────────────────────
   Die Blasen auf der Karte zeichnet der Canvas (MitgliedMarker in karte.js);
   hier steht nur, was im Blatt und in der Sprechblase als DOM auftaucht:
   runde Avatare, der „Du"-Anhänger und die grüne Online-Zeit. */
.ka-frak-kopf {
  width: 29px; height: 29px; flex: none; border-radius: 50%;
  object-fit: cover; background: var(--fill); display: block;
}
.ka-frak-ini {
  display: flex; align-items: center; justify-content: center;
  background: var(--green); color: #fff; font-size: 13px; font-weight: 700;
}
.ka-frak-rund { border-radius: 50%; object-fit: cover; }
/* In der Sprechblase (helles Kartenpapier, unabhängig vom Farbschema) darf
   die Initialen-Scheibe nicht die Portal-Variablen erben. */
.ka-pop .ka-frak-ini { background: #34C759; font-size: 15px; }
.ka-frak-du {
  display: inline-block; margin-left: 6px; padding: 1px 7px;
  border-radius: var(--r-pill); font-size: 12px; font-weight: 600;
  background: color-mix(in srgb, var(--blue) 15%, transparent); color: var(--blue);
  vertical-align: 1px;
}
.ka-frak-on { color: var(--green); }
.ka-zeile[aria-pressed="false"] .ka-punkt { opacity: .35; }

/* Schnellaktionen oben im Blatt (Standard / Alles aus) und der
   „Alle an/aus“-Knopf am Gruppenkopf. Der Kopf ist versal gesetzt
   (group-header) — der Knopf bewusst nicht, er ist Aktion, kein Titel. */
.ka-blatt-aktionen { display: flex; gap: var(--s2); margin: 0 var(--gutter) var(--s2); }
.ka-blatt-aktionen .btn { flex: 1; min-height: 40px; font-size: 15px; }
.ka-gruppenkopf { display: flex; align-items: baseline; justify-content: space-between; }
.ka-gruppen-alle {
  font-size: 13px; font-weight: 600; color: var(--blue);
  text-transform: none; letter-spacing: 0;
  padding: 6px 0 6px 16px; margin: -6px 0;
}

/* ── Kartenmarker ───────────────────────────────────────────
   Die Nadeln auf der Karte zeichnet der Canvas (PinMarker in karte.js).
   Hier steht, was als DOM erscheint: die Leiste beim Setzen, Symbol- und
   Farbwahl im Formular, die runden Symbolscheiben in Liste und Blatt. */

/* `display: flex` würde das hidden-Attribut überstimmen — beim Setzen
   treten die Knöpfe ab, die Leiste erscheint. */
.ka-knoepfe[hidden] { display: none; }

/* Im Material der Suchleiste, unten über der Karte. Unter Scrim/Blatt (der
   Stapelkontext von .app regelt das), damit das Formular sie überdeckt. */
.ka-setzen {
  position: absolute; left: var(--gutter); right: var(--gutter); bottom: var(--gutter);
  z-index: 800; padding: var(--s3);
  display: flex; flex-direction: column; gap: var(--s3);
  border-radius: var(--r-box);
  background: var(--bar);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
}
.ka-setzen[hidden] { display: none; }
.ka-setzen-text { margin: 0; font-size: 15px; line-height: 1.35; color: var(--label); text-align: center; }
.ka-setzen-knoepfe { display: flex; gap: var(--s2); }
.ka-setzen-knoepfe .btn { flex: 1; min-height: 44px; }
.ka-setzen-knoepfe .btn:disabled { opacity: .45; }

/* Runde Symbolscheibe in der Markerfarbe (Farbe per style aus MK_FARBEN).
   Der weiße Rand wie bei der Nadel auf der Karte — ohne ihn verschwindet
   die schwarze Scheibe auf dem dunklen Blatt. */
.ka-mk-rund {
  width: 29px; height: 29px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff;
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.9);
}
.ka-mk-rund-gross { width: 44px; height: 44px; }

/* Kopf der Einzelansicht: Scheibe neben Name und Art. Das h3 bringt im
   Blatt eigene Ränder mit — hier sitzt es in der Zeile. */
.ka-mk-kopf { display: flex; align-items: center; gap: var(--s3); margin: 0 var(--gutter) var(--s4); }
.ka-mk-kopf-text { min-width: 0; }
.ka-mk-kopf-text h3 { margin: 0; overflow-wrap: anywhere; }
.sheet p.ka-mk-notiztext { white-space: pre-line; color: var(--label); overflow-wrap: anywhere; }

/* Eingabefelder im Formular — wie im Suchprofil der Mitspielersuche. */
.ka-mk-feld {
  width: 100%; min-height: 44px; padding: 0 12px;
  text-align: left; font: inherit; font-size: 17px;
}
.ka-mk-notiz { padding: 10px 12px; min-height: 84px; resize: vertical; line-height: 1.4; }

/* Symbolwahl: vier Spalten, Name unter der Scheibe. */
.ka-mk-raster {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s2);
  margin: 0 var(--gutter) var(--s4);
}
.ka-mk-wahl {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  min-height: 66px; padding: 8px 2px 6px;
  border-radius: var(--r-box); background: var(--fill);
  box-shadow: inset 0 0 0 2px transparent;
}
.ka-mk-wahl[aria-pressed="true"] {
  background: color-mix(in srgb, var(--blue) 14%, transparent);
  box-shadow: inset 0 0 0 2px var(--blue);
}
.ka-mk-wahl-name { font-size: 11.5px; line-height: 1.2; color: var(--label); text-align: center; }

/* Farbwahl: runde Knöpfe, die gewählte mit Ring. Der innere Ring in der
   Blattfarbe trennt Farbe und Auswahlring sauber. Die feine graue Kante
   braucht Schwarz: Auf dem dunklen Blatt verschwand der Knopf sonst. */
/* 8 × 32 px + 7 × 10 px Abstand = 326 px: alle acht in einer Reihe, auch
   auf dem kleinsten Telefon (375 − 2 × 16 = 343 px). */
.ka-mk-farben { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 var(--gutter) var(--s4); }
.ka-mk-farbe {
  width: 32px; height: 32px; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(128,128,128,.6);
}
.ka-mk-farbe[aria-pressed="true"] {
  box-shadow: inset 0 0 0 1px rgba(128,128,128,.6), 0 0 0 3px var(--bg-elev), 0 0 0 5px var(--blue);
}

/* Ohne Fraktion ist „Fraktion" nicht wählbar. */
.ka-mk-sicht button:disabled { opacity: .4; }

.ka-mk-fehler { margin: 0 var(--gutter) var(--s3); font-size: 14px; line-height: 1.35; color: var(--red); text-align: center; }
.ka-mk-fehler[hidden] { display: none; }

/* ── Home-Bildschirm ────────────────────────────────────────
   Der Start-Tab ist das App-Menü. Maße nach iOS: 60 px Symbol, 22 % Radius
   (das „Squircle" lässt sich mit CSS nicht exakt nachbauen, 22 % kommt nah
   heran), Beschriftung darunter in 11 px.

   Vier Spalten sind gesetzt, nicht responsiv: Ein Home-Bildschirm mit sechs
   Spalten sähe nach Dateimanager aus, nicht nach Telefon. Auf breiten
   Anzeigen wächst stattdessen der Abstand. */
/* Hintergrundbild des Home-Bildschirms.

   Kein Apple-Bild: Die Hintergründe aus iOS sind urheberrechtlich geschützt
   und gehören nicht in dieses Repository. Stattdessen die Karte von
   Chernarus, die ohnehin mitgeliefert wird (`chernarus_preview.webp`) —
   abgedunkelt, damit die App-Symbole und ihre Beschriftungen darauf lesbar
   bleiben. Das passt zum Server und kostet keine neue Datei.

   Lädt das Bild nicht, bleibt der Farbverlauf darunter stehen.

   Das Bild liegt auf `.app`, nicht auf dem Inhalt: Nur so läuft es hinter
   Statusleiste, Navigationsleiste und Tab-Leiste durch, statt an deren Kante
   abzubrechen. Die Leisten werden auf dem Home-Bildschirm dafür durchsichtig
   — ihre Unschärfe bleibt und lässt das Bild durchscheinen, wie in iOS.

   Seit 29.08.2026 in ZWEI Schichten: obenauf die scharfe Tapete
   (chernarus_tapete.webp, 2048 px, tools/build_chernarus_tapete.py — die
   1024er-Vorschau wirkte per `cover` auf Handy-Gerätepixeln weichgezeichnet),
   darunter weiterhin die kleine Sofortansicht. Der Browser zeigt die
   Vorschau, bis die große Datei da ist — dann deckt die Tapete sie ab. */
[data-bildschirm="start"] .app {
  background-image:
    linear-gradient(180deg, rgba(0,0,0,.45), rgba(0,0,0,.72)),
    url("/assets/chernarus_tapete.webp"),
    url("/assets/chernarus_preview.webp");
  background-size: cover;
  background-position: center;
}
[data-theme="light"][data-bildschirm="start"] .app {
  background-image:
    linear-gradient(180deg, rgba(255,255,255,.55), rgba(255,255,255,.78)),
    url("/assets/chernarus_tapete.webp"),
    url("/assets/chernarus_preview.webp");
}
/* Inhalt und Leisten geben den Blick frei. Die Tab-Leiste behält ihre
   Trennlinie — sie trennt weiterhin zwei Bereiche.

   Diese Regel steht WEITER UNTEN als `.navbar.is-scrolled` und ist gleich
   spezifisch (je zwei Stellen) — deshalb gewinnt sie und die Leiste bleibt
   auf dem Home-Bildschirm auch beim Scrollen farblos. Die Reihenfolge macht
   hier die Arbeit; wer den Block verschiebt, schaltet das Glas wieder ein. */
[data-bildschirm="start"] .scroll,
[data-bildschirm="start"] .statusbar,
[data-bildschirm="start"] .navbar,
[data-bildschirm="start"] .homebar { background: transparent; }

/* Der Scroll-Edge gilt auf dem Home-Bildschirm NICHT — dort läuft die Tapete
   ununterbrochen durch, und auf einem iPhone gibt es auf dem Home-Bildschirm
   überhaupt keine Leiste, unter der Inhalt durchlaufen könnte.
   Die Farbe nimmt ihr schon die Regel darüber; hier stehen die beiden
   Eigenschaften, die sie nicht abdeckt: Der Weichzeichner bleibt dauerhaft an
   (so sah die Leiste hier immer aus), und die Trennlinie bleibt weg — eine
   Haarlinie quer über die Karte hätte die Fläche zerschnitten. */
[data-bildschirm="start"] .navbar {
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom-color: transparent;
}
.hs-wand { min-height: 100%; }
/* Auf dem Hintergrundbild braucht die Beschriftung einen Schatten, sonst
   verschwindet sie über hellen Stellen der Karte. */
.hs-wand .hs-name { text-shadow: 0 1px 3px rgba(0,0,0,.7); color: #fff; }
[data-theme="light"] .hs-wand .hs-name { color: #000; text-shadow: 0 1px 3px rgba(255,255,255,.8); }
.hs-wand .hint { color: rgba(255,255,255,.75); text-shadow: 0 1px 3px rgba(0,0,0,.7); }
[data-theme="light"] .hs-wand .hint { color: rgba(0,0,0,.7); text-shadow: none; }

/* Rastermasse aus Apples „Home Screen - iPhone": 30px Rand seitlich,
   28 oben, 20 zwischen den Spalten. Bei 375px Breite geht die Rechnung
   genau auf: 30 + 4x64 + 3x20 + 30 = 376.
   Der Zeilenabstand bleibt bei 20 statt Apples 36,33 — bei Apple sitzt die
   Beschriftung IM Zeilenabstand, im Portal gehoert sie zur Kachel. */
.hs-raster {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: var(--s5) 20px;
  padding: 28px 30px var(--s6);
  max-width: 560px; margin: 0 auto;
}
.hs-app {
  /* 5px zwischen Kachel und Beschriftung — Apples Wert, vorher 6. */
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  text-decoration: none; color: inherit;
}
.hs-app:active .hs-kachel { transform: scale(.9); }
.hs-kachel {
  /* 64x64 nach Apples „App Icon" (Home Screen - iPhone). Die Foundations
     des Betreibers nennen 60x60 mit Radius 15; das Bauteil sagt 64. Der
     Radius waechst proportional mit — 15/60 = 0,25, also 16 bei 64. Wer
     auf 60 zurueck will, dreht beide Zahlen zusammen. */
  position: relative; width: 64px; height: 64px; border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 8px rgba(0,0,0,.28);
  transition: transform .12s ease;
}
.hs-glyphe { font-size: 30px; line-height: 1; filter: drop-shadow(0 1px 1px rgba(0,0,0,.25)); }
/* Eigenes App-Bild über der Kachel. `cover` und dieselbe Rundung wie die
   Kachel: Die mitgelieferten Symbole bringen ihre eigene Hintergrundfarbe mit
   und sollen die Fläche ganz ausfüllen, nicht darin schweben. Lädt die Datei
   nicht, nimmt das Skript das Bild heraus und der Farbverlauf bleibt sichtbar. */
.hs-bild {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; border-radius: inherit; display: block;
}
.hs-abzeichen {
  position: absolute; top: -5px; right: -5px; min-width: 20px; height: 20px;
  padding: 0 6px; border-radius: 10px; background: var(--red); color: #fff;
  font-size: 12px; font-weight: 700; line-height: 20px; text-align: center;
  border: 2px solid var(--bg);
}
.hs-name {
  font-size: 11px; line-height: 1.2; text-align: center; color: var(--label);
  max-width: 76px; overflow: hidden;
  /* Zwei Zeilen statt Abschneiden: „eBay Kleinanzeigen" wäre einzeilig nur
     noch „eBay Kleina…". Ab der dritten Zeile wird gekürzt, damit die Reihen
     im Raster gleich hoch bleiben. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  word-break: break-word;
}
.hs-klingelt {
  display: block; margin: 0 var(--gutter) var(--s4); padding: var(--s3) var(--s4);
  border-radius: var(--r-card); background: var(--green); color: #fff;
  font-size: 15px; font-weight: 600; text-align: center; text-decoration: none;
}

/* ── Telefon ────────────────────────────────────────────────
   Klingelbild und laufendes Gespräch sehen gleich aus: großer Avatar, Name,
   Zustand, darunter die Knöpfe. Das ist die Anordnung, die jeder vom Telefon
   kennt — und sie braucht keine Erklärung. */
.tel-klingel, .tel-aktiv {
  text-align: center; padding: var(--s5) var(--gutter) var(--s4);
}
.tel-aktiv {
  background: var(--bg-elev); border-radius: var(--r-card);
  margin: 0 var(--gutter) var(--s4);
}
.tel-klingel .avatar.lg, .tel-aktiv .avatar.lg { margin: 0 auto; }
.tel-klingel-name {
  font-size: 24px; font-weight: 700; letter-spacing: -.5px; margin-top: var(--s3);
}
.tel-klingel-unter { font-size: 15px; color: var(--label-2); margin-bottom: var(--s4); }
.tel-knoepfe { display: flex; justify-content: center; gap: var(--s8); padding: var(--s3) 0; }
.tel-rund {
  width: 68px; height: 68px; border-radius: 50%; border: 0;
  font-size: 28px; color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 14px rgba(0,0,0,.3);
  transition: transform .12s ease;
}
.tel-rund:active { transform: scale(.92); }
.tel-rund.an { background: var(--green); }
.tel-rund.ab { background: var(--red); }
.tel-rot { color: var(--red); }

/* Kontakte: zwei runde Schnellaktionen je Zeile. 36 px sind kleiner als die
   44-px-Regel, deshalb hat die Zeile selbst reichlich Höhe und die Knöpfe
   liegen weit auseinander — treffen lässt sich das trotzdem. */
.kt-rund {
  width: 36px; height: 36px; flex: none; margin-left: var(--s2);
  border: 0; border-radius: 50%; background: var(--fill); color: var(--label);
  font-size: 16px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.kt-rund.gruen { background: var(--green); color: #fff; }
.kt-rund:active { opacity: .7; }

/* Nachrichten: runder Avatar statt Anzeigenbild, Anrufzeilen abgesetzt. */
.mn-bild.rund { border-radius: 50%; font-weight: 700; }
.mn-system.anruf { color: var(--green); }

/* ── Fraktion: Flagge und Armband ───────────────────────────
   Die Bilder liegen als JPG auf dem Server (Armbinden_Flaggen) und kommen
   über /api/community/factions/asset/… — also hinter der Anmeldung, wie die
   Anzeigenfotos auch.

   Die beiden haben GEGENSÄTZLICHE Formate, und daran hängt das ganze Layout:

       Flagge    2087 x 1186  → quer  (1,76)
       Armband     298 x  458 → hoch  (0,65)

   Vorher steckten beide in derselben quadratischen Fläche; das Armband
   zusätzlich in einem 34x20-Streifen mit `cover`, von dem am Ende ein
   Ausschnitt in Daumennagelgröße übrig blieb. Jetzt bekommt jedes seine
   eigene Form — beide gleich hoch, damit die Zeile ruhig steht — und `contain`
   sorgt dafür, dass nichts abgeschnitten wird. */
.fr-kopf { text-align: center; padding: var(--s2) var(--gutter) var(--s5); }
.fr-wappen {
  display: flex; gap: var(--s3); justify-content: center; align-items: flex-start;
  flex-wrap: wrap;
}
.fr-stueck {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  margin: 0;
}
.fr-stueck img {
  display: block; object-fit: contain;
  background: var(--fill); border-radius: var(--r-card);
}
/* 16:9 und 2:3 — nah an den echten Formaten, gleiche Höhe (~124 px). */
.fr-stueck.flagge img  { width: 220px; aspect-ratio: 16 / 9; }
.fr-stueck.armband img { width: 82px;  aspect-ratio: 2 / 3; }
.fr-stueck figcaption { font-size: 13px; color: var(--label-2); }

/* Auf schmalen Geräten die Flagge schrumpfen lassen, statt umzubrechen:
   220 + 12 + 82 = 314 px passen in die 343 px eines iPhone SE — darunter
   nicht mehr. */
@media (max-width: 359px) {
  .fr-stueck.flagge img  { width: 168px; }
  .fr-stueck.armband img { width: 63px; }
}

.fr-flagge.klein {
  width: 29px; height: 29px; flex: none; border-radius: 7px;
  margin: 0; object-fit: cover;
}
.fr-name { font-size: 24px; font-weight: 700; letter-spacing: -.5px; margin-top: var(--s4); }

/* ── Symbole in vorhandenen Behältern ───────────────────────
   Diese Klassen haben ihre Emojis frueher ueber `font-size` bemessen. Eine
   Zeichnung hat keine Schriftgroesse — sie bringt ihre Masse selbst mit und
   muss stattdessen ZENTRIERT werden. Genau das steht hier, und nur das:
   Farbe, Abstand und Hintergrund bleiben, wo sie waren. */
.tp-tab-sym, .az-tab-sym, .mk-tab-sym, .mk-lupe, .hm-k-sym,
.ka-haken, .mt-knopf, .cs-gross-zeichen {
  display: flex; align-items: center; justify-content: center;
}
.cs-gross-zeichen { gap: 8px; }        /* Zahl und Zeichnung nebeneinander */
.mk-kein {
  display: flex; align-items: center; justify-content: center;
  opacity: .5; color: var(--label-3);
}
.ka-haken { width: 20px; }

/* Der Kopf eines Killfeed-Blocks traegt jetzt Symbol UND Text. */
.kd-kopf { display: flex; align-items: center; gap: 6px; }

/* Kleine Zeichnungen mitten im Text: der Pfeil zwischen zwei Namen im
   Killfeed und die Richtung eines Anrufs. Gedaempft, damit sie die Namen
   nicht ueberstrahlen. */
.kf-pfeil, .tf-pfeil { color: var(--label-3); }

/* Der Haken in Auswahllisten — dort, wo frueher ein ✓ als Schriftzeichen
   stand. */
.ic-haken { color: var(--blue); display: inline-flex; align-items: center; }

/* Das grosse Herz auf der Match-Karte. */
.mt-herz {
  display: flex; align-items: center; justify-content: center;
  color: var(--pink); padding: var(--s2) 0;
}

/* ── Kategorien: wischbares Band aus Rechtecken ─────────────
   Vorher fünf runde Knöpfe in einem starren 5-Spalten-Raster. Das hatte zwei
   Nachteile, die zusammenhängen: Unter einen 48-px-Kreis passt kaum
   Beschriftung — „Weitere Kategorien" brach auf zwei Zeilen —, und mehr als
   fünf Kategorien waren überhaupt nicht erreichbar.

   Ein Band aus Rechtecken löst beides: Die Beschriftung steht NEBEN dem
   Symbol und hat dadurch Platz auf einer Zeile, und es passen beliebig viele
   hinein. Die angeschnittene nächste Kachel am rechten Rand zeigt, dass es
   weitergeht — deshalb endet das Band mit Abstand statt bündig. */
.mk-katreihe {
  display: flex; gap: var(--s2); overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: 0 var(--gutter) var(--s5);
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.mk-katreihe::-webkit-scrollbar { display: none; }

.mk-kat {
  scroll-snap-align: start; flex: 0 0 auto;
  display: flex; flex-direction: row; align-items: center; gap: 9px;
  /* 44 px hoch: das Mindestmaß, das iOS zum Antippen vorgibt. */
  min-height: 44px; padding: 0 15px 0 7px;
  border: 0; border-radius: 12px;
  background: var(--fill); color: var(--label);
  font: inherit; cursor: pointer;
}
.mk-kat.an {
  background: color-mix(in srgb, #6CB33F 22%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #6CB33F 45%, transparent);
}
.mk-kat-kreis {
  width: 30px; height: 30px; border-radius: 8px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, #6CB33F 30%, transparent);
  color: #6CB33F;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #6CB33F 45%, transparent);
}
/* Eine Zeile, kein Umbruch — dafür ist das Band da. */
.mk-kat-name {
  font-size: 14px; font-weight: 500; letter-spacing: -.15px;
  white-space: nowrap; color: var(--label);
}

/* ══════════════════════════════════════════════════════════
   NORTHSIDE Hot Fruits
   ══════════════════════════════════════════════════════════
   Der große Automat. Was hier steht, gilt NUR für ihn — die gemeinsamen
   Teile (Walzwerk, Konsole, Überlagerung) stehen weiter oben und werden
   nicht angefasst.

   Geschaltet wird über Klassen an der Bühne, die hotfruits.js setzt:
   `hf-lichter`, `hf-puls`, `hf-unscharf`, `hf-dunkel`, `hf-ruhe`,
   `hf-brennt`. Jede davon hängt an einem Schalter in CONFIG.effekte — wer
   einen Effekt abschaltet, bekommt die Klasse nicht, und damit fällt auch
   die Regel weg. Kein Effekt wird an zwei Stellen abgeschaltet. */

/* ── Der Ladebalken ───────────────────────────────────────
   Er steht so lange, wie die Walzenbilder brauchen, und verschwindet dann.
   Fehlen alle Bilder, verschwindet er trotzdem: Der Automat läuft mit den
   Zeichnungen weiter, und ein stehender Balken sähe nach Absturz aus. */
.hf-laden {
  margin: 0 var(--gutter) var(--s2); text-align: center;
  transition: opacity .24s ease;
}
.hf-laden.fertig { opacity: 0; }
.hf-laden-text { font-size: 11.5px; color: var(--label-2); margin-bottom: 4px; }
.hf-laden-schiene {
  height: 4px; border-radius: 2px; overflow: hidden;
  background: rgba(255,255,255,.12);
}
.hf-laden-schiene i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--cs-gold), var(--cs-gold-hell));
  transition: width .18s ease;
}

/* ── Die Kachel ───────────────────────────────────────────
   Jedes Walzenfeld trägt einen Rahmen mit der Symbolklasse (`hf-k-seven`).
   An ihm hängen Glut, Funken und Wackler — ohne ihn müsste die CSS raten,
   welches Symbol gerade liegt. */
.hf-k {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; position: relative;
}
.hf-k .cs-sym, .hf-k .cs-bild { pointer-events: none; }

/* Fehlt Bild UND Zeichnung, steht der Name da. Nie eine leere Fläche, nie
   ein Absturz. */
.cs-fehlbild {
  display: flex; align-items: center; justify-content: center;
  width: 86%; height: 86%; border-radius: 8px;
  background: rgba(0,0,0,.10); color: #3A3A3C;
  font-size: 10px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.18);
}

/* Die Sieben glüht immer ein wenig — sie ist das Symbol, auf das gewartet
   wird, und ein Automat zeigt das, bevor sie trifft. */
.hf-k-seven { filter: drop-shadow(0 0 5px rgba(255,120,20,.55)); }

/* Bei einem Treffer kommt das Hitzeflimmern dazu: eine Schliere, die über
   dem Symbol steht und atmet. Nur `transform` und `opacity` — beides läuft
   im Verdichter und kostet keine Neuberechnung des Seitenaufbaus. */
.hf-glut .hf-k-seven::after {
  content: ""; position: absolute; inset: -10%;
  pointer-events: none; border-radius: 50%;
  background: radial-gradient(circle at 50% 62%, rgba(255,196,80,.55),
                              rgba(255,90,0,.28) 45%, transparent 70%);
  animation: hf-glut 1.05s ease-in-out infinite;
}
@keyframes hf-glut {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); opacity: .5; }
  50%      { transform: translate3d(0, -6%, 0) scale(1.12); opacity: .95; }
}

/* Der Stern beim Landen: ein Funke, der aufblitzt und vergeht. */
.hf-sternfunke {
  position: absolute; left: 50%; top: 50%; width: 70%; height: 70%;
  margin: -35% 0 0 -35%; pointer-events: none; border-radius: 50%;
  background:
    conic-gradient(from 0deg, transparent 0deg 12deg, rgba(255,255,255,.95) 14deg 16deg,
                   transparent 18deg 42deg, rgba(255,229,150,.9) 44deg 46deg,
                   transparent 48deg 90deg);
}

/* ── Nicht gewinnende Symbole treten zurück ───────────────
   Erst dadurch liest sich eine Gewinnlinie: Was zahlt, steht voll da; der
   Rest wird leise. */
.hf-dunkel.cs-gewinn .cs-kachel:not(.cs-treffer) .hf-k,
.hf-dunkel.cs-gewinn .cs-flaeche:not(.cs-treffer) .hf-k {
  filter: brightness(.52) saturate(.7);
  transition: filter .22s ease;
}

/* Bewegungsunschärfe im Lauf — auch für das flache Walzwerk, das sie bisher
   nicht hatte (nur die Trommel). Ein Band ohne Unschärfe sieht aus, als
   sprängen die Symbole. */
.hf-unscharf .cs-walze.cs-rollt .cs-kachel { filter: blur(.7px); }

/* ── Rahmenlichter ────────────────────────────────────────
   Ein Lauflicht um das Walzenfeld, wie an einer Spielhallenfront: im
   Leerlauf gemächlich, während des Drehs schnell. Es liegt als Randstreifen
   auf, nicht als Kette von Lämpchen — dreißig Knoten für einen Effekt, den
   niemand einzeln ansieht, wären dreißig zu viel. */
.hf-lichter .cs-rahmen::before {
  content: ""; position: absolute; inset: -3px; border-radius: 17px;
  pointer-events: none; z-index: 0; padding: 3px; opacity: .55;
  background: repeating-linear-gradient(90deg,
    rgba(255,224,102,.85) 0 7px, rgba(255,224,102,0) 7px 21px);
  -webkit-mask: linear-gradient(#000 0 0) content-box exclude,
                linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  animation: hf-marquee 2.6s linear infinite;
}
.hf-lichter.cs-laeuft .cs-rahmen::before { animation-duration: .55s; opacity: .9; }
@keyframes hf-marquee { to { background-position: 42px 0; } }

/* ── Der Hintergrund atmet ────────────────────────────────
   Sehr dezent. Wer es bemerkt, hat zu lange hingesehen — es soll nur
   verhindern, dass die Fläche tot wirkt. */
.hf-puls::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  border-radius: inherit;
  background: radial-gradient(120% 90% at 50% 10%, rgba(255,190,90,.14), transparent 62%);
  animation: hf-atem 5.5s ease-in-out infinite;
}
@keyframes hf-atem { 50% { opacity: .35; } }

/* ── Ruhemodus ────────────────────────────────────────────
   Nach 30 s ohne Eingabe blinkt der Startknopf, und ein zufälliges Symbol
   dreht sich einmal (hotfruits.js). Mehr passiert nicht — ein Gerät, das von
   allein Töne macht, ist eine Zumutung. */
.hf-ruhe ~ .cs-konsole .cs-taste.start { animation: hf-locken 1.5s ease-in-out infinite; }
@keyframes hf-locken {
  50% { box-shadow: 0 3px 0 #8A5F0B, inset 0 1px 0 rgba(255,255,255,.4),
                    0 0 26px rgba(255,213,74,.85); transform: translateY(-1px); }
}

/* ── Fünf Siebenen ────────────────────────────────────────
   Der seltenste Fall dieses Automaten. Er darf den ganzen Bildschirm haben. */
.hf-brennt { animation: hf-brand 1.6s ease-out; }
@keyframes hf-brand {
  0%   { box-shadow: inset 0 0 0 1px rgba(233,185,73,.22), 0 8px 24px rgba(0,0,0,.28); }
  25%  { box-shadow: inset 0 0 60px rgba(255,120,20,.75), 0 8px 34px rgba(255,90,0,.5); }
  100% { box-shadow: inset 0 0 0 1px rgba(233,185,73,.22), 0 8px 24px rgba(0,0,0,.28); }
}

/* ── Die Partikel-Leinwand ────────────────────────────────
   Münzregen und Feuer laufen hier, nicht als DOM-Elemente: neunzig Münzen
   wären neunzig Knoten, die der Browser bei jedem Bild neu einsortiert. */
canvas.hf-partikel {
  position: absolute; inset: 0; z-index: 6;
  pointer-events: none; width: 100%; height: 100%;
}

/* Der Strahlenkranz beim Mega Win — über den Walzen, hinter dem Betrag.

   Die Mitte bleibt AUSGESPART. Ohne die Maske legen sich die Strahlen über
   den Betrag, und ausgerechnet die Zahl, für die der ganze Auftritt gebaut
   ist, wird unlesbar — beim ersten Versuch stand „Mega Win" hinter einem
   goldenen Schleier. */
.hf-strahlen {
  position: absolute; left: 50%; top: 50%;
  width: 190%; aspect-ratio: 1; margin: -95% 0 0 -95%;
  pointer-events: none; opacity: .12;
  background: repeating-conic-gradient(from 0deg, var(--cs-gold-hell) 0deg 6deg,
                                       transparent 6deg 16deg);
  -webkit-mask: radial-gradient(circle, transparent 0 20%, #000 40%);
  mask: radial-gradient(circle, transparent 0 20%, #000 40%);
  animation: dreh 11s linear infinite;
}

/* Der Startknopf im Stopp-Zustand. Er trägt bewusst NICHT `cs-aktion`: Die
   wird beim Drehen gesperrt, und genau dann muss man anhalten können. */
.cs-taste.start.stopp {
  background: linear-gradient(#FF8A80, #C62828); color: #fff;
  box-shadow: 0 3px 0 #7F1D1D, inset 0 1px 0 rgba(255,255,255,.35);
  animation: none;
}
.cs-taste.ton.an, .cs-taste.haptik.an {
  background: linear-gradient(#5EE0A0, #21A468); color: #06301D;
  box-shadow: 0 3px 0 #0E5C39, inset 0 1px 0 rgba(255,255,255,.4);
}

/* ── Dunkle Walzen ────────────────────────────────────────
   Der gelieferte Symbolsatz ist für einen DUNKLEN Grund gemalt: Jedes Symbol
   trägt eine cremefarbene Leuchtkontur, und die leuchtet nur gegen Dunkles.
   Auf dem hellen Stein der übrigen Spiele verschwindet sie spurlos — übrig
   bleibt der schwarze Ring darunter. Lesbar, aber die halbe Zeichnung.

   Deshalb bekommt **nur dieser Automat** dunkle Walzen. Die sieben anderen
   Spiele behalten ihren hellen Stein; sie laufen mit Vektorsymbolen, die
   dafür gezeichnet sind. Wer die Bilder austauscht und einen hellen Satz
   liefert, streicht diesen Block — mehr hängt nicht daran. */
.hf .cs-walze {
  background: linear-gradient(#101028, #07071A 50%, #101028);
  box-shadow: inset 0 8px 10px -8px #000, inset 0 -8px 10px -8px #000,
              inset 0 0 0 1px rgba(255,255,255,.08);
}
.hf .cs-kachel, .hf .cs-flaeche {
  background: linear-gradient(#16163A, #0B0B22 52%, #16163A);
}
.hf .cs-kachel { border-bottom: 1px solid rgba(255,255,255,.07); }
.hf .cs-flaeche { box-shadow: inset 0 0 0 1px rgba(255,255,255,.07); }
/* Der Lichtbogen der Trommel muss auf dunklem Grund kräftiger sein, sonst
   sieht der Zylinder wieder flach aus. */
.hf .cs-maschine.raum .cs-walze::before {
  background:
    linear-gradient(rgba(0,0,0,.62), rgba(0,0,0,.10) 26%, rgba(255,255,255,.10) 50%,
                    rgba(0,0,0,.10) 74%, rgba(0,0,0,.62));
}
/* Ein Treffer leuchtet von INNEN. Die helle Fassung der übrigen Spiele würde
   hier die Zeichnung überstrahlen — genau die, für die gezahlt wurde. */
.hf .cs-kachel.cs-treffer, .hf .cs-flaeche.cs-treffer {
  background:
    radial-gradient(circle at 50% 50%, rgba(255,213,74,.38), rgba(255,213,74,.05) 72%),
    linear-gradient(#242455, #14142E 52%, #242455);
  box-shadow: inset 0 0 0 2px var(--cs-gold);
}

/* ── Bewegung reduzieren ──────────────────────────────────
   Alles, was wandert, blinkt oder flimmert, hört auf. Was bleibt, ist das
   Ergebnis: Gewinnlinien, Betrag, Farbe. */
@media (prefers-reduced-motion: reduce) {
  .hf-lichter .cs-rahmen::before,
  .hf-puls::before,
  .hf-glut .hf-k-seven::after,
  .hf-ruhe ~ .cs-konsole .cs-taste.start,
  .hf-brennt,
  .hf-strahlen { animation: none; }
  .hf-unscharf .cs-walze.cs-rollt .cs-kachel { filter: none; }
  canvas.hf-partikel { display: none; }
}

/* ══════════════════════════════════════════════════════════════
   Diplomatie (Phase 39) — Lagebesprechungs-Ästhetik: dunkle Karten,
   Statusfarben aus der Vorgabe (Krieg #c0392b usw., kommen als
   Inline-Styles vom Server — EINE Farbwahrheit für Web und Discord).
   Lesbarkeit schlägt Deko: Alles liegt auf den normalen Portal-Flächen.
   ══════════════════════════════════════════════════════════════ */
:root { --diplo: #6d7a58; }

/* Kopf: die Lage der eigenen Fraktion */
.dp-lage {
  border-radius: var(--r-card); padding: var(--s4);
  background: linear-gradient(160deg, #262b22, #14160f);
  color: #fff; margin-bottom: var(--s3);
  border: 1px solid rgba(255,255,255,.08);
}
.dp-lage-kopf { display: flex; align-items: center; gap: var(--s3); }
.dp-wappen {
  width: 40px; height: 40px; border-radius: 10px; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 15px; color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,.5);
}
.dp-lage-name { font-weight: 700; font-size: 19px; }
.dp-lage-sub { color: rgba(255,255,255,.65); font-size: 13px; margin-top: 2px; }
.dp-chips { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s3); }
.dp-chip {
  border-radius: var(--r-pill); padding: 5px 11px; font-size: 13px;
  font-weight: 600; background: rgba(255,255,255,.10); color: #fff;
  border: 1px solid rgba(255,255,255,.12);
}
.dp-chip b { font-variant-numeric: tabular-nums; }
.dp-antrag-btn {
  margin-top: var(--s3); width: 100%; min-height: 48px;
  border: 0; border-radius: var(--r-ctl); cursor: pointer;
  font: inherit; font-weight: 700; font-size: 16px;
  background: var(--diplo); color: #fff;
}
.dp-antrag-btn:disabled { opacity: .55; cursor: default; }

/* Statusabzeichen — Farbe kommt inline vom Server */
.dp-badge {
  display: inline-block; border-radius: var(--r-pill);
  padding: 3px 10px; font-size: 12px; font-weight: 700; color: #fff;
  letter-spacing: .01em; white-space: nowrap;
}
.dp-punkt {
  display: inline-block; width: 10px; height: 10px; border-radius: 50%;
  margin-right: 6px; vertical-align: baseline;
}

/* Abstimmungs-Karte */
.dp-karte {
  background: var(--bg-elev); border-radius: var(--r-card);
  padding: var(--s4); margin-bottom: var(--s3); box-shadow: var(--shadow);
}
.dp-k-kopf { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.dp-k-typ {
  border-radius: var(--r-pill); padding: 3px 10px; color: #fff;
  font-size: 12px; font-weight: 700;
}
.dp-k-kammer {
  border-radius: var(--r-pill); padding: 3px 10px; font-size: 12px;
  font-weight: 600; background: var(--fill); color: var(--label-2);
}
.dp-uhr {
  margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums;
  font-size: 14px; color: var(--label-2);
}
.dp-uhr.rot { color: var(--red); }
.dp-k-titel { font-weight: 700; font-size: 16px; margin-top: var(--s2); }
.dp-k-grund { margin: var(--s2) 0 0; }
.dp-k-grund summary {
  cursor: pointer; color: var(--label-2); font-size: 14px;
  list-style: none; -webkit-user-select: none; user-select: none;
}
.dp-k-grund summary::-webkit-details-marker { display: none; }
.dp-k-grund[open] summary .dp-mehr { display: none; }
.dp-k-grund p {
  margin: var(--s2) 0 0; font-size: 14px; color: var(--label);
  background: var(--fill); border-radius: var(--r-box); padding: var(--s3);
}

/* Beteiligungsbalken mit Quorum-Marke — bewusst KEIN Ja/Nein-Verhältnis */
.dp-balken-kasten { margin-top: var(--s3); }
.dp-balken {
  position: relative; height: 8px; border-radius: 4px;
  background: var(--fill); overflow: visible;
}
.dp-balken > span {
  display: block; height: 100%; border-radius: 4px;
  background: var(--diplo); transition: width .3s;
}
.dp-quorum-marke {
  position: absolute; top: -3px; bottom: -3px; width: 2px;
  background: var(--label-2); border-radius: 1px;
}
.dp-balken-txt {
  display: flex; justify-content: space-between;
  font-size: 12px; color: var(--label-2); margin-top: 5px;
}

/* Die drei Stimm-Buttons — identisch zur Discord-DM */
.dp-stimmen { display: flex; gap: var(--s2); margin-top: var(--s3); }
.dp-stimme {
  flex: 1; min-height: 46px; border-radius: var(--r-ctl); cursor: pointer;
  border: 1.5px solid var(--separator); background: transparent;
  font: inherit; font-size: 14px; font-weight: 700; color: var(--label);
}
.dp-stimme.ja.gewaehlt   { background: var(--green); border-color: var(--green); color: #fff; }
.dp-stimme.nein.gewaehlt { background: var(--red); border-color: var(--red); color: #fff; }
.dp-stimme.enth.gewaehlt { background: var(--grau); border-color: var(--grau); color: #fff; }
.dp-stimme:disabled { opacity: .5; cursor: default; }
.dp-hinweis { font-size: 13px; color: var(--label-2); margin-top: var(--s2); }
.dp-zurueck {
  margin-top: var(--s2); background: none; border: 0; cursor: pointer;
  font: inherit; font-size: 13px; color: var(--red); padding: 4px 0;
}

/* Beziehungsmatrix (eigener Bildschirm, horizontal scrollbar) */
.dp-matrix-scroll {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  background: var(--bg-elev); border-radius: var(--r-card); padding: var(--s3);
}
.dp-matrix { border-collapse: separate; border-spacing: 3px; }
.dp-matrix th {
  font-size: 11px; font-weight: 600; color: var(--label-2);
  padding: 4px 6px; text-align: left; max-width: 92px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dp-matrix th.dp-spalte {
  writing-mode: vertical-rl; transform: rotate(180deg);
  text-align: left; max-width: none; max-height: 92px; padding: 6px 4px;
}
.dp-zelle {
  width: 34px; height: 34px; border-radius: 7px; border: 0;
  cursor: pointer; padding: 0;
}
.dp-zelle.leer { background: var(--fill); cursor: default; }
.dp-zelle:not(.leer) { box-shadow: inset 0 0 0 1px rgba(0,0,0,.15); }
.dp-matrix tr.selbst th { color: var(--label); font-weight: 800; }
.dp-legende { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s3); }

/* Chronik als Zeitstrahl */
.dp-zeit { position: relative; padding-left: 22px; }
.dp-zeit::before {
  content: ""; position: absolute; left: 7px; top: 6px; bottom: 6px;
  width: 2px; background: var(--separator); border-radius: 1px;
}
.dp-zeit-eintrag { position: relative; padding: 0 0 var(--s4); }
.dp-zeit-eintrag::before {
  content: ""; position: absolute; left: -20px; top: 5px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--diplo); border: 2px solid var(--bg);
}
.dp-zeit-wann { font-size: 12px; color: var(--label-2); }
.dp-zeit-text { font-size: 15px; margin-top: 2px; }
.dp-zeit-zahlen { font-size: 13px; color: var(--label-2); margin-top: 4px; }

/* Warnbox des Antrags-Assistenten (Kriegserklärung / Paktbruch) */
.dp-warnung {
  background: rgba(192,57,43,.14); border: 1px solid #c0392b;
  color: var(--label); border-radius: var(--r-box);
  padding: var(--s3); font-size: 14px; margin-top: var(--s3);
}
.dp-wiz-typ { opacity: 1; }
.dp-wiz-typ.aus { opacity: .5; }
.dp-wiz-typ .row-sub { white-space: normal; }
