/* ============================================================
   Typical Web – Bausteine (Visuell 1:1 an die iOS-App angeglichen)
   ============================================================
   Die Farben, Maße und Schriftstufen stehen in `tokens.css` und
   nirgends sonst. Hier steht nur, wie daraus Bildschirme werden.
   ============================================================ */

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/*
   **Der Grund steht am `html`, nicht am `body`** – und mit einer Farbe
   dahinter. Ein Verlauf allein am `body` malt nur so weit, wie der Inhalt
   reicht; was darüber hinausgeht bekäme das Weiß der Zeichenfläche.
*/
html {
    min-height: 100%;
    /* Theme.grundVerlauf – Pflaume oben, Petrol unten */
    background: var(--grund-1)
        linear-gradient(to bottom,
            var(--grund-1), var(--grund-2), var(--grund-3), var(--grund-4)) fixed;
    color: var(--ink);
}

/*
   **Der Inhalt steht in der Mitte des Fensters, nicht oben dran.** Bei einer
   Handybreite füllt der Inhalt fast immer die Höhe – hier fiel das nie auf.
   Im Browser kann das Fenster beliebig hoch sein, und ein kurzer Bildschirm
   (Start, Einladung) klebte oben, während darunter nur der Verlauf stand.
   `justify-content: center` zentriert nur, solange Inhalt hineinpasst; ist er
   höher als das Fenster, wächst `body` darüber hinaus und alles läuft wie
   gewohnt von oben nach unten – Formulare mit Tastatur oder eine lange Liste
   verlieren dadurch keine Zeile.
*/
body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font: var(--font-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-text-size-adjust: 100%;
    position: relative;
    overflow-x: hidden;
}

/*
   **Solange eine Runde offen ist, steht der Inhalt oben – nicht in der Mitte.**
   Reiterleiste und Zahnrad müssen auf jedem Reiter an derselben Stelle stehen
   (Wunsch des Nutzers, 05.09.2026). Zentriert rutschten sie mit jedem Wechsel,
   weil Übersicht, Karte, Spielerliste und Chat verschieden hoch sind – und die
   Karte selbst beim Falten noch einmal. `ansicht.js` setzt `runde-offen` an
   `<html>`, solange die Reiterleiste gezeichnet wird; Start, Beitreten und
   Aufbau bleiben zentriert.
*/
html.runde-offen body { justify-content: flex-start; }

/* ── Atmosphärischer Neon-Hintergrund (NeonBackground aus Swift) ── */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: -2;
    background:
        radial-gradient(circle 210px at calc(50% - 110px) 15%, rgba(255, 62, 126, 0.30), transparent 70%),
        radial-gradient(circle 190px at calc(50% + 130px) 48%, rgba(150, 111, 255, 0.20), transparent 70%),
        radial-gradient(circle 160px at calc(50% - 75px) 82%, rgba(53, 221, 211, 0.14), transparent 70%);
}

.hell body::before {
    background:
        radial-gradient(circle 210px at calc(50% - 110px) 15%, rgba(255, 62, 126, 0.16), transparent 70%),
        radial-gradient(circle 190px at calc(50% + 130px) 48%, rgba(111, 69, 221, 0.12), transparent 70%),
        radial-gradient(circle 160px at calc(50% - 75px) 82%, rgba(0, 150, 142, 0.10), transparent 70%);
}

/* Vignette nach unten hin abdunkeln */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: -1;
    background: linear-gradient(to bottom, transparent 40%, rgba(11, 10, 19, 0.85) 100%);
}

.hell body::after {
    background: linear-gradient(to bottom, transparent 40%, rgba(242, 241, 248, 0.85) 100%);
}

/*
   **Der Start-Reiter bringt sein eigenes Licht mit** (Theme.startVerlauf,
   NeonBackground.eigenesLicht) – Entwurf 21a/21b. `haupt.js` setzt die Klasse
   `start-reiter` an `<html>`, solange `startSeite()` zu sehen ist (auch
   während der Modus-Wahl, nicht mehr beim Beitreten oder Anlegen).

   Im Dunkeln ist das derselbe Verlauf wie überall (`grund-1..4`), deshalb
   steht hier nur die helle Fassung. Die drei Farbschleier und die Vignette
   entfallen in beiden Designs: Der Auftritt aus schwebenden Feldern
   (`.start-auftritt`) bringt seinen eigenen violetten Schein mit, und die
   Pillen tragen ihre Farbe selbst.
*/
html.start-reiter {
    background: var(--grund-1)
        linear-gradient(to bottom,
            var(--grund-1), var(--grund-2), var(--grund-3), var(--grund-4)) fixed;
}

html.hell.start-reiter {
    background: var(--start-hell-1)
        linear-gradient(to bottom,
            var(--start-hell-1), var(--start-hell-2), var(--start-hell-3), var(--start-hell-4)) fixed;
}

html.start-reiter body::before,
html.start-reiter body::after {
    content: none;
}

/* Der Rahmen, in dem alles steht */
.rahmen {
    width: 100%;
    max-width: 440px;
    margin: 0 auto;
    padding: var(--space-screen);
    padding-top: max(var(--space-medium), env(safe-area-inset-top));
    padding-bottom: max(var(--space-section), env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    gap: var(--space-large);
    position: relative;
    z-index: 1;
    box-sizing: border-box;
}

/* ── Kopfleiste / Toolbar ─────────────────────────────────── */

.kopfleiste {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-small);
    min-height: 36px;
    width: 100%;
}

.kopfleiste.mit-zurueck {
    justify-content: space-between;
}

.kopf-rechts {
    display: flex;
    align-items: center;
    gap: var(--space-small);
}

.kopf-icon-knopf {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: rgba(var(--veil-basis), 0.06);
    border: 1px solid var(--kante-fein);
    color: var(--ink-soft);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.kopf-icon-knopf:hover, .kopf-icon-knopf:focus-visible {
    color: var(--ink);
    border-color: var(--kante-stark);
    background: rgba(var(--veil-basis), 0.12);
}

.kopf-icon-knopf:active {
    transform: scale(0.92);
}

.kopf-zurueck {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: none;
    color: var(--cyan);
    font: var(--font-label);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    padding: 6px 0;
}

.kopf-zurueck:active { opacity: 0.7; }

/* ── Der Auftritt und der Schriftzug (StartHeld + TypicalSchriftzug) ──
   Entwurf 21a/21b. Ersetzt die alte Chat-Blase (`NeonWordmark`) auf dem
   Start-Reiter – die bleibt, wo sie noch gebraucht wird: als Signatur unter
   dem Rückblick. Hier steht seit dem 31.08.2026 der Auftritt aus schwebenden
   Feldern über dem freistehenden Wort, 1:1 aus `StartHeld.swift` und
   `TypicalSchriftzug.swift`. */

.hero-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding-top: var(--space-small);
    padding-bottom: var(--space-tight);
    width: 100%;
    position: relative;
}

/* Die Salve beim Osterei (`kugelSalve` in `ansicht.js`) – Blitz, Ring und
   aufsteigende Kugeln, die sich beim Ende ihrer eigenen Animation selbst aus
   dem DOM entfernen. Bewusst außerhalb von `.start-felder`: die trägt die
   Ausblend-Maske fürs Schweben, und die Salve soll unter den Feldern
   durchziehen, statt mit ihnen ausgeblendet zu werden.

   **`z-index: 0` – hinter Auftritt und Wort.** Die Kugeln steigen zwischen den
   Feldern hindurch, so wie die ruhenden Punkte dort auch hinter ihnen liegen;
   auf iOS besorgt das ein `zIndex(-1)` am Kopf. Die beiden Geschwister
   darüber tragen dafür ihr eigenes `z-index: 1`. */
.osterei-blitz, .osterei-ring, .osterei-kugel {
    position: absolute;
    pointer-events: none;
    z-index: 0;
}

.osterei-blitz {
    border-radius: 50%;
    background: radial-gradient(circle,
        #fff 0%,
        color-mix(in srgb, var(--blitz-farbe) 70%, transparent) 50%,
        transparent 72%);
}

/* Der Ring wächst über `width`/`height`, nicht über `transform: scale()`:
   Ein skalierter Rand würde mit dem Ring dicker, gewollt ist das Gegenteil –
   eine Stoßwelle wird dünner, je weiter sie kommt. */
.osterei-ring {
    border-radius: 50%;
    border-style: solid;
    border-width: 3px;
    transform: translate(-50%, -50%);
    box-sizing: border-box;
}

/* Eine Kugel ist dieselbe Gestalt wie die ruhenden Punkte im Auftritt: ein
   voller Kern in einer der vier Farben, eine Glut darum. Beides in einem
   Verlauf statt Kern plus `box-shadow` – ein Anstrich weniger je Bild. */
.osterei-kugel {
    border-radius: 50%;
    background: radial-gradient(circle,
        var(--kugel-farbe) 0%,
        var(--kugel-farbe) var(--kugel-kern, 18%),
        color-mix(in srgb, var(--kugel-farbe) 55%, transparent) calc(var(--kugel-kern, 18%) + 2%),
        transparent 70%);
}

/* Der Auftritt: fünf schwebende Felder und fünf Punkte, 402 px Entwurfsbreite.
   Die Lage rechnet sich anteilig zur tatsächlichen Breite um (`calc(x/402*100%)`,
   siehe `startAuftritt()` in `ansicht.js`); die Höhe bleibt fest, wie im Entwurf. */
.start-auftritt {
    position: relative;
    width: 100%;
    height: 222px;
    pointer-events: none;
    /* Über der Salve – siehe `.osterei-blitz` oben. */
    z-index: 1;
}

.start-schein {
    position: absolute;
    width: 440px;
    height: 320px;
    left: calc(201 / 402 * 100%);
    top: 144px;
    transform: translate(-50%, -50%);
    background: radial-gradient(circle, color-mix(in srgb, var(--violet) 15%, transparent) 0%, transparent 70%);
}

/* Der Rahmen, der die Maske trägt – **größer als die sichtbaren 222 px**,
   sonst schneidet die Maske selbst hart ab: Ein `mask-image` klippt immer an
   der eigenen Box, unabhängig von `overflow`. Mehrere Felder reichen schon in
   Ruhelage leicht über 0 bzw. 222 hinaus (das große Haken-Feld etwa beginnt
   bei y ≈ −8), und der Wurf wirft zusätzlich bis zu 26 px nach oben aus –
   ohne das Polster stünde dort eine sichtbare Kante statt eines Randes.
   `startAuftritt()` in `ansicht.js` addiert denselben Polsterwert (60 px) auf
   jede `top`-Position, damit die Lage der Felder dadurch unverändert bleibt.
   Nach unten blendet die Maske vollständig auf null aus, statt bei rund
   42 % Deckkraft hart zu enden. */
.start-felder {
    position: absolute;
    left: 0;
    right: 0;
    top: -60px;
    height: 302px;
    -webkit-mask-image: linear-gradient(to bottom, black 0%, black 64.7%, transparent 113.9%);
    mask-image: linear-gradient(to bottom, black 0%, black 64.7%, transparent 113.9%);
    transform-origin: 50% 100%;
    will-change: transform;
}

/* **Der Sog: jede Form hat ihren eigenen Vektor.** Die Schleife
   (`schreibeHalteschicht` in `ansicht.js`) setzt nur `--sog` und `--wf` am
   Rahmen darüber; die zehn Formen rechnen daraus ihre eigene Verschiebung.
   Zehn Formen einzeln je Bild zu beschreiben wären zehnmal so viele
   Stilrechnungen für dasselbe Bild.

   Zehn Formen, die alle mit demselben Faktor zur Mitte rücken, sähen aus wie
   ein Bild, das kleiner wird. Zehn mit eigenem Vektor sehen aus wie zehn
   Dinge, die von derselben Sache angezogen werden. */
.start-feld, .start-punkt {
    position: absolute;
    transform:
        translate(-50%, -50%)
        translate(calc((var(--sx, 0) * var(--sog, 0) + var(--tx, 0) * var(--wf, 0)) * 1px),
                  calc((var(--sy, 0) * var(--sog, 0) + var(--ty, 0) * var(--wf, 0)) * 1px))
        rotate(calc((var(--drehung, 0) + var(--tr, 0) * var(--wf, 0)) * 1deg));
}

/* Der Griff hält die Formen an: Was gepackt ist, treibt nicht mehr. */
.start-feld-schweben, .start-punkt-schweben {
    width: 100%;
    height: 100%;
    animation: start-schweben var(--dauer, 5s) ease-in-out var(--verzug, 0s) infinite alternate;
    animation-play-state: var(--lauf, running);
}

@keyframes start-schweben {
    from { transform: translateY(0); }
    to   { transform: translateY(-9px); }
}

.start-feld-wurf, .start-punkt-wurf {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.start-feld-wurf.spielt, .start-punkt-wurf.spielt {
    animation: start-wurf 0.8s ease-out;
}

@keyframes start-wurf {
    0%    { transform: translateY(0) rotate(0deg) scale(1); }
    30%   { transform: translateY(-26px) rotate(180deg) scale(1.12); }
    62.5% { transform: translateY(4px) rotate(345deg) scale(1.05); }
    100%  { transform: translateY(0) rotate(360deg) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .start-feld-schweben, .start-punkt-schweben { animation: none; }
    .start-feld-wurf.spielt, .start-punkt-wurf.spielt { animation: none; }
}

/* Die fünf Felder – ein geschriebener Satz, der eingetretene, ein
   Kartenausschnitt, ein zweiter Treffer, ein noch leeres Feld. */
.feld-zeilen {
    border-radius: 18px;
    background: color-mix(in srgb, var(--violet) 4%, transparent);
    border: 1px solid color-mix(in srgb, var(--violet) 26%, transparent);
    flex-direction: column;
    gap: 7px;
}

.start-balken {
    border-radius: 999px;
    background: color-mix(in srgb, var(--violet) 32%, transparent);
    width: 48px;
    height: 5px;
}

.start-balken.kurz {
    background: color-mix(in srgb, var(--violet) 20%, transparent);
    width: 32px;
}

.feld-haken-gross {
    border-radius: 20px;
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--pink) 52%, transparent),
        color-mix(in srgb, var(--violet) 36%, transparent));
    border: 1px solid color-mix(in srgb, var(--pink) 55%, transparent);
    box-shadow: 0 0 19px color-mix(in srgb, var(--pink) 45%, transparent),
                inset 0 1px 0 rgba(255, 255, 255, 0.18);
    color: #fff;
}

.feld-haken-gross svg { width: 40px; height: 40px; stroke-width: 3; }

.feld-raster {
    border-radius: 18px;
    background: color-mix(in srgb, var(--cyan) 6%, transparent);
    border: 1px solid color-mix(in srgb, var(--cyan) 45%, transparent);
    box-shadow: 0 0 10px color-mix(in srgb, var(--cyan) 20%, transparent);
}

.start-raster {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 7px;
    width: 74px;
    height: 74px;
}

.start-stein {
    border-radius: 7px;
}

.start-stein.voll { background: color-mix(in srgb, var(--cyan) 30%, transparent); }
.start-stein.leer { border: 1px solid color-mix(in srgb, var(--cyan) 35%, transparent); }

.feld-haken-klein {
    border-radius: 17px;
    background: color-mix(in srgb, var(--amber) 7%, transparent);
    border: 1px solid color-mix(in srgb, var(--amber) 50%, transparent);
    box-shadow: 0 0 8px color-mix(in srgb, var(--amber) 22%, transparent);
    color: var(--amber);
    opacity: 0.92;
}

.feld-haken-klein svg { width: 26px; height: 26px; stroke-width: 3; }

.feld-schemen {
    border-radius: 16px;
    border: 1px solid color-mix(in srgb, var(--violet) 18%, transparent);
    opacity: 0.6;
    filter: blur(1px);
}

/* Die fünf Punkte. */
.start-punkt-koerper { width: 100%; height: 100%; border-radius: 50%; }
.punkt-pink { background: var(--pink); box-shadow: 0 0 6px color-mix(in srgb, var(--pink) 60%, transparent); }
.punkt-cyan { background: var(--cyan); box-shadow: 0 0 7px color-mix(in srgb, var(--cyan) 60%, transparent); }
.punkt-violet { background: var(--violet); box-shadow: 0 0 5px color-mix(in srgb, var(--violet) 60%, transparent); opacity: 0.85; }
.punkt-amber { background: var(--amber); box-shadow: 0 0 5px color-mix(in srgb, var(--amber) 60%, transparent); opacity: 0.85; }
.punkt-pink-fern { background: var(--pink); opacity: 0.5; filter: blur(0.5px); }

/* Der Schriftzug: **das Wort als Aufkleber**, aufrecht, in Textfarbe, mit
   zwei harten Schatten in Rosa und Violett dahinter – gestapelte
   `text-shadow`, dieselbe Technik, die `TypicalSchriftzug.swift` mit drei
   `Text`-Kopien nachbaut, weil SwiftUI keine gestapelten Textschatten kennt.
   In CSS reicht eine Regel.

   **Ein `<h1>`, kein `<div>`.** Auf iOS trägt der Schriftzug `.isHeader`;
   hier übernimmt das die native Überschrift, ohne eigenes ARIA. Das Osterei
   bekommt bewusst keine Tastaturbedienung – dieselbe Ausnahme wie auf iOS
   (`.accessibilityAction` fehlt dort ebenso), weil die Geste rein beiläufig
   gemeint ist. */
/* **Die Glut** – eine weiche rosa Aura, die nur im Rausch zu sehen ist und mit
   ihm wächst (`--rausch`, gesetzt von `ostereiTippen`). Auf iOS ist das eine
   weichgezeichnete Kopie des Worts hinter allem; ein `text-shadow` ohne Versatz
   malt dasselbe, ohne eine fünfte Kopie in den Baum zu hängen. */
@property --rausch {
    syntax: "<number>";
    inherits: false;
    initial-value: 0;
}

.schriftzug {
    font-family: var(--slab);
    font-weight: 800;
    font-size: 76px;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--ink);
    text-align: center;
    margin: 4px 0 0;
    padding: 6px 10px 30px;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
    touch-action: manipulation;
    cursor: pointer;
    /* Über der Salve, wie der Auftritt – siehe `.osterei-blitz`. */
    position: relative;
    z-index: 1;
    will-change: transform;
    --rausch: 0;
    transition: --rausch 0.35s ease-out;
    --schriftzug-nah: color-mix(in srgb, var(--pink) 88%, black);
    --schriftzug-fern: color-mix(in srgb, var(--violet) 55%, transparent);
    --schriftzug-tiefe: rgba(0, 0, 0, 0.5);
    --schriftzug-glut: color-mix(in srgb, var(--pink) calc(var(--rausch) * 60%), transparent);
    /* **Der Versatz der beiden Schatten bleibt fest, auch im Rausch**
       (Rückmeldung des Nutzers, 02.09.2026): Auf iOS fuhren sie zwischenzeitlich
       auseinander, und das Wort zerfiel dabei sichtbar in seine Farbauszüge.
       Der Schriftzug ist eine Gestalt aus dem Entwurf, kein Effekt. */
    text-shadow:
        3px 3px 0 var(--schriftzug-nah),
        6px 6px 0 var(--schriftzug-fern),
        0 10px 17px var(--schriftzug-tiefe),
        0 0 26px var(--schriftzug-glut),
        0 0 26px var(--schriftzug-glut);
}

/* ── Das Halten auf dem Schriftzug ────────────────────────────────────
   Entwurf `Startseite Halten.dc.html` (06.09.2026). **Es gibt hier keine
   Keyframes mehr.** Sechs Stufen als CSS-Animationen wären sechs harte
   Wechsel; gewollt ist Trägheit, und die kommt aus einer Feder, die
   `halten.js` je Bild rechnet. Was hier steht, ist nur die Bühne: die vier
   Ebenen, die die Schleife beschreibt.

   **Der Grund geht unter, während das Licht steigt** – die eine Regel aus
   `docs/DESIGN.md`: „Neon lebt vom dunklen Grund, nicht von mehr Farbe." Ein
   Schein, der auf den Verlauf addiert, hebt die Schwärzen und macht aus dem
   Pflaumengrund Pastell; deshalb liegt er in `mix-blend-mode: screen` – er
   kann nur Licht hinzufügen, wo Licht ist – und die Vignette zieht
   gleichzeitig deutlich an. */
.halte-bloom, .halte-vignette {
    position: fixed;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    z-index: -1;
}

/* **Auf dem Bildschirm ausgemessen, nicht 20 % darüber hinaus.** Der Entwurf
   spannt den Bloom über einen Kasten von 140 % (`inset: -20%`) und legt die
   Ellipse mit `34% 22% at 50% 45%` hinein. Ein Kasten, der über den Bildschirm
   hinausragt, macht die Seite waagerecht scrollbar – dieselbe Ellipse in
   Bildschirmmaßen ist `47,6% 30,8% at 50% 43%` und deckungsgleich, auch unter
   dem `scale()` der Schleife. */
.halte-bloom {
    mix-blend-mode: screen;
}

.halte-bloom.a {
    background: radial-gradient(ellipse 47.6% 30.8% at 50% 43%,
        rgba(255, 62, 126, 0.9) 0%,
        rgba(150, 111, 255, 0.34) 46%,
        rgba(150, 111, 255, 0) 72%);
}

.halte-bloom.b {
    background: radial-gradient(ellipse 47.6% 30.8% at 50% 43%,
        rgba(53, 221, 211, 0.85) 0%,
        rgba(255, 180, 77, 0.36) 48%,
        rgba(255, 180, 77, 0) 74%);
}

.halte-vignette {
    background: radial-gradient(ellipse 76% 52% at 50% 44%,
        rgba(3, 2, 8, 0) 18%,
        rgba(3, 2, 8, 0.86) 72%,
        rgba(3, 2, 8, 1) 100%);
}

/* Der Bruch und der Blitz liegen über allem – auch über der Reiterleiste:
   Es zerfällt der Bildschirm, nicht ein Ausschnitt davon. */
.halte-bruch {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 90;
}

.halte-blitz {
    position: fixed;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    background: #fff;
    z-index: 91;
}

/* **Solange das Halten läuft, rollt die Seite nicht.** Die Kamera skaliert den
   Inhalt; ein skalierter Rahmen ist höher und breiter als das Fenster, und der
   Browser blendet dafür eine Bildlaufleiste ein – ein Balken am Rand, mitten in
   einer Animation, die den ganzen Bildschirm meint. `clip` schneidet ab, ohne
   einen Rollbereich anzulegen; `ansicht.js` setzt die Klasse nur, solange die
   Schleife läuft. */
html.halte-laeuft {
    overflow: clip;
}

/* Die Kamera drückt sich unter Ladung in den Bildschirm hinein. */
#rahmen {
    transform-origin: 50% 45%;
}

.start-pillen {
    transform-origin: 50% 0%;
}

@media (prefers-reduced-motion: reduce) {
    .start-felder {
        transform: none !important;
        filter: none !important;
    }
    .halte-bloom, .halte-vignette, .halte-blitz, .halte-bruch { display: none; }
}


.hell .schriftzug {
    --schriftzug-nah: color-mix(in srgb, var(--pink) 85%, black);
    --schriftzug-tiefe: color-mix(in srgb, var(--ink) 15%, transparent);
}

.hero-subtitle {
    font: var(--font-support);
    color: var(--ink-soft);
    text-align: center;
    max-width: 320px;
    margin: 0 auto;
    line-height: 1.35;
}

/* ── Die zwei Aktionspillen des Start-Reiters ──────────────────────
   1:1 aus `PillenStil` (`Theme/Buttons.swift`) – **eigene Klassen, nicht
   `.big-action`.** Die Modus-Wahl (`modusSchritt()`) benutzt `.big-action`
   für dieselbe Kartenform mit anderer Rolle; sie behält ihr Aussehen, das ist
   auf iOS ebenfalls `ModusWahl`, nicht `PillenStil` – der eine Knopfstil, der
   nur dem Start-Reiter gehört. */
.start-pillen {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
    width: 100%;
}

.start-pille {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    box-sizing: border-box;
    min-height: 92px;
    padding: 24px;
    border-radius: var(--radius-large);
    border: none;
    background: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: transform 0.12s ease-out;
}

.start-pille:active { transform: scale(0.965); }

.start-pille.gefuellt {
    background: linear-gradient(115deg,
        color-mix(in srgb, var(--pink) 88%, black) 0%, var(--neon-violett) 100%);
    background-repeat: no-repeat;
    border: 1px solid rgba(255, 255, 255, 0.22);
    box-shadow: 0 10px 15px color-mix(in srgb, var(--pink) 35%, transparent);
    color: #fff;
}

.start-pille.umrandet {
    background: color-mix(in srgb, var(--cyan) 7%, transparent);
    border: 1.5px solid color-mix(in srgb, var(--cyan) 55%, transparent);
    color: var(--cyan);
}

.start-pille-icon {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.start-pille.gefuellt .start-pille-icon {
    background: rgba(255, 255, 255, 0.15);
    border: 1px solid rgba(255, 255, 255, 0.35);
}

.start-pille.umrandet .start-pille-icon {
    background: color-mix(in srgb, var(--cyan) 15%, transparent);
    border: 1px solid color-mix(in srgb, var(--cyan) 35%, transparent);
}

.start-pille-titel {
    font: var(--font-title);
    flex: 1;
    min-width: 0;
}

.start-pille-chevron {
    flex: none;
    opacity: 0.7;
}

.start-fuss {
    font: var(--font-micro);
    color: var(--ink-faint);
    text-align: center;
    margin-top: 2px;
}

/* ── BigAction Karten (Modus-Wahl & laufende Runde) ────────── */

.big-actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
    width: 100%;
}

.big-action {
    display: flex;
    align-items: center;
    gap: var(--space-medium);
    width: 100%;
    box-sizing: border-box;
    padding: 16px var(--space-large);
    border-radius: var(--radius-large);
    text-align: left;
    cursor: pointer;
    border: 1px solid var(--kante-klar);
    background: rgba(var(--veil-basis), 0.03);
    position: relative;
    overflow: hidden;
    transition: transform 0.15s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.15s ease;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

.big-action:active {
    transform: scale(0.985);
    opacity: 0.9;
}

.big-action.pink-tint {
    background: radial-gradient(circle at 10% 10%, rgba(255, 62, 126, 0.24) 0%, rgba(255, 62, 126, 0.06) 55%, transparent 100%);
    border-color: rgba(255, 62, 126, 0.42);
}

.big-action.cyan-tint {
    background: radial-gradient(circle at 10% 90%, rgba(53, 221, 211, 0.22) 0%, rgba(53, 221, 211, 0.05) 55%, transparent 100%);
    border-color: rgba(53, 221, 211, 0.42);
}

.big-action-icon {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
}

.big-action.pink-tint .big-action-icon {
    background: rgba(255, 62, 126, 0.15);
    border: 1px solid rgba(255, 62, 126, 0.35);
    color: var(--pink);
}

.big-action.cyan-tint .big-action-icon {
    background: rgba(53, 221, 211, 0.15);
    border: 1px solid rgba(53, 221, 211, 0.35);
    color: var(--cyan);
}

.big-action-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.big-action-title {
    font: var(--font-title);
    font-size: 19px;
    font-weight: 700;
    color: var(--ink);
}

.big-action-subtitle {
    font: var(--font-support);
    color: var(--ink-soft);
}

.big-action-chevron {
    color: var(--ink-faint);
    flex: none;
    opacity: 0.7;
}

/* ── Section Label ────────────────────────────────────────── */

.section-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1.4px;
    color: var(--ink-faint);
    margin-top: var(--space-small);
    margin-bottom: var(--space-tight);
}

/* ── GameRow / Laufende Runden ────────────────────────────── */

.game-row {
    display: flex;
    align-items: center;
    gap: var(--space-medium);
    width: 100%;
    padding: 14px 16px;
    border-radius: var(--radius-large);
    background: rgba(var(--veil-basis), 0.03);
    border: 1px solid var(--kante-klar);
    cursor: pointer;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
    transition: transform 0.15s ease, opacity 0.15s ease;
    text-align: left;
}

.game-row:active {
    transform: scale(0.985);
}

.game-row-emoji {
    width: 52px;
    height: 52px;
    border-radius: var(--radius-medium);
    background: rgba(255, 62, 126, 0.14);
    border: 1px solid rgba(255, 62, 126, 0.4);
    display: grid;
    place-items: center;
    font-size: 24px;
    flex: none;
}

.game-row-emoji.cyan {
    background: rgba(53, 221, 211, 0.14);
    border-color: rgba(53, 221, 211, 0.4);
}

.game-row-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.game-row-title {
    font: var(--font-rowtitle);
    font-size: 16px;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.game-row-desc {
    font: var(--font-support);
    color: var(--ink-soft);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.game-row-meta {
    display: flex;
    align-items: center;
    gap: var(--space-small);
    font: var(--font-micro);
    color: var(--ink-faint);
}

.status-pill {
    display: inline-flex;
    align-items: center;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--pink);
    background: rgba(255, 62, 126, 0.14);
    border: 1px solid rgba(255, 62, 126, 0.35);
    border-radius: 999px;
    padding: 2px 8px;
}

.status-pill.cyan {
    color: var(--cyan);
    background: rgba(53, 221, 211, 0.14);
    border-color: rgba(53, 221, 211, 0.35);
}

/* ── Knöpfe ───────────────────────────────────────────────── */
button { font: inherit; color: inherit; cursor: pointer; }

.knopf {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-small);
    width: 100%;
    min-height: 52px;
    border: none;
    border-radius: var(--radius-medium);
    background: linear-gradient(180deg, var(--pink) 0%, #e62868 100%);
    color: #fff;
    font: var(--font-headline);
    font-size: 16px;
    font-weight: 700;
    padding: var(--space-medium) var(--space-large);
    border: 1px solid rgba(255, 255, 255, 0.22);
    box-shadow: 0 8px 24px rgba(255, 62, 126, 0.36);
    transition: transform 0.15s ease, opacity 0.15s ease;
}

.knopf:active:not(:disabled) {
    transform: scale(0.985);
    opacity: 0.9;
}

/* **Ein Knopf antwortet, bevor man ihn drückt.** Der leise Knopf trug bis zum
   05.09.2026 keinen Hover-Zustand und sah damit aus wie abgeschaltet – im
   Übersichts-Reiter standen drei davon untereinander, und man traute keinem.
   Mit Maus hellt er sich auf und zeigt eine türkise Kante; am Handy bleibt
   das Drücken (`:active`) die Antwort. */
@media (hover: hover) {
    .knopf:hover:not(:disabled) { filter: brightness(1.06); }
    .knopf.leise:hover:not(:disabled) {
        background: rgba(var(--veil-basis), 0.10);
        border-color: var(--cyan);
        color: var(--ink);
        filter: none;
    }
}

.knopf:disabled {
    background: rgba(var(--veil-basis), 0.08);
    border-color: var(--kante-klar);
    color: var(--ink-faint);
    box-shadow: none;
    cursor: default;
    opacity: 0.6;
}

.knopf.cyan {
    background: linear-gradient(180deg, var(--cyan) 0%, #20b8af 100%);
    color: var(--ground);
    box-shadow: 0 8px 24px rgba(53, 221, 211, 0.36);
}

.knopf.leise {
    background: rgba(var(--veil-basis), 0.05);
    color: var(--ink-soft);
    border: 1px solid var(--kante-klar);
    box-shadow: none;
    min-height: 48px;
    font-weight: 600;
}

/**
 * Nur so breit wie der Text, nicht `width: 100%` – für einen Knopf, der die
 * Ausnahme auf dem Bildschirm ist, nicht die Hauptaktion. Anders als
 * `.knopf.klein`: normale Groß-/Kleinschreibung und lesbare Schriftgröße,
 * keine Kapitälchen-Pille.
 */
.knopf.kompakt {
    width: auto;
    min-height: auto;
    padding: var(--space-small) var(--space-medium);
    border-radius: var(--radius-small);
    font-size: 15px;
}

/**
 * Kompakter Kapsel-Knopf für Zeilenaktionen (wie Gutschein-Einlösung) –
 * 1:1 zu den Kapseln in `SettingsCodeField` (iOS) und `SettingsCodeRow` (Android).
 */
.knopf.pille {
    width: auto;
    min-height: 28px;
    padding: 5px 13px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
    background: color-mix(in srgb, var(--cyan) 14%, transparent);
    border: 0.75px solid color-mix(in srgb, var(--cyan) 35%, transparent);
    color: var(--cyan);
    box-shadow: none;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s ease, border-color 0.15s ease, opacity 0.15s ease, color 0.15s ease;
}

@media (hover: hover) {
    .knopf.pille:hover:not(:disabled) {
        background: color-mix(in srgb, var(--cyan) 22%, transparent);
        border-color: color-mix(in srgb, var(--cyan) 55%, transparent);
        filter: none;
    }
}

.knopf.pille:disabled {
    background: rgba(var(--veil-basis), 0.08);
    border-color: var(--kante-fein);
    color: var(--ink-faint);
    box-shadow: none;
    cursor: default;
    opacity: 0.6;
}

.knopf.klein {
    width: auto;
    min-height: 36px;
    padding: var(--space-tight) var(--space-small);
    background: rgba(var(--veil-basis), 0.05);
    border: 1px solid var(--kante-klar);
    color: var(--ink-soft);
    font: var(--font-micro);
    border-radius: var(--radius-small);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

/**
 * Die getroffene Wahl unter kleinen Knöpfen – getönt wie `.dauer-kachel`, nur
 * in Violett, weil die Solo-Karte diese Farbe trägt (`RasterFeld`/`ZielFeld`
 * auf iOS tönen mit denselben 16 % und 55 %).
 *
 * **Diese Regel muss es geben.** `.knopf.klein` überschreibt den Verlauf von
 * `.knopf` mit derselben Fläche, die `.knopf.leise` setzt – ein gewählter
 * Knopf sah dadurch aus wie die ungewählten daneben, und die Wahl war auf dem
 * Bildschirm nicht ablesbar.
 */
.knopf.klein.gewaehlt {
    background: color-mix(in srgb, var(--violet) 16%, transparent);
    border-color: color-mix(in srgb, var(--violet) 55%, transparent);
    color: var(--violet);
}

select.knopf.klein {
    appearance: none;
    cursor: pointer;
    font: var(--font-micro);
    padding-right: calc(var(--space-small) + 12px);
    background-image: linear-gradient(45deg, transparent 50%, var(--ink-soft) 50%),
                      linear-gradient(135deg, var(--ink-soft) 50%, transparent 50%);
    background-position: right var(--space-tight) center,
                         calc(100% - var(--space-tight) + 4px) center;
    background-size: 4px 4px, 4px 4px;
    background-repeat: no-repeat;
}

:where(button, input, textarea, a, [tabindex]):focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
}

.big-action:focus-visible,
.game-row:focus-visible,
.dauer-kachel:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 3px;
    border-radius: var(--radius-large);
}

.wahlfeld:focus-visible,
.person-zeile:focus-visible,
.team-chip:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
    border-radius: var(--radius-medium);
}

.emoji-knopf:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
    border-radius: var(--radius-medium);
    transform: scale(1.12);
}

.kopf-icon-knopf:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
    border-radius: 50%;
}

.kopf-zurueck:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 2px;
    border-radius: var(--radius-medium);
}

/* ── Zeitstrahl / AblaufLeiste ────────────────────────────── */

.zeitstrahl {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    position: relative;
    width: 100%;
    padding: 0 4px;
    margin-bottom: var(--space-tight);
}

.zeitstrahl::before {
    content: "";
    position: absolute;
    top: 11px;
    left: 24px;
    right: 24px;
    height: 1px;
    background: var(--kante-fein);
    z-index: 0;
}

.zeitstrahl .schritt {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    flex: 1;
    position: relative;
    z-index: 1;
}

.zeitstrahl .punktzeile {
    width: 22px;
    height: 22px;
    display: grid;
    place-items: center;
    position: relative;
}

.zeitstrahl .punkt {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: rgba(var(--veil-basis), 0.18);
    transition: all 0.2s ease;
}

.zeitstrahl .schritt.erledigt .punkt {
    background: var(--cyan);
    box-shadow: 0 0 6px rgba(53, 221, 211, 0.6);
}

.zeitstrahl .schritt.jetzt .punkt {
    width: 10px;
    height: 10px;
    background: var(--pink);
    box-shadow: 0 0 10px rgba(255, 62, 126, 0.9);
}

.zeitstrahl .schritt.jetzt .punktzeile::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: rgba(255, 62, 126, 0.28);
    animation: zeitstrahl-puls 1.6s infinite ease-out;
}

@keyframes zeitstrahl-puls {
    0% { transform: scale(0.55); opacity: 1; }
    100% { transform: scale(1.3); opacity: 0; }
}

.zeitstrahl .schritt span:last-child {
    font-size: 10px;
    font-weight: 500;
    color: var(--ink-faint);
    text-align: center;
    line-height: 1.1;
    white-space: nowrap;
}

.zeitstrahl .schritt.jetzt span:last-child {
    color: var(--ink);
    font-weight: 700;
}

/* ── Garderobenmarke (Einladungs-Ticket) ───────────────────── */

.garderobenmarke {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    box-sizing: border-box;
    padding: var(--space-large);
    border-radius: var(--radius-hero);
    background: linear-gradient(135deg, rgba(255, 62, 126, 0.13), rgba(var(--veil-basis), 0.04));
    border: 1px solid var(--kante-klar);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
    position: relative;
    overflow: hidden;
}

.marke-kopf {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 4px;
    width: 100%;
}

.marke-emoji {
    font-size: 34px;
    line-height: 1;
}

/* Das eigene Bild einer Runde – an derselben Stelle wie das Sinnbild, in der
   Form, in der die Runde auch sonst auftritt: eine Karte, kein Kreis. */
.marke-bild {
    width: 76px;
    height: 76px;
    object-fit: cover;
    border-radius: 21px;
    border: 1px solid var(--kante-fein);
}

.marke-titel {
    font: var(--font-display);
    font-size: 24px;
    font-weight: 800;
    color: var(--ink);
    margin: 4px 0 0 0;
}

.marke-gastgeber {
    font: var(--font-support);
    color: var(--ink-soft);
}

.marke-perforation {
    width: calc(100% + 2 * var(--space-large));
    margin: var(--space-medium) calc(-1 * var(--space-large));
    height: 1px;
    background: repeating-linear-gradient(90deg, var(--kante-klar), var(--kante-klar) 6px, transparent 6px, transparent 12px);
    position: relative;
}

.marke-abriss {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: var(--space-medium);
    width: 100%;
}

.marke-qr-box {
    /* Das Bild, das man jemandem hinhält – es darf so groß sein wie der Code
       daneben laut ist. Auf iOS sind es 112 pt in einer Handbreite; im
       Browser steht mehr Fläche zur Verfügung, und ein zu kleiner QR-Code
       lässt sich aus einem Meter Abstand nicht mehr scannen. */
    width: 168px;
    height: 168px;
    border-radius: var(--radius-medium);
    background: #ffffff;
    padding: 8px;
    flex: none;
    display: grid;
    place-items: center;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
}

.marke-qr-box .qr-bild {
    width: 100%;
    height: 100%;
    display: block;
}

.marke-details {
    display: flex;
    flex-direction: column;
    gap: var(--space-tight);
    /* Schmäler als das wird die Spalte nicht gequetscht – sie bricht dann
       lieber unter das QR-Bild, statt die Ziffern abzuschneiden. */
    flex: 1 1 200px;
    min-width: 0;
}

.marke-code-zeile {
    display: flex;
    align-items: center;
    gap: var(--space-small);
}

.marke-code {
    font-family: var(--slab);
    font-weight: 800;
    font-size: clamp(26px, 2.4vw, 34px);
    color: var(--ink);
    letter-spacing: 0.06em;
    line-height: 1.1;
    white-space: nowrap;
}

/**
 * Kopieren als kleines Zeichen neben den Ziffern – dieselbe Lösung wie
 * `kopierZeichen` auf iOS: Es steht dort, wo der Code steht, statt als
 * eigener Knopf in voller Breite darunter.
 */
.marke-kopie {
    width: 34px;
    height: 34px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 1px solid var(--kante-klar);
    background: rgba(var(--veil-basis), 0.07);
    color: var(--ink-soft);
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.marke-kopie:hover {
    color: var(--cyan);
    border-color: color-mix(in srgb, var(--cyan) 45%, transparent);
}

.marke-kopie:active { transform: scale(0.94); }

/**
 * Die beiden Wege, die der Browser zusätzlich braucht: den Link verschicken
 * (auf iOS macht das das Teilen-Blatt) und den Code entziehen (auf iOS das
 * Kontextmenü). Sie stehen als kleine Zeilen unter dem Code – erreichbar,
 * aber nicht in der Lautstärke von „Weiter".
 */
.marke-aktionen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-tight) var(--space-medium);
    margin-top: 2px;
}

.marke-tat {
    background: none;
    border: none;
    padding: 2px 0;
    color: var(--ink-soft);
    font: var(--font-support);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-color: var(--kante-stark);
    text-underline-offset: 3px;
    transition: color 0.15s ease;
}

.marke-tat:hover {
    color: var(--cyan);
    text-decoration-color: color-mix(in srgb, var(--cyan) 60%, transparent);
}

.marke-tat:active { opacity: 0.7; }


/**
 * Die Bühne des Einladen-Bildschirms.
 *
 * **Am Handy untereinander, im Browser nebeneinander.** Marke, Mitspieler und
 * „Weiter" ergeben gestapelt gut 900 px; auf einem 14-Zoll-Notebook (830 px
 * Fensterhöhe) reicht das nicht, und wer sehen will, wer schon da ist, muss
 * scrollen – während rechts und links vom Inhalt leerer Verlauf steht.
 * Zwei Spalten füllen das Fenster und lassen den Bildschirm in einem Blick.
 */
.einladen-buehne {
    display: flex;
    flex-direction: column;
    gap: var(--space-large);
    width: 100%;
}

.einladen-spalte {
    display: flex;
    flex-direction: column;
    gap: var(--space-large);
}

/**
 * Die Bühne eines Aufbauschritts – eine Spalte, auch im Browser (seit dem
 * 16.09.2026; die Breite steht weiter unten bei `.rahmen.breit.einrichten`).
 */
.aufbau-buehne {
    display: flex;
    flex-direction: column;
    gap: var(--space-large);
    width: 100%;
}

@media (min-width: 900px) {
    .einladen-buehne { flex-direction: row; align-items: flex-start; }
    .einladen-buehne > .garderobenmarke { flex: 1 1 46%; min-width: 0; }
    .einladen-buehne > .einladen-spalte { flex: 1 1 54%; min-width: 0; }
}


/* ── Flächen / Glass Panel ────────────────────────────────── */

.karte {
    background: rgba(var(--veil-basis), 0.03);
    border: 1px solid var(--kante-klar);
    border-radius: var(--radius-large);
    padding: var(--space-large);
    display: flex;
    flex-direction: column;
    gap: var(--space-medium);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.karte.stark {
    border-color: var(--kante-stark);
    border-radius: var(--radius-hero);
}

.karte.cyan-licht {
    background: radial-gradient(circle at 10% 90%, rgba(53, 221, 211, 0.20) 0%, rgba(53, 221, 211, 0.05) 55%, transparent 100%);
    border-color: rgba(53, 221, 211, 0.42);
}

h1 { font: var(--font-display); font-size: 26px; line-height: 1.2; }
h2 { font: var(--font-title); }
h3 { font: var(--font-headline); }

.leise-zeile { font: var(--font-support); color: var(--ink-soft); }
.mikro {
    font: var(--font-micro);
    color: var(--ink-faint);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/*
 * **Kapitälchen sind eine Überschrift, kein Kleingedrucktes.** „Satz 1 von 9"
 * und „von dir · selbst gemeldet" sind Sätze und werden gelesen, nicht
 * überflogen – in Versalien las sich beides wie eine Rubrik.
 */
.mikro.normal { text-transform: none; letter-spacing: normal; }

/*
 * **Die Abschnittsüberschrift** – das Web-Pendant zu `SectionLabel` in iOS und
 * Android, mit denselben Maßen. Sie steht heute an einer Stelle: der
 * Auflösung, die Treffer von Fehlschüssen trennt.
 *
 * Die Farbe kommt von `.gut` daneben und muss deshalb **später** stehen als
 * diese Regel – bei gleicher Spezifität gewinnt die letzte.
 */
.abschnitt {
    font: 700 11px var(--system);
    text-transform: uppercase;
    letter-spacing: 1.4px;
    color: var(--ink-faint);
    margin: var(--space-small) 0 var(--space-tight);
}

/*
 * **Die Zeile unter der Stichtags-Wahl.** Beschriftung links, Datumsfeld
 * rechts – und beim Gast statt des Feldes nur der Text, weil ein
 * abgeschaltetes Eingabefeld aussieht wie eine Bedienung, die klemmt.
 */
.stichtag-zeile {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-small);
    padding: var(--space-tight) 0 0;
}
.stichtag-zeile .feld { width: auto; min-height: 40px; flex: 0 1 auto; }

.trenner { height: 1px; background: var(--kante-fein); border: none; }

/* ── Eingabefelder ────────────────────────────────────────── */

label {
    display: block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    color: var(--ink-faint);
    margin-bottom: var(--space-tight);
}

.feld {
    width: 100%;
    min-height: 52px;
    padding: var(--space-medium) var(--space-large);
    border: 1px solid var(--kante-klar);
    border-radius: var(--radius-medium);
    background: rgba(150, 111, 255, 0.07);
    color: var(--ink);
    font: var(--font-body);
    font-size: 16px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.feld::placeholder { color: var(--ink-faint); }
.feld:focus {
    outline: none;
    border-color: var(--cyan);
    box-shadow: 0 0 12px rgba(53, 221, 211, 0.35);
}

.feld.code {
    font-family: var(--slab);
    font-weight: 800;
    font-size: 32px;
    text-align: center;
    letter-spacing: 0.25em;
    padding-left: calc(var(--space-large) + 0.25em);
    min-height: 64px;
}

textarea.feld { min-height: 88px; resize: vertical; line-height: 1.4; }

/* ── Emoji-Wahl & Sinnbild-Wahl ───────────────────────────── */

.emoji-wahl {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: var(--space-tight);
}

.emoji-knopf {
    aspect-ratio: 1;
    min-height: 46px;
    border: 1px solid var(--kante-fein);
    border-radius: var(--radius-small);
    background: rgba(var(--veil-basis), 0.03);
    font-size: 24px;
    line-height: 1;
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.emoji-knopf:active {
    transform: scale(0.92);
}

.emoji-knopf[aria-pressed="true"] {
    border-color: var(--pink);
    background: rgba(255, 62, 126, 0.20);
    box-shadow: 0 0 10px rgba(255, 62, 126, 0.4);
}

.emoji-vorschau-box {
    width: 52px;
    height: 52px;
    border-radius: var(--radius-medium);
    background: rgba(var(--veil-basis), 0.06);
    border: 1px solid var(--kante-klar);
    display: grid;
    place-items: center;
    font-size: 26px;
    flex: none;
}

/* ── Zeilen und Avatare ───────────────────────────────────── */

.liste { display: flex; flex-direction: column; gap: var(--space-small); list-style: none; }

.zeile {
    display: flex;
    align-items: center;
    gap: var(--space-medium);
    width: 100%;
    min-height: 56px;
    padding: var(--space-small) var(--space-medium);
    border: 1px solid var(--kante-fein);
    border-radius: var(--radius-medium);
    background: rgba(var(--veil-basis), 0.02);
    text-align: left;
    transition: transform 0.15s ease;
}

.zeile.antippbar { cursor: pointer; }
.zeile.antippbar:active { transform: scale(0.985); }
.zeile .waechst { flex: 1; min-width: 0; }
.zeile .name { font: var(--font-label); font-weight: 700; color: var(--ink); }
.zeile .untertitel {
    font: var(--font-support);
    font-size: 12px;
    color: var(--ink-faint);
    margin-top: 1px;
}

.zeilen-icon {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--cyan) 16%, transparent);
    color: var(--cyan);
}

.gutschein-zeile {
    display: flex;
    align-items: center;
    gap: var(--space-medium);
}

.gutschein-status {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.code-badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 8px;
    border-radius: 9999px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.5px;
    background: color-mix(in srgb, var(--cyan) 14%, transparent);
    border: 0.75px solid color-mix(in srgb, var(--cyan) 35%, transparent);
    color: var(--cyan);
    flex-shrink: 0;
}

.gutschein-eingabe-huelle {
    display: flex;
    align-items: center;
    position: relative;
    min-width: 0;
}

.gutschein-eingabe {
    width: 100%;
    background: transparent;
    border: none;
    outline: none;
    font: var(--font-body);
    font-size: 15px;
    color: var(--ink);
    padding: 0;
}

.gutschein-eingabe:not(:placeholder-shown) {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-weight: 600;
}

.gutschein-eingabe::placeholder {
    color: var(--ink-faint);
    font-family: var(--font-body);
    font-weight: 400;
}

.gutschein-clear-knopf {
    background: transparent;
    border: none;
    color: var(--ink-faint);
    padding: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    border-radius: 50%;
    flex-shrink: 0;
    transition: color 0.15s ease;
}

.gutschein-clear-knopf:hover {
    color: var(--ink);
}

.gutschein-fussnote {
    font: var(--font-support);
    font-size: 12px;
    line-height: 1.4;
    color: var(--ink-faint);
    padding: 2px var(--space-medium) 0;
    margin: 0;
}

.gutschein-fussnote.erfolg {
    color: var(--cyan);
}

.gutschein-fussnote.fehler {
    color: var(--amber);
}

.spinner-kreis {
    width: 12px;
    height: 12px;
    border: 2px solid color-mix(in srgb, var(--cyan) 25%, transparent);
    border-top-color: var(--cyan);
    border-radius: 50%;
    animation: spinner-drehung 0.75s linear infinite;
    display: inline-block;
}

@keyframes spinner-drehung {
    to { transform: rotate(360deg); }
}

.avatar {
    flex: none;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 20px;
    background: rgba(var(--veil-basis), 0.08);
    border: 1.5px solid var(--spieler-farbe, var(--violet));
    overflow: hidden;
    box-shadow: 0 0 8px color-mix(in srgb, var(--spieler-farbe, var(--violet)) 40%, transparent);
}

.avatar img { width: 100%; height: 100%; object-fit: cover; }

/* ── Modus-Wahl Vorschau ──────────────────────────────────── */

.mini-karten-vorschau {
    position: relative;
    width: 52px;
    height: 44px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
}

.mini-karten-stapel {
    position: relative;
    width: 22px;
    height: 28px;
}

.mini-karte-blatt {
    position: absolute;
    width: 22px;
    height: 28px;
    border-radius: 4px;
    background: rgba(150, 111, 255, 0.10);
    border: 1px solid var(--kante-klar);
}

.mini-karte-blatt:nth-child(1) { left: -13px; top: 3px; }
.mini-karte-blatt:nth-child(2) { left: 0px; top: 0px; }
.mini-karte-blatt:nth-child(3) { left: 13px; top: -3px; border-color: rgba(255, 62, 126, 0.75); }

.mini-gruppe-grid {
    display: grid;
    grid-template-columns: repeat(4, 7.5px);
    grid-template-rows: repeat(4, 7.5px);
    gap: 1.5px;
    padding: 3px;
    border-radius: 6px;
    border: 1px solid rgba(53, 221, 211, 0.55);
}

.mini-gruppe-zelle {
    border-radius: 1.5px;
    opacity: 0.85;
}

/* ── Bingokarte ───────────────────────────────────────────── */
/* Die Felder selbst tragen keine Klasse mehr: `ansicht.js` setzt sie seit
   dem Entwurf „Karte Flug" mit eigenen Stilen je Feld. Hier steht nur noch
   das Raster, das sie hält. */

/*
 * **Die Kachel wächst mit, bleibt aber eine Kachel.** Ohne Deckel würde eine
 * 3×3-Karte in der breiten Bühne (`.rahmen.breit`) auf über 200 pt pro Feld
 * gezogen – viel leere Fläche um einen kurzen Satz. Der Deckel skaliert mit
 * der Spaltenzahl, damit ein 5×5-Raster mehr Breite bekommt als ein 3×3, und
 * zentriert sich selbst, sobald die Bühne breiter ist als sein Bedarf.
 */
.raster {
    display: grid;
    grid-template-columns: repeat(var(--spalten, 3), 1fr);
    gap: var(--zellenfuge, var(--space-small));
    width: 100%;
    max-width: calc(var(--spalten, 3) * 160px);
    margin: 0 auto;
    padding: 0 12px;
    box-sizing: border-box;
    container-type: inline-size;
}

/* Die Modus-Vorschau der Solo-Karte: ein 3×3 statt des 4×4 der Teamkarte,
   in Violett statt Türkis – dieselbe Farbe, die die Karte selbst trägt. */
.mini-gruppe-grid.solo {
    grid-template-columns: repeat(3, 9px);
    grid-template-rows: repeat(3, 9px);
    border-color: color-mix(in srgb, var(--violet) 55%, transparent);
}

/* Ein Feld der Solo-Karte. **Farben setzt `ansicht.js` je Feld** – Treffer,
   Siegfeld und Lücke unterscheiden sich pro Kachel, genau wie auf der
   Spielkarte seit „Karte Flug". Hier stehen nur die Maße und das, was für
   alle gilt. */
/* Die Kachelbreite kommt aus dem Container (`.raster`, `container-type:
   inline-size`), nicht aus dem Rasterfluss selbst – `cqw` misst also genau
   die Breite, die `1fr` gerade wirklich bekommt. `--zk` ist das Gegenstück zu
   `kante` in `SoloKarteView.swift`: (Containerbreite − Zwischenräume) / Spalten. */
.solo-feld {
    --zk: calc((100cqw - (var(--spalten, 3) - 1) * var(--zellenfuge, 6px)) / var(--spalten, 3));
    aspect-ratio: 1 / var(--hoehenfaktor, 1);
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    padding: clamp(5px, calc(var(--zk) * 0.06), 7px);
    border-radius: var(--radius-medium);
    border: 1px solid var(--kante-klar);
    font-family: var(--system);
    font-weight: 500;
    font-size: clamp(10px, calc(7px + var(--zk) * 0.07), 16px);
    text-align: center;
    line-height: 1.25;
    overflow: hidden;
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.2s ease;
}

.solo-feld:hover:not(:disabled) { transform: translateY(-1px); }
.solo-feld:disabled { cursor: default; opacity: 0.75; }

/* Lange Sätze auf kleinen Kacheln: lieber umbrechen als überlaufen. */
.solo-feld > span:first-child {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* Der Haken-Kreis bei einem Treffer – Gegenstück zu `SoloFeld.hakenGroesse`. */
.solo-feld-haken {
    position: absolute;
    top: clamp(4px, calc(var(--zk) * 0.05), 6px);
    right: clamp(4px, calc(var(--zk) * 0.05), 6px);
    width: clamp(14px, calc(var(--zk) * 0.16), 22px);
    height: clamp(14px, calc(var(--zk) * 0.16), 22px);
    border-radius: 50%;
    background: #fff;
    color: color-mix(in srgb, var(--pink) 85%, black);
    font-size: clamp(8px, calc(var(--zk) * 0.09), 12px);
    font-weight: 900;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

/* Eine schon eingetragene Vorhersage – zusammengeklappt, mit „Ändern". */
.steht {
    display: flex;
    align-items: flex-start;
    gap: var(--space-small);
    padding: var(--space-small) var(--space-medium);
    border: 1px solid var(--kante-fein);
    border-radius: var(--radius-medium);
    background: rgba(var(--veil-basis), 0.02);
}

.steht .knopf { width: auto; min-height: 36px; padding: var(--space-tight) var(--space-small); }

/* ── Phasenkopf: die Farbe sitzt an der Kante, nicht im Satz ── */
/*
 * `.dran`/`.gut` färbten die ganze Karte – und damit auch die Überschrift, die
 * dadurch pink war. In der App ist sie `Theme.ink` und getönt wird der Rahmen;
 * eine pinke Überschrift über einem violetten Rahmen sah aus wie ein Fehler.
 */
/* **Mittig, wie `PhasenKopf` in der App** (16.09.2026) – Überschrift und Zeile
   darunter sind eine Antwort auf „was ist jetzt zu tun?" und stehen unter der
   Ablaufleiste, die selbst über die ganze Breite läuft. */
.phasenkopf h1 { color: var(--ink); text-align: center; }
.phasenkopf .leise-zeile { text-align: center; }
.phasenkopf.dran { border-color: color-mix(in srgb, var(--pink) 45%, transparent); }
.phasenkopf.gut  { border-color: color-mix(in srgb, var(--cyan) 45%, transparent); }

/* ── Spieldauer: die Wahl zeigt, was man bekommt ──────────── */
/*
 * Gegenstück zu `ScopePhase`/`Rastervorschau` in der App. Vorher standen hier
 * zwei Zeilen mit Radioknopf untereinander – ein Wort lässt sich deuten, ein
 * Muster nicht. Die Diagonale zeigt, wie lang eine Linie wird.
 */

.dauer-wahl {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-small);
}

.dauer-kachel {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-small);
    padding: var(--space-medium) var(--space-small);
    border: 1px solid var(--kante-klar);
    border-radius: var(--radius-small);
    background: transparent;
    cursor: pointer;
    transition: transform 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.dauer-kachel:active { transform: scale(0.985); }

/* Getönt bleibt allein die Wahl – dort ist die Farbe die Aussage. */
.dauer-kachel.gewaehlt {
    background: color-mix(in srgb, var(--pink) 16%, transparent);
    border-color: color-mix(in srgb, var(--pink) 55%, transparent);
}

.dauer-titel { font: var(--font-rowtitle); color: var(--ink); }
.dauer-kachel.gewaehlt .dauer-titel { color: var(--pink); }
.dauer-unter { font: var(--font-micro); color: var(--ink-faint); text-align: center; }

.raster-vorschau {
    display: grid;
    grid-template-columns: repeat(var(--raster-spalten), 19px);
    gap: 5px;
}

/* Kleiner bei größeren Rastern, damit die Vorlage immer gleich breit ist. */
.raster-vorschau.eng { grid-template-columns: repeat(var(--raster-spalten), 15px); }

.raster-zelle {
    aspect-ratio: 1;
    border-radius: 4px;
    border: 1px solid color-mix(in srgb, var(--kante-klar) 70%, transparent);
}

.raster-zelle.auf-linie {
    border-color: transparent;
    background: linear-gradient(140deg, var(--treffer-a), var(--treffer-b));
}

/* ── Schreiben: erst die Person, dann Satz für Satz ───────── */
/*
 * Gegenstück zu `WritingPhase` und `SchreibDeck` in der App. Vorher stand
 * jeder Auftrag als eigenes Feld untereinander, jedes mit eigenem Knopf.
 */

.person-zeile {
    display: flex;
    align-items: center;
    gap: var(--space-medium);
    width: 100%;
    padding: var(--space-medium) var(--space-large);
    border-radius: var(--radius-large);
    /* Jede Person hat ihre Farbe – auch als Zeile. Der Zustand steht daneben
     * in der Kapsel, nie in der Kante: Spielerfarben gehören einer Person. */
    background: color-mix(in srgb, var(--spieler-farbe, var(--violet)) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--spieler-farbe, var(--violet)) 60%, transparent);
    text-align: left;
    cursor: pointer;
    transition: transform 0.15s ease;
}

.person-zeile:active { transform: scale(0.985); }
.person-name { font: var(--font-title); color: var(--ink); }
.zeilen-pfeil { flex: none; color: var(--ink-faint); font-size: 20px; line-height: 1; }

.noch-pille {
    flex: none;
    font-size: 11px;
    font-weight: 700;
    color: var(--pink);
    padding: 5px 9px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--pink) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--pink) 40%, transparent);
}

.avatar.gross { width: 52px; height: 52px; font-size: 26px; }
.avatar.klein { width: 34px; height: 34px; font-size: 17px; }

.schreib-kopf { display: flex; align-items: center; gap: var(--space-small); }

/*
 * Die Fortschrittskette: ein Glied je Auftrag – kein Prozentbalken. Bei vier
 * Sätzen sagt „25 %" weniger als ein Glied von vieren. Die erledigten Glieder
 * tragen ihren Platz auf der Gewinnlinie von Pink nach Cyan.
 */
.perlen {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 5px;
    height: 4px;
}

.perle {
    border-radius: 999px;
    /* Die leeren Plätze sind nicht grau – ein weißer Schleier würde auf
     * tiefschwarzem Grund zu Grau; die schwache Tönung bleibt Teil der Welt. */
    background: color-mix(in srgb, var(--violet) 22%, transparent);
}

.perle.voll,
.perle.jetzt {
    background: color-mix(in oklab, var(--pink), var(--cyan) calc(var(--anteil, 0) * 100%));
}

.perle.jetzt { opacity: 0.45; }

/* Die einzige Karte mit deckender Fläche – sie trägt die Eingabe. */
.schreib-karte {
    display: flex;
    flex-direction: column;
    gap: var(--space-medium);
    border-color: color-mix(in srgb, var(--pink) 30%, transparent);
    background:
        radial-gradient(120% 90% at 0% 0%,
                        color-mix(in srgb, var(--pink) 20%, transparent), transparent 70%),
        var(--ground-lift);
}

.schreib-karte h3 { font: var(--font-headline); color: var(--ink); }
.steht-liste { max-height: 260px; overflow-y: auto; }

/* ── Übersicht: der Zeitstrahl der Runde ──────────────────── */
/*
 * Gegenstück zu `Zeitstrahl` in der App. Er läuft rückwärts durch die Zeit:
 * Wer die Seite aufmacht, um zu sehen, was gerade passiert ist, soll nicht
 * erst an allem vorbeiscrollen, was er schon kennt.
 */

/* **Ohne Pink seit dem 30.08.2026.** Pink heißt „was jetzt dran ist" und
 * höchstens einmal je Bildschirm; der Gewinn ist das Gegenteil davon – eine
 * Tatsache, die sich über die ganze Runde nicht ändert. Mit Fläche und Kante
 * las sich die Zeile als Karte und stand als zweite laute Kante direkt über
 * der türkisen Stand-Karte. In derselben Zeile steht jetzt der Stand der
 * Karte, wofür vorher eine eigene Kapitälchen-Überschrift da war. */
.gewinn-zeile {
    display: flex;
    align-items: center;
    gap: var(--space-small);
    font: var(--font-support);
    color: var(--ink-soft);
    padding: 0 var(--space-tight);
    margin: 0;
}

.gewinn-zeile .trennpunkt { color: var(--ink-faint); }

.stand-karte { display: flex; flex-direction: column; gap: var(--space-tight); }
.stand-karte h3 { font: var(--font-title); color: var(--ink); }

/* **Punkte statt Balken (30.08.2026).** Überschrift, Unterzeile und Balken
 * sagten dasselbe dreimal – als Satz, als Bruch und als Grafik. Vier Felder,
 * drei davon voll, sagen es einmal und zeigen zusätzlich, wie lang die Linie
 * überhaupt ist. Die Unterzeile trägt der `aria-label` weiter. */
.linienpunkte {
    display: flex;
    gap: var(--space-tight);
    margin-top: var(--space-tight);
}

.linienpunkt {
    flex: 1;
    height: 7px;
    border-radius: 999px;
    border: 1.5px solid color-mix(in srgb, var(--cyan) 55%, transparent);
}

.linienpunkt.voll {
    border-color: transparent;
    background: var(--cyan);
}

.sieg-karte {
    border-color: color-mix(in srgb, var(--pink) 45%, transparent);
    background: color-mix(in srgb, var(--pink) 12%, transparent);
}

.sieg-karte h2 { font: var(--font-title); color: var(--ink); }

/*
 * Das Band trägt den Bogen der Runde – Pink oben, wo das Jüngste steht,
 * Türkis unten am Anfang. Es liegt hinter den Einträgen, damit die Punkte
 * darauf sitzen.
 */
.strahl {
    position: relative;
    display: flex;
    flex-direction: column;
}

.strahl::before {
    content: "";
    position: absolute;
    left: 5px;
    top: 7px;
    bottom: 18px;
    width: 1.5px;
    background: linear-gradient(180deg, var(--pink),
                color-mix(in srgb, var(--violet) 55%, transparent), var(--cyan));
    opacity: 0.85;
}

.strahl-eintrag {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: var(--space-medium);
    padding-bottom: var(--space-medium);
}

.bandpunkt {
    flex: none;
    width: 11px;
    height: 11px;
    margin-top: 4px;
    border-radius: 50%;
    background: var(--cyan);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--cyan) 22%, transparent);
}

/* **Der Punkt trägt zwei Auskünfte.** Türkis heißt „ein Treffer", Pink
 * zusätzlich „das ist neu für dich". */
.bandpunkt.neu {
    background: var(--pink);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--pink) 22%, transparent);
}

/* **Die Uhrzeit steht über ihrer Gruppe, nicht in jeder Zeile (30.08.2026).**
 * Sechs Meldungen aus zwei Minuten trugen sechsmal fast dieselbe Zahl vor sich
 * her – in der Spalte, die zuerst gelesen wird. Leiser als der Tag darüber,
 * sonst stünden zwei gleich laute Überschriften übereinander. */
.zeit-kopf {
    margin-left: calc(11px + var(--space-medium));
    margin-bottom: var(--space-tight);
    font: 600 11px ui-monospace, SFMono-Regular, Menlo, monospace;
    font-variant-numeric: tabular-nums;
    color: var(--ink-faint);
}

/* **Was seit dem letzten Besuch dazugekommen ist** – siehe `js/gelesen.js`. */
.neu-trenner {
    display: flex;
    align-items: center;
    gap: var(--space-small);
    margin-left: calc(11px + var(--space-medium));
    margin-bottom: var(--space-small);
}

.neu-strich {
    flex: 1;
    height: 1px;
    background: color-mix(in srgb, var(--pink) 45%, transparent);
}

.neu-zahl {
    font: 700 10px var(--system);
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--pink);
}

.strahl-satz { font: var(--font-body); color: var(--ink); }
.strahl-name { font-weight: 700; color: var(--spieler-farbe, var(--ink)); }

/* Der Tag steht als Überschrift, nicht in jeder Zeile – eingerückt neben
 * dem Band, nicht darauf. */
.tages-kopf { margin-left: calc(11px + var(--space-medium)); }

/* ── Reiterleiste (Tab Bar aus iOS) ───────────────────────── */

.reiter {
    display: flex;
    gap: var(--space-tight);
    background: rgba(var(--veil-basis), 0.04);
    padding: 4px;
    border-radius: var(--radius-medium);
    border: 1px solid var(--kante-klar);
}

.reiter button {
    flex: 1;
    /* Trägt den Zähler in der Ecke – siehe `.chat-zahl`. */
    position: relative;
    min-height: 40px;
    border-radius: calc(var(--radius-medium) - 3px);
    background: none;
    font: var(--font-label);
    font-size: 14px;
    color: var(--ink-soft);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: all 0.15s ease;
}

.reiter button[aria-pressed="true"] {
    color: var(--ink);
    background: rgba(255, 62, 126, 0.16);
    border: 1px solid rgba(255, 62, 126, 0.4);
    font-weight: 700;
    box-shadow: 0 0 10px rgba(255, 62, 126, 0.25);
}

/* ── Modals / Sheets (Blatt) ──────────────────────────────── */

.blatt {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(0, 0, 0, 0.65);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    padding: 0;
    animation: blatt-fade 0.2s ease-out;
}

@keyframes blatt-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

.blatt > div {
    width: 100%;
    max-width: 440px;
    max-height: 86vh;
    overflow-y: auto;
    background: var(--schwebe-grund);
    border: 1px solid var(--kante-stark);
    border-bottom: none;
    border-top-left-radius: var(--radius-hero);
    border-top-right-radius: var(--radius-hero);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    padding: var(--space-large);
    padding-bottom: max(var(--space-large), env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    gap: var(--space-medium);
    box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.16);
    animation: blatt-slide 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
    scrollbar-width: thin;
    scrollbar-color: var(--kante-klar) transparent;
}

.blatt > div::-webkit-scrollbar {
    width: 6px;
}

.blatt > div::-webkit-scrollbar-track {
    background: transparent;
}

.blatt > div::-webkit-scrollbar-thumb {
    background: var(--kante-klar);
    border-radius: 999px;
}

.blatt-griff {
    width: 36px;
    height: 5px;
    border-radius: 999px;
    background: rgba(var(--veil-basis), 0.22);
    margin: -4px auto 4px auto;
    flex: none;
}

@keyframes blatt-slide {
    from { transform: translateY(40px); }
    to { transform: translateY(0); }
}

@keyframes blatt-dialog-in {
    from { opacity: 0; transform: scale(0.96) translateY(8px); }
    to { opacity: 1; transform: scale(1) translateY(0); }
}

/* ── Meldungen & Feedback ─────────────────────────────────── */

.hinweis {
    border: 1px solid var(--kante-klar);
    border-radius: var(--radius-medium);
    padding: var(--space-small) var(--space-medium);
    font: var(--font-support);
    color: var(--ink-soft);
    background: rgba(var(--veil-basis), 0.03);
}

.hinweis.schlecht {
    border-color: var(--pink);
    background: rgba(255, 62, 126, 0.12);
    color: var(--ink);
}

.hinweis.gut {
    border-color: var(--cyan);
    background: rgba(53, 221, 211, 0.12);
    color: var(--ink);
}

/* **In der laufenden Runde ist der Hinweis ein Toast, keine Zeile.** Als Zeile
   stand er zwischen Kopfleiste und Reitern und schob die Reiter nach unten –
   genau das, was seit dem 05.09.2026 nicht mehr passieren darf. Als Toast
   schwebt er unten über dem Inhalt, blendet ein und geht (bei „gut“) von
   selbst wieder. Dieselbe Bauart wie der Feld-Hinweis der Karte. */
html.runde-offen .rahmen > .hinweis {
    position: fixed;
    /* Mittig über `left/right: 0` plus `margin: auto`, nicht über einen
       `transform` – den setzt die Einblend-Animation am Ende auf `none`. */
    left: 0;
    right: 0;
    margin: 0 auto;
    bottom: max(24px, env(safe-area-inset-bottom));
    z-index: 60;
    width: min(560px, calc(100% - 40px));
    text-align: center;
    font-weight: 600;
    color: var(--ink);
    overflow-wrap: anywhere;
    background: var(--schwebe-grund);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
    animation: einblenden 0.22s ease;
}

html.runde-offen .rahmen > .hinweis.gut {
    background: color-mix(in srgb, var(--cyan) 18%, var(--schwebe-grund));
}

html.runde-offen .rahmen > .hinweis.schlecht {
    background: color-mix(in srgb, var(--pink) 18%, var(--schwebe-grund));
}

/* ── Kleinteile ───────────────────────────────────────────── */

.reihe { display: flex; gap: var(--space-small); align-items: center; }
.reihe.verteilt { justify-content: space-between; }
.reihe.zentriert { justify-content: center; }

/*
   Drei Punkte, die warten – neben „verbindet" und „Code entsteht".

   Die Klasse stand seit dem Umbau in `js/ansicht.js`, die Regel dazu nie:
   Drei leere `<i>` ohne Größe und ohne Farbe sind im Browser nichts, also
   sah man an vier Stellen genau gar nichts warten. `aria-hidden` sitzt am
   Behälter, weil der Satz daneben schon sagt, was gerade läuft – ein
   Vorleseprogramm soll nicht dreimal „Punkt" hinterherschieben.

   Die Bewegung braucht hier keinen eigenen Riegel: Ganz unten steht die
   Regel, die jede Animation abstellt, sobald das System sie abbestellt hat.
   **Deshalb ist der Ruhezustand der sichtbare** – die Punkte stehen voll da
   und die Welle dimmt sie kurz weg, nicht umgekehrt. Andersherum fröre die
   angehaltene Animation auf dem blassen Bild ein, und ausgerechnet wer die
   Bewegung abbestellt hat, bekäme den Hinweis am schlechtesten zu sehen.
*/
.punkte { display: inline-flex; gap: var(--space-hairline); align-items: center; }
.punkte i {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--ink-faint);
    opacity: 1;
    animation: punkte-puls 1.2s infinite ease-in-out;
}
.punkte i:nth-child(2) { animation-delay: 0.16s; }
.punkte i:nth-child(3) { animation-delay: 0.32s; }

@keyframes punkte-puls {
    0%, 100% { opacity: 1; }
    45%      { opacity: 0.2; }
}
.spalte { display: flex; flex-direction: column; gap: var(--space-small); }
.waechst { flex: 1; min-width: 0; }
.gut { color: var(--cyan); }
.dran { color: var(--pink); }

/*
   **Die Breite wächst mit dem Fenster – gestaffelt, nicht endlos.** Ein
   Formular oder eine Zeilenliste wird ab einer gewissen Breite nur schwerer
   zu lesen, keine Zeile darin wird dadurch wichtiger; die Stufen halten die
   Zeilenlänge vernünftig und nutzen trotzdem spürbar mehr vom Fenster als
   die feste Handybreite von vorher.
*/
@media (min-width: 640px) {
    .rahmen { max-width: 480px; padding: var(--space-section); }
    .blatt {
        align-items: center;
        padding: var(--space-large);
    }
    .blatt > div {
        max-width: 480px;
        max-height: calc(100vh - 64px);
        border: 1px solid var(--kante-stark);
        border-radius: var(--radius-hero);
        padding: var(--space-section);
        box-shadow: 0 24px 60px rgba(0, 0, 0, 0.75), 0 0 1px 1px var(--kante-klar), inset 0 1px 0 rgba(255, 255, 255, 0.16);
        animation: blatt-dialog-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);
    }
    .blatt-griff {
        display: none;
    }
}

@media (min-width: 900px) {
    .rahmen { max-width: 580px; }
    .blatt > div { max-width: 540px; }
}

@media (min-width: 1280px) {
    .rahmen { max-width: 640px; }
    .blatt > div { max-width: 580px; }
}

/*
   **Die Bühne einer laufenden Runde darf breiter werden als ein Formular.**
   Einladung, Schreiben, Karte und Zeitstrahl sind keine Fließtexte, die eine
   Zeilenlänge einhalten müssen – Kartenraster, Spielerliste und Ticket tragen
   mehr Breite gut. `.breit` sitzt am selben `.rahmen`, den `ansicht.js` für
   genau diese Bildschirme zusätzlich vergibt (siehe `zeichneAlles`); Start
   und Beitreten bleiben bei der schmaleren Stufe – zwei große Knöpfe mittig
   im Fenster wirken breitgezogen eher verloren als geräumig.
*/
@media (min-width: 900px) {
    .rahmen.breit { max-width: 720px; }
}

@media (min-width: 1280px) {
    .rahmen.breit { max-width: 860px; }
}

/*
   **Der Einladen-Bildschirm steht in zwei Spalten und braucht dafür Platz.**
   In 860 px bleiben der Marke keine 400 – QR-Bild und Ziffern rücken dann
   übereinander, und der halbe Bildschirm bleibt leerer Verlauf. `ansicht.js`
   vergibt `.weit` nur in der Einladephase.
*/
@media (min-width: 1100px) {
    .rahmen.breit.weit { max-width: 980px; }
}

@media (min-width: 1440px) {
    .rahmen.breit.weit { max-width: 1120px; }
}

/*
   **Die Fragekarten des Einrichtens stehen untereinander – in der Reihenfolge
   der Apps** (16.09.2026): Wer darf abhaken → Wie entstehen die Teams →
   Kartengröße → Teams → Ende. Jede Frage baut auf der davor auf; das Teamfeld
   erscheint erst, wenn die Teambildung beantwortet ist.

   Bis dahin standen sie ab 900 px in zwei, ab 1200 px in drei Spalten, dicht
   gepackt (`grid-auto-flow: dense`). Das sparte Höhe, ergab aber ein
   Zickzack: das Teamfeld neben den Fragen, der Stichtag in der Lücke links
   daneben, die Kartengröße als schmale Kachel rechts oben. Eine Spalte in
   Formularbreite liest sich dagegen wie in der App von oben nach unten – und
   „Weiter" steht, wo man am Ende ankommt.
*/
@media (min-width: 900px) {
    .rahmen.breit.einrichten { max-width: 680px; }
}

/*
   **Am Handy bleiben QR und Ziffern nebeneinander, nur kleiner** – so wie in
   der App. Ohne diese Stufe passt das 168er Bild nicht neben die Ziffern,
   bricht darüber und schiebt allein schon eine halbe Bildschirmhöhe.
*/
@media (max-width: 560px) {
    .marke-qr-box { width: 124px; height: 124px; padding: 6px; }
    .marke-details { flex: 1 1 140px; }
}

@keyframes wackel {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-3px); }
    45% { transform: translateX(3px); }
    70% { transform: translateX(-2px); }
}

@keyframes einblenden {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}

/* ── Wahlfelder (Spielfeld & Teambildung) ─────────────────── */

.wahlfeld {
    display: flex;
    align-items: center;
    gap: var(--space-medium);
    padding: var(--space-small) var(--space-medium);
    border-radius: var(--radius-medium);
    border: 1px solid var(--kante-klar);
    background: transparent;
    cursor: pointer;
    text-align: left;
    transition: all 0.15s ease;
    width: 100%;
    box-sizing: border-box;
}

.wahlfeld:active { transform: scale(0.985); }

.wahlfeld.gewaehlt {
    background: color-mix(in srgb, var(--pink) 14%, transparent);
    border-color: color-mix(in srgb, var(--pink) 50%, transparent);
}

.wahlfeld-bild {
    flex: none;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
}

.wahlfeld-titel {
    font: var(--font-title);
    font-size: 15px;
    font-weight: 700;
    color: var(--ink);
}

.wahlfeld.gewaehlt .wahlfeld-titel {
    color: var(--pink);
}

.wahlfeld-zeile {
    font: var(--font-micro);
    color: var(--ink-soft);
    margin-top: 1px;
}

/* ── Einrichten: Frage-Kopf, Hinweiszeile, Fußhinweis ──────── */
/*
   Gegenstück zu `FrageKopf`, `hinweisZeile` und `fussHinweis` in der App
   (16.09.2026). **Das Sinnbild ist leise, nicht bunt** – es findet die Karte beim
   Überfliegen; eine Farbe sagt in dieser App schon etwas (pink: dran, türkis:
   erreicht) und gehört nicht hierher. **Eine feste Breite je Sinnbild**, sonst
   begänne jede Frage an einer anderen Stelle.
*/

.frage-kopf {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.frage-kopf-zeile {
    display: flex;
    align-items: center;
    gap: var(--space-small);
    min-width: 0;
}

.frage-kopf-zeile h3 { flex: 1 1 auto; min-width: 0; }

.frage-kopf-symbol {
    flex: none;
    width: 28px;
    display: inline-flex;
    align-items: center;
    color: var(--ink-soft);
}

.frage-kopf-hinweis {
    font: var(--font-micro);
    color: var(--ink-soft);
}

.hinweis-zeile {
    display: flex;
    align-items: baseline;
    gap: var(--space-tight);
    font: var(--font-micro);
    color: var(--ink-soft);
}

.hinweis-zeile-symbol {
    flex: none;
    display: inline-flex;
    align-self: center;
}

.teilnehmer-marke {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 9px;
    border-radius: 999px;
    background: rgba(var(--veil-basis), 0.10);
    border: 1px solid var(--kante-fein);
    font: var(--font-micro);
    font-weight: 600;
    color: var(--ink-soft);
    white-space: nowrap;
}

.teilnehmer-marke-symbol { display: inline-flex; }
.teilnehmer-marke-symbol svg { width: 12px; height: 12px; }

/*
   **Eine kleine Kapsel, kein Streifen** (Nutzer, 16.09.2026). Solange „Weiter"
   nicht geht, sagt sie, was fehlt – und schwebt dabei unten über dem Inhalt,
   statt einen Streifen zu belegen. `sticky` hält sie am Fensterrand, solange die
   Seite länger ist als das Fenster; ist sie kürzer, steht sie am Ende. Der
   eigene Grund hält den Satz lesbar, wenn Inhalt darunter durchrollt.
*/
.fuss-hinweis {
    position: sticky;
    bottom: max(var(--space-medium), env(safe-area-inset-bottom));
    z-index: 2;
    align-self: center;
    display: flex;
    align-items: baseline;
    gap: var(--space-tight);
    max-width: 100%;
    box-sizing: border-box;
    padding: var(--space-tight) var(--space-medium);
    border-radius: 999px;
    background: color-mix(in srgb, var(--ground) 94%, transparent);
    border: 1px solid var(--kante-klar);
    font: var(--font-support);
    color: var(--ink-soft);
    text-align: center;
}

.fuss-hinweis-symbol { flex: none; display: inline-flex; align-self: center; }
.fuss-hinweis-symbol svg { width: 15px; height: 15px; }

.dauer-felder { font: var(--font-micro); color: var(--ink-soft); text-align: center; }

/* ── Das Teamfeld ────────────────────────────────────────── */
/*
   Gegenstück zu `teamWahl` in `GameHubPhases.swift`: eine Karte für alles, was
   an der Teamzahl hängt – Zahl, Vorrat, Teams, Schreibarbeit. Bis zum 16.09.2026
   standen hier ein Team-Baukasten mit Ziel-Kästen und eine eigene Namenskarte.
*/

.team-feld { gap: var(--space-medium); }

/* **Beschriftung und Zahl in einer Zeile** – passt beides nicht nebeneinander,
   rutscht das Feld darunter, statt die Worte abzuschneiden. */
.teamzahl-zeile {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-small);
}

.teamzahl-beschriftung {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.teamzahl-frage { font: var(--font-label); color: var(--ink); }
.teamzahl-groesse { font: var(--font-micro); color: var(--ink-soft); }

.teamzahl-wahl {
    display: inline-flex;
    align-items: stretch;
    min-height: 44px;
    border-radius: var(--radius-small);
    background: rgba(var(--veil-basis), 0.08);
    border: 1px solid var(--kante-klar);
    overflow: hidden;
}

.teamzahl-wahl.nur-anzeige { padding: 0 var(--space-medium); align-items: center; }

.teamzahl-schritt {
    appearance: none;
    width: 42px;
    border: none;
    background: none;
    color: var(--ink);
    display: grid;
    place-items: center;
}

.teamzahl-schritt svg { width: 15px; height: 15px; }
.teamzahl-schritt:disabled { color: var(--ink-soft); opacity: 0.35; cursor: default; }

@media (hover: hover) {
    .teamzahl-schritt:hover:not(:disabled) { background: rgba(var(--veil-basis), 0.06); }
}

/* **Ein Klick auf die Zahl öffnet alle Möglichkeiten.** Das `<select>` liegt
   unsichtbar über Zahl und Pfeilen – sichtbar bleibt die große Zahl, die Liste
   bringt der Browser. */
.teamzahl-mitte {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 0 var(--space-small);
    border-left: 1px solid var(--kante-fein);
    border-right: 1px solid var(--kante-fein);
    cursor: pointer;
}

.teamzahl-mitte:focus-within { box-shadow: inset 0 0 0 2px var(--cyan); }

.teamzahl-zahl {
    min-width: 30px;
    text-align: center;
    font: 800 22px var(--slab);
    color: var(--pink);
    font-variant-numeric: tabular-nums;
}

.teamzahl-pfeile { display: inline-flex; color: var(--ink-soft); }

.teamzahl-liste {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    font-size: 16px;
}

/* ── Der Vorrat: gestrichelte Ablage mit Überschrift ── */
.team-vorrat {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
    padding: var(--space-small);
    border-radius: var(--radius-small);
    background: rgba(var(--veil-basis), 0.05);
    border: 1px dashed var(--kante-klar);
}

.team-vorrat-kopf {
    display: flex;
    align-items: center;
    gap: var(--space-tight);
}

.team-vorrat-kopf h4 { font: var(--font-label); color: var(--ink); }

.team-vorrat-zaehler {
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(var(--veil-basis), 0.14);
    font: var(--font-micro);
    font-weight: 700;
    color: var(--ink-soft);
    font-variant-numeric: tabular-nums;
}

/* ── Die Teams ── */
.team-liste {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
}

.abschnitt-titel {
    font: var(--font-micro);
    color: var(--ink-faint);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.team-zeile {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
    padding: var(--space-small);
    border-radius: var(--radius-small);
    background: rgba(var(--veil-basis), 0.05);
    border: 1px solid var(--kante-klar);
    transition: border-color 0.18s ease, background 0.18s ease;
}

/* Eine Zeile, über der gerade jemand hängt – die Rückmeldung zum Ziehen. */
.team-zeile.darueber {
    background: color-mix(in srgb, var(--pink) 14%, transparent);
    border-color: color-mix(in srgb, var(--pink) 70%, transparent);
    box-shadow: inset 0 0 0 0.5px color-mix(in srgb, var(--pink) 70%, transparent);
}

.team-zeile-kopf {
    appearance: none;
    display: flex;
    align-items: center;
    gap: var(--space-medium);
    width: 100%;
    padding: 0;
    border: none;
    background: none;
    text-align: left;
    color: inherit;
}

button.team-zeile-kopf { cursor: pointer; }

.team-zeile-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.team-zeile-name {
    font: var(--font-rowtitle);
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.team-zeile-unter { font: var(--font-micro); color: var(--ink-soft); }

.team-zeile-stift {
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: var(--cyan);
    background: color-mix(in srgb, var(--cyan) 12%, transparent);
}

.team-zeile-stift svg { width: 13px; height: 13px; }

/*
   **Das Wappen: Farbe des Teams in Fläche und Kante, die Ziffer in Tinte**
   (16.09.2026) – dieselben Anteile wie `TeamWappen` in der App (0,18 und 0,8).
   Die Palette ist für Flächen gemacht, nicht für Schrift.
*/
.team-wappen {
    flex: none;
    width: 36px;
    height: 36px;
    box-sizing: border-box;
    border-radius: var(--radius-small);
    background: color-mix(in srgb, var(--team-farbe, var(--violet)) 18%, transparent);
    border: 1px solid color-mix(in srgb, var(--team-farbe, var(--violet)) 80%, transparent);
    display: grid;
    place-items: center;
    overflow: hidden;
    color: var(--ink);
}

.team-wappen img { width: 100%; height: 100%; object-fit: cover; }
.team-wappen-sinnbild { font-size: 19px; line-height: 1; }
.team-wappen-ziffer { font: 800 15px var(--slab); color: var(--ink); }

.team-wappen.gross { width: 52px; height: 52px; border-radius: var(--radius-medium); }
.team-wappen.gross .team-wappen-sinnbild { font-size: 27px; }
.team-wappen.gross .team-wappen-ziffer { font-size: 22px; }

.team-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-tight);
}

.team-chip {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--spieler-farbe, var(--cyan)) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--spieler-farbe, var(--cyan)) 48%, transparent);
    font: var(--font-micro);
    font-weight: 500;
    color: var(--ink);
    cursor: pointer;
    transition: transform 0.12s ease, opacity 0.15s ease;
    box-sizing: border-box;
}

.team-chip:active {
    transform: scale(0.95);
}

.team-chip .punkt {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--spieler-farbe, var(--cyan));
    flex: none;
}

.team-chip .name {
    color: var(--ink);
    line-height: 1;
}

.team-chip .entfernen {
    padding-left: 2px;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    color: var(--ink-faint);
    transition: color 0.15s ease;
}

.team-chip:hover .entfernen { color: var(--pink); }

/* Eine Marke, die man anklicken kann, sagt das auch. Ohne diesen Unterschied
   sieht eine Marke beim Zusehen aus wie eine beim Verteilen. */
.team-chip:not(.tippbar) { cursor: default; }
.team-chip.tippbar:hover {
    background: color-mix(in srgb, var(--spieler-farbe, var(--cyan)) 24%, transparent);
    border-color: color-mix(in srgb, var(--spieler-farbe, var(--cyan)) 72%, transparent);
}
.team-chip[draggable="true"] { cursor: grab; }
.team-chip[draggable="true"]:active { cursor: grabbing; }

/* ── Handlungen unter den Teams ── */
.team-aktionen {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-tight) var(--space-large);
}

.aktion-knopf {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: var(--space-tight);
    min-height: 36px;
    padding: 0;
    border: none;
    background: none;
    font: var(--font-support);
    font-weight: 600;
    color: var(--cyan);
}

.aktion-knopf-symbol { display: inline-flex; }

@media (hover: hover) {
    .aktion-knopf:hover { opacity: 0.8; }
}

/* **Was die Wahl kostet, direkt unter der Wahl.** */
.schreibarbeit {
    display: flex;
    align-items: baseline;
    gap: var(--space-small);
    padding-top: var(--space-small);
    border-top: 1px solid var(--kante-fein);
}

.schreibarbeit-zahl { font: 800 26px var(--slab); color: var(--ink); }
.schreibarbeit-text { font: var(--font-support); color: var(--ink-soft); }

/* ── Die Blätter des Teamfelds ── */
.team-auswahl {
    display: flex;
    flex-direction: column;
    gap: var(--space-tight);
}

.team-auswahl-knopf {
    appearance: none;
    display: flex;
    align-items: center;
    gap: var(--space-medium);
    width: 100%;
    min-height: 52px;
    padding: var(--space-tight) var(--space-medium);
    border-radius: var(--radius-medium);
    border: 1px solid var(--kante-klar);
    background: rgba(var(--veil-basis), 0.04);
    font: var(--font-label);
    color: var(--ink);
    text-align: left;
}

@media (hover: hover) {
    .team-auswahl-knopf:hover { border-color: var(--cyan); background: rgba(var(--veil-basis), 0.08); }
}

.teamschild-block {
    display: flex;
    flex-direction: column;
    gap: var(--space-small);
}

.teamschild-namenszeile {
    display: flex;
    align-items: center;
    gap: var(--space-small);
}

.teamschild-namenszeile .feld { flex: 1 1 auto; min-width: 0; }

.teamschild-sinnbild { max-width: 160px; }

/* ── Karte Flug: Kopfleiste, Legende & Feedback ──────────── */

.karten-kopf-leiste {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 4px;
    margin-bottom: 8px;
    width: 100%;
}

.karten-kopf-punkt {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--du-farbe, var(--pink));
    flex: none;
}

.karten-kopf-titel {
    font: var(--font-headline);
    font-size: 15px;
    font-weight: 700;
    color: var(--ink);
    white-space: nowrap;
}

.karten-kopf-trenner {
    color: var(--ink-faint);
    font-size: 11px;
}

.karten-kopf-zusatz {
    color: var(--ink-soft);
    font-size: 11px;
    font-weight: 500;
    white-space: nowrap;
}

.umschalt-kapsel {
    appearance: none;
    border: 0;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 5px 11px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--cyan) 14%, transparent);
    color: var(--cyan);
    font: var(--font-support);
    font-size: 11px;
    font-weight: 600;
    margin-left: auto;
    white-space: nowrap;
    transition: all 0.15s ease;
}

.umschalt-kapsel:active { transform: scale(0.96); }

/* Behält ihren Platz, wenn sie verblasst – `ansicht.js` schaltet nur die
   Deckkraft; ein Zusammenklappen schöbe das Raster darunter mitten im
   Faltungs-Flug nach oben. */
.legende-huelle {
    padding: 0 4px;
    margin-top: 6px;
    box-sizing: border-box;
    transition: opacity 0.26s ease;
}

.legende-liste {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.legende-kapsel {
    appearance: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 5px 9px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--violet) 8%, transparent);
    border: 1px solid var(--kante-fein);
    font: var(--font-support);
    font-size: 11px;
    transition: all 0.15s ease;
}

.legende-kapsel.aktiv {
    background: color-mix(in srgb, var(--spieler-farbe, var(--cyan)) 20%, transparent);
    border-color: var(--spieler-farbe, var(--cyan));
}

.legende-kapsel .punkt {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--spieler-farbe, var(--cyan));
    flex: none;
}

.legende-kapsel .name {
    color: var(--ink-soft);
    font-weight: 400;
}

.legende-kapsel.ist-ich .name {
    color: var(--ink);
    font-weight: 700;
}

.legende-kapsel .zahl {
    color: var(--ink-faint);
    font-weight: 500;
}

.karten-fuss {
    padding: 16px 12px 0;
    text-align: center;
    font: var(--font-support);
    font-size: 13px;
    color: var(--ink-faint);
    line-height: 1.5;
}

.karten-hinweis-toast {
    margin: 14px 4px 0;
    padding: 10px 14px;
    border-radius: var(--radius-medium);
    text-align: center;
    background: color-mix(in srgb, var(--hinweis-farbe, var(--pink)) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--hinweis-farbe, var(--pink)) 50%, transparent);
    font: var(--font-support);
    font-size: 12px;
    font-weight: 500;
    color: var(--ink);
    animation: einblenden 0.22s ease;
}

.karten-mulde {
    transition: transform 0.15s ease, opacity 0.3s ease;
}

.karten-mulde:focus-visible {
    outline: 2px solid var(--cyan);
    outline-offset: 3px;
    border-radius: 14px;
}

@media (hover: hover) {
    .karten-mulde[tabindex="0"]:hover {
        transform: translateY(-2px);
    }
}

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

/* ── Rechtstexte ────────────────────────────────────────────────────────────
   Die Fußzeile mit Datenschutz, Nutzungsbedingungen und Impressum. Sie steht
   fest in `index.html` und nicht in einem Modul – siehe die Begründung dort. */
.rechtsfuss {
    max-width: 42rem;
    margin: 2.5rem auto 3rem;
    padding: 0 1.25rem;
    text-align: center;
    font-size: .85rem;
    opacity: .6;
}

.rechtsfuss a {
    color: inherit;
    margin: 0 .6rem;
    display: inline-block;
    line-height: 2;
}

/* ── Der Rundenchat ──────────────────────────────────────────────
   Gegenstück zu `Views/GameTabs/ChatTab.swift`: eigene Nachrichten
   rechts und getönt, fremde links auf ruhiger Fläche. Die
   Unterscheidung muss ohne Lesen funktionieren. */

/* **Der Zähler sitzt über der rechten Schulter des Reiters, nicht daneben.**
   Neben der Beschriftung las er sich wie ein zweiter Teil des Namens
   („Chat 3"); in der Ecke ist er das, was er überall sonst auch ist. Absolut
   gesetzt kostet er zudem keine Breite – die Reiter bleiben gleich breit, ob
   eine Zahl dasteht oder nicht. */
.chat-zahl {
    position: absolute;
    top: 3px;
    right: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 17px;
    height: 17px;
    padding: 0 5px;
    border-radius: 999px;
    /* **Weiß auf tieferem Rosa.** `--marke-ink` ist die Schrift der
       Siegfeld-Marke (Petrol) und stand hier falsch – auf Rosa gemessen
       1,9:1. Weiß auf `--pink` misst 3,4:1 und bleibt unter den 4,5 für
       kleine fette Schrift; eine Spur abgedunkelt trägt dieselbe Marke die
       weiße Ziffer mit 5,6:1. */
    background: #bf2e5e;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
}

/* **Der Verlauf rollt für sich – und setzt unten auf, ohne oben etwas zu
   verstecken.** Bis zum 05.09.2026 stand hier `justify-content: flex-end` am
   rollenden Kasten: Wenige Nachrichten saßen damit am Fuß, aber sobald mehr
   hineinkamen, als Platz war, lag der Überlauf *über* dem oberen Rand – und
   dorthin rollt kein Browser. Man kam an die älteren Nachrichten nicht mehr
   heran. Jetzt schiebt `margin-top: auto` am inneren Kasten die Blasen nach
   unten; der Überlauf bleibt Überlauf und lässt sich rollen. */
.chat-verlauf {
    display: flex;
    flex-direction: column;
    margin: 10px 0 0;
    padding: 4px 2px;
    height: min(58vh, 620px);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--kante-klar) transparent;
}

.chat-verlauf-innen {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

/* **Eine Blase pro Nachricht, und man sieht sie.** Vorher trug sie Fläche und
   Kante aus Variablen, die es nicht gab (`--flaeche`, `--kante`) – sie war
   unsichtbar, und der ausgeblendete Melde-Knopf darunter kostete trotzdem
   seine Zeile: Sechzig Pixel Luft zwischen zwei Sätzen derselben Person.

   **Eine Form für alle** (Wunsch des Nutzers, 05.09.2026): dieselbe Rundung an
   jeder Ecke, ob erste oder Folgenachricht, ob fremd oder eigen – ein
   farbiger Saum an einer Seite brach an den Rundungen ab und sah nach zwei
   Bauarten aus. Die Spielerfarbe steckt stattdessen im Namen, in der Kante
   und als Hauch in der Fläche; eigene Blasen tragen Rosa auf dieselbe Weise
   und stehen rechts. Folgenachrichten derselben Person rücken eng zusammen,
   ein Personenwechsel bekommt Luft. */
/* **Jede Blase trägt die Farbe ihres Autors – auch die eigene.** Bis zum
   07.09.2026 war `.meine` rosa getönt; dieselbe Nachricht sah damit beim
   Schreiber anders aus als bei allen anderen, und wer selbst das Rot der
   Palette trägt, war von den eigenen Blasen der anderen kaum zu unterscheiden.
   Farbe ist die Person, Seite ist der Absender – Begründung in
   `ios/Typical/Views/GameTabs/ChatTab.swift`. */
/* **Das Rezept einer Chat-Blase – die Zahlen stehen nicht hier.** Fläche und
   Kante tragen die Farbe des Autors (`--autor-farbe`, gesetzt in `ansicht.js`),
   nur unterschiedlich stark. Dieselben Werte gelten in `ChatTab.swift` und
   `ChatTab.kt`; Quelle für alle drei ist `shared/design-tokens/chat-blase.txt`.
   Bis zum 07.09.2026 standen sie dreimal im Code – und die Web-Fassung trug
   9 % und 38 statt 10 % und 35, ohne dass es jemandem auffiel. */
/* erzeugt aus shared/design-tokens/chat-blase.txt – nicht von Hand ändern. */
/* Erzeugen mit: python3 devtools/baue-design-tokens.py */
:root {
    /* Fläche der Blase, in der Farbe des Autors. */
    --chat-blase-flaeche: 10%;
    /* Kante der Blase, dieselbe Farbe, kräftiger. */
    --chat-blase-kante: 35%;
    /* Strichstärke dieser Kante. */
    --chat-blase-kantenbreite: 1px;
}
/* Ende erzeugter Block */

/* **Rundung und Polster kommen aus dem Maßsystem, nicht aus der Hand.**
   Bis zum 07.09.2026 standen hier 14px und `7px 12px 6px` – die Apps setzen
   an derselben Blase `Theme.Radius.medium` und `Theme.Space.medium/small`.
   Die Zahlen dafür stehen in `tokens.css` längst (16 / 14 / 10); die Blase
   war die einzige Stelle, die daran vorbeigriff. Entschieden ist damit
   nichts Neues – es gilt, was in drei Dateien ohnehin schon stand. */
.chat-blase {
    position: relative;
    align-self: flex-start;
    max-width: min(78%, 34rem);
    padding: var(--space-small) var(--space-medium);
    border: var(--chat-blase-kantenbreite) solid
        color-mix(in srgb, var(--autor-farbe, var(--ink-faint)) var(--chat-blase-kante), transparent);
    border-radius: var(--radius-medium);
    background: color-mix(in srgb, var(--autor-farbe, var(--ink-faint)) var(--chat-blase-flaeche), transparent);
}

.chat-blase.kopf:not(:first-child) {
    margin-top: 12px;
}

.chat-blase.meine { align-self: flex-end; }

.chat-name {
    display: block;
    margin: 0 0 2px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--autor-farbe, var(--ink-soft));
    font: inherit;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.2px;
    cursor: pointer;
}

.chat-name:hover { text-decoration: underline; }

/* Text und Uhrzeit in einer Zeile – die Uhrzeit hängt sich rechts unten an
   und bricht mit, wenn der Satz länger ist als die Blase. */
.chat-text {
    margin: 0;
    overflow-wrap: anywhere;
    font-size: 14.5px;
    line-height: 1.35;
}

.chat-uhr {
    display: inline-block;
    margin-left: 8px;
    color: var(--ink-faint);
    font-size: 10.5px;
    font-weight: 400;
    vertical-align: baseline;
    white-space: nowrap;
}

/* **Melden hängt an der Nachricht, nicht an einem Knopf daneben.** Sichtbar
   wird es erst beim Überfahren oder mit der Tastatur – aber es ist immer
   vorhanden, nie `display: none`: Ein Knopf, den es für Hilfsmittel nicht
   gibt, erfüllt die Meldepflicht nicht. Absolut gesetzt, damit er unsichtbar
   keinen Platz nimmt. */
.chat-melden {
    position: absolute;
    right: 10px;
    top: -9px;
    padding: 1px 7px;
    border: 1px solid var(--kante-fein);
    border-radius: 999px;
    background: var(--schwebe-grund, #1a1628);
    color: var(--ink-soft);
    font: inherit;
    font-size: 10.5px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s ease;
}

.chat-blase:hover .chat-melden,
.chat-melden:focus-visible { opacity: 1; }

.chat-leer { padding: 32px 0; text-align: center; }

.chat-hinweis {
    margin: 8px 0 0;
    color: var(--amber, #f0a020);
    font-size: 13px;
}

.chat-zeile {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-top: 12px;
}

.chat-zeile .feld { flex: 1; }

@media (prefers-reduced-motion: reduce) {
    .chat-melden { transition: none; }
}

/*
   **Ein niedriges Fenster bekommt einen engeren Takt.**

   Zwei Spalten allein reichen nicht: Auf einem 14-Zoll-Notebook bleiben nach
   Menü- und Adressleiste rund 830 px Fensterhöhe, und der Einladen-Bildschirm
   lief unten heraus – man musste rollen, um „Weiter" zu sehen, also genau die
   Hauptaktion. Statt einer festen Skalierung (die Schrift kaputtmacht) rückt
   hier alles zusammen, was Luft ist: Ränder, Abstände, das QR-Bild, der
   Rechtsfuß. Die Schriftgrößen bleiben, wie sie sind – bis auf Sinnbild und
   Rundentitel, die als Schmuck den meisten Platz kosten.

   Gilt nur auf dem Rechner (`min-width: 900px`): Ein Handy im Querformat ist
   niedrig, dort ist Rollen aber der übliche Weg, und die Marke steht in einer
   Spalte.
*/
@media (min-width: 900px) and (max-height: 900px) {
    .rahmen {
        padding-top: var(--space-medium);
        padding-bottom: var(--space-medium);
        gap: var(--space-medium);
    }
    .einladen-buehne,
    .einladen-spalte,
    .aufbau-buehne { gap: var(--space-medium); }
    .zeitstrahl { margin-bottom: 0; }
    .garderobenmarke { padding: var(--space-medium); }
    .marke-emoji { font-size: 26px; }
    .marke-titel { font-size: 20px; }
    .marke-perforation { margin-block: var(--space-small); }
    .marke-qr-box { width: 140px; height: 140px; }
    .karte { padding: var(--space-medium); gap: var(--space-small); }
    /* Der Kopf trägt Zeitstrahl und Frage – zwei Zeilen, die keine
       Sektionsränder brauchen, wenn die Höhe knapp ist. */
    .phasenkopf { padding: var(--space-small) var(--space-medium); }
    .wahlfeld { padding: var(--space-small); }
    /* Vier Namen sind der Regelfall einer Gruppenrunde – vier Zeilen à 56 px
       sind hier die größte einzelne Fläche. Der Avatar bleibt 40 px, die
       Zeile verliert nur ihre Luft. */
    .liste { gap: var(--space-tight); }
    .zeile { min-height: 48px; padding: var(--space-tight) var(--space-small); }
    /* Die Rastervorschau ist die höchste Kachel der Dauer-Wahl – ihre
       Aussage ist die Diagonale, nicht die Feldgröße. */
    .dauer-kachel { padding: var(--space-small); gap: var(--space-tight); }
    .raster-vorschau { grid-template-columns: repeat(var(--raster-spalten), 15px); gap: 4px; }
    .raster-vorschau.eng { grid-template-columns: repeat(var(--raster-spalten), 12px); }
    .rechtsfuss { margin: var(--space-large) auto var(--space-medium); }
}

/* ── Das Werbeblatt (js/werbung.js) ──────────────────────────────
   Gegenstück zu `Views/WerbeBlatt.swift`: Vollbild, nicht als `.blatt` –
   ein Blatt lässt sich wegtippen, eine Anzeige, die man wegwischen kann,
   ist keine. Die Kennzeichnung steht oben und bleibt stehen (§ 5a Abs. 4
   UWG). Die Fläche in der Mitte trägt den Anzeigenblock oder, als
   Attrappe, den Ring mit dem Zähler. */

.werbeblatt {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ground);
    padding: var(--space-screen);
    padding-top: max(var(--space-screen), env(safe-area-inset-top));
    padding-bottom: max(var(--space-screen), env(safe-area-inset-bottom));
    box-sizing: border-box;
    animation: blatt-fade 0.2s ease-out;
}

.werbe-inhalt {
    width: 100%;
    max-width: 480px;
    height: 100%;
    max-height: 760px;
    display: flex;
    flex-direction: column;
    gap: var(--space-large);
}

.werbe-kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-small);
    padding: var(--space-small) var(--space-medium);
    border-radius: var(--radius-medium);
    background: rgba(var(--veil-basis), 0.08);
    border: 1px solid var(--kante-klar);
}

.werbe-kennzeichnung {
    font: var(--font-headline);
    color: var(--ink);
}

.werbe-restzeit {
    font: var(--font-support);
    font-variant-numeric: tabular-nums;
    color: var(--ink-soft);
}

.werbe-flaeche {
    flex: 1;
    min-height: 280px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-large);
    background: rgba(var(--veil-basis), 0.10);
    border: 1px solid var(--kante-klar);
    overflow: hidden;
}

.werbe-flaeche > ins.adsbygoogle {
    width: 100%;
    min-height: 250px;
}

.werbe-ring {
    --anteil: 0;
    width: 132px;
    height: 132px;
    position: relative;
    display: grid;
    place-items: center;
    animation: werbe-puls 1s ease-in-out infinite alternate;
}

/* Der Bogen: ein Kegelverlauf, dem eine Maske die Mitte nimmt – so bleibt
   ein 6 px breiter Ring, der sich mit `--anteil` füllt. Die Zahl liegt
   daneben, nicht darin: Die Maske gilt für den Bogen allein. */
.werbe-ring-bogen {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: conic-gradient(var(--cyan) calc(var(--anteil) * 360deg), var(--kante-fein) 0);
    -webkit-mask: radial-gradient(circle, transparent 60px, #000 61px);
    mask: radial-gradient(circle, transparent 60px, #000 61px);
    transition: background 1s linear;
}

.werbe-zahl {
    position: relative;
    font: 800 34px var(--slab);
    font-variant-numeric: tabular-nums;
    color: var(--ink);
}

@keyframes werbe-puls {
    from { transform: scale(1); }
    to { transform: scale(1.03); }
}

@media (prefers-reduced-motion: reduce) {
    .werbe-ring { animation: none; }
}

.werbe-hinweis {
    margin: 0;
    text-align: center;
    font: var(--font-body);
    color: var(--ink-soft);
}

.werbeblatt .knopf:disabled {
    /* Solange der Clip läuft, ist der Knopf da, aber ohne Wirkung – ein
       Knopf, der erst auftaucht, lässt den Bildschirm springen. */
    opacity: 0.35;
}

/* ── Das Banner (js/werbung.js) ──────────────────────────────────
   Nur ab 1280 px, rechts neben der Bühne (`.rahmen` ist dort 640 px
   breit, es bleibt Platz). Auf welchen Bildschirmen es steht, entscheidet
   `ansicht.js` – hier steht nur, wie. */

.werbe-banner {
    display: none;
}

@media (min-width: 1280px) {
    .werbe-banner {
        position: fixed;
        right: max(24px, calc((100vw - 640px) / 2 - 300px - 48px));
        top: 50%;
        transform: translateY(-50%);
        z-index: 1;
        width: 300px;
        display: flex;
        flex-direction: column;
        gap: var(--space-small);
    }
    .werbe-banner[hidden] { display: none; }
    .werbe-banner .werbe-kennzeichnung {
        font: var(--font-support);
        color: var(--ink-faint);
        text-transform: uppercase;
        letter-spacing: 0.08em;
    }
    .werbe-banner > ins.adsbygoogle {
        border-radius: var(--radius-medium);
        overflow: hidden;
    }
}
