/* Spieltisch, Spielerkarten, Rollenkarte, Abstimmung, Chat, Sprachchat. */

/* ------------------------------------------------------------- Phasenkopf */

.phase {
    display: flex;
    align-items: center;
    gap: var(--s4);
    padding: var(--s4);
    border-radius: var(--r-gross);
    background: var(--flaeche);
    border: 1px solid var(--rand);
    margin-bottom: var(--s5);
}
.phase--nacht {
    background: linear-gradient(150deg, #141a2c, var(--flaeche));
    border-color: color-mix(in srgb, var(--mond) 25%, var(--rand));
}
.phase--tag {
    background: linear-gradient(150deg, #232a3d, var(--flaeche));
}
.phase--ende { border-color: var(--mond); }

.phase__text   { flex: 1; min-width: 0; }
.phase__titel  { font-family: var(--schrift-display); font-weight: 700; font-size: var(--f-gross); margin: 0; }
.phase__unter  { color: var(--text-leise); font-size: var(--f-klein); margin: 0; }

.uhr {
    font-variant-numeric: tabular-nums;
    font-size: var(--f-titel);
    font-weight: 700;
    color: var(--mond);
    flex: none;
}
.uhr--knapp { color: var(--blut-schrift); animation: puls 1s ease-in-out infinite; }
@keyframes puls { 50% { opacity: .5; } }

/* ------------------------------------------------------------- Erzählung */

/*
 * Der Erzähler während der Nacht. Er beantwortet die Frage, die sonst alle
 * beschäftigt: Läuft das Spiel noch, oder hängt es?
 */
.erzaehlung {
    display: flex;
    align-items: center;
    gap: var(--s4);
    padding: var(--s4) var(--s5);
    margin-bottom: var(--s5);
    border-radius: var(--r-gross);
    border: 1px solid color-mix(in srgb, var(--mond) 30%, var(--rand));
    background: linear-gradient(150deg,
                color-mix(in srgb, var(--mond) 8%, var(--flaeche)), var(--flaeche));
    animation: erzaehlung-auf var(--zeit) var(--kurve);
}
@keyframes erzaehlung-auf {
    from { opacity: 0; transform: translateY(-.5rem); }
    to   { opacity: 1; transform: none; }
}


.erzaehlung__text {
    flex: 1;
    margin: 0;
    font-size: var(--f-gross);
    font-style: italic;
    color: var(--text);
    line-height: 1.4;
}

/*
 * Der Sprecherzettel: „Jeder sein Gerät", nur auf dem lauten Gerät. Eine
 * eigene Karte im Fluss der Seite — kein Gatter aus aufbau.css greift
 * hier, der Text steht unabhängig vom Profilschalter „Mitlesen".
 */
.sprecherzettel {
    padding: var(--s3) var(--s5);
    margin-bottom: var(--s4);
    border-radius: var(--r-gross);
    border: 1px solid color-mix(in srgb, var(--mond) 45%, var(--rand));
    border-left: 3px solid var(--mond);
    background: color-mix(in srgb, var(--mond) 6%, var(--flaeche));
}
.sprecherzettel__wer {
    margin: 0 0 var(--s1);
    font-size: var(--f-klein);
    color: var(--text-still);
}
.sprecherzettel__text {
    margin: 0;
    font-size: var(--f-gross);
    font-style: italic;
    color: var(--text);
    line-height: 1.4;
}

@media (max-width: 34rem) {
    .erzaehlung { padding: var(--s3) var(--s4); gap: var(--s3); }
    .erzaehlung__text { font-size: var(--f-normal); }
}

/* ------------------------------------------------------------- Spielertisch */

.tisch {
    display: grid;
    gap: var(--s3);
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}

.spieler {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s2);
    padding: var(--s2) var(--s2) var(--s3);
    border-radius: var(--r-mittel);
    background: var(--flaeche);
    border: 2px solid var(--rand);
    text-align: center;
    cursor: default;
    transition: border-color var(--zeit-kurz) var(--kurve),
                transform var(--zeit-kurz) var(--kurve);
}
.spieler--waehlbar { cursor: pointer; }
@media (hover: hover) {
    .spieler--waehlbar:hover { border-color: var(--mond); transform: translateY(-2px); }
}

.spieler--gewaehlt {
    border-color: var(--mond);
    background: color-mix(in srgb, var(--mond) 12%, var(--flaeche));
}
.spieler--ich { border-color: var(--dorf); }

/* Das Rudel am Tisch markiert (17.10.2026): orange, solange es noch nicht
   einig ist — blutrot und eingeloggt, sobald alle dieselbe Person haben. */
.spieler--wolfswahl {
    border-color: var(--wolfswahl);
    background: color-mix(in srgb, var(--wolfswahl) 18%, var(--flaeche));
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--wolfswahl) 55%, transparent);
}
.spieler--wolfsopfer {
    border-color: var(--blut);
    background: color-mix(in srgb, var(--blut) 22%, var(--flaeche));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--blut) 60%, transparent);
}
.spieler__wolfswahl {
    font-size: var(--f-winzig);
    font-weight: 700;
    color: var(--wolfswahl);
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}
.spieler--wolfsopfer .spieler__wolfswahl { color: var(--blut-schrift); }

.spieler--tot {
    opacity: .55;
    filter: grayscale(.7);
}
.spieler--tot .spieler__bild::after {
    content: "✕";
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 1.6rem;
    color: var(--blut);
    background: var(--tot-schleier);
    border-radius: 50%;
}

/* Die Kachel zeigt das Gesicht groß — als Porträt, der Name liegt auf dem
   dunklen unteren Bildrand (die Avatare sind so komponiert). */
.spieler__bild {
    position: relative;
    width: 100%;
    aspect-ratio: 1;
    border-radius: var(--r-klein);
    display: grid;
    place-items: center;
    font-size: 3rem;             /* Emoji-Rückfall in Kachelgröße */
    background: var(--flaeche-hoch);
    border: 1px solid var(--rand-hell);
    overflow: hidden;
}

/* In der Lobby ist das Bild ein Knopf: Es öffnet die Karte des Mitspielers.
   Es soll dabei aussehen wie vorher — nur der Zeiger und ein Ring beim
   Zeigen verraten, dass sich etwas dahinter verbirgt. Am Spieltisch bleibt
   es ein Bild; dort wählt man mit der Kachel sein Ziel. */
.spieler__bild--knopf {
    /* Kein Warten auf einen möglichen Doppeltipp — siehe .knopf. */
    touch-action: manipulation;
    padding: 0;
    color: inherit;
    font-family: inherit;
    cursor: pointer;
    transition: border-color var(--zeit-kurz) var(--kurve),
                transform var(--zeit-kurz) var(--kurve);
}
@media (hover: hover) {
    .spieler__bild--knopf:hover,
    .spieler__bild--knopf:focus-visible { border-color: var(--mond); }
}

.spieler__bild--knopf:active { transform: scale(.97); }

/* Gezeichnete Avatare legen sich über das Emoji; scheitert das Laden,
   räumt sich das Bild ab und das Emoji tritt hervor. */
.sinnbild-traeger {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 100%; height: 100%;
}

/*
 * Der Emoji-Rückfall ist STANDARDMÄSSIG UNSICHTBAR — dieselbe Lösung wie
 * bei den Symbolen (.symbol__zeichen in components.css).
 *
 * Früher lag er einfach unter dem Bild, in der Annahme, das deckende Bild
 * verberge ihn ohnehin. Am Spieltisch stimmt das nicht: Dort wird der Tisch
 * alle sechs Sekunden neu gebaut, und im Augenblick zwischen Einfügen und
 * Zeichnen des frischen Bildes blitzte das Emoji hervor. Genau das war das
 * Flackern der Spielerkacheln.
 *
 * `visibility` und nicht `display: none`: Das Zeichen behält seinen Platz,
 * die Kachel springt beim Umschalten also nicht.
 */
.sinnbild-zeichen { visibility: hidden; }
.sinnbild-zeichen--sichtbar { visibility: visible; }
.sinnbild-bild {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    border-radius: inherit;
}
/* Der Tot-Schleier (✕) muss ÜBER dem Avatarbild liegen. */
.spieler--tot .spieler__bild::after { z-index: 2; border-radius: inherit; }

.spieler__name {
    position: absolute;
    inset: auto 0 0 0;
    z-index: 1;
    padding: var(--s4) var(--s2) var(--s1);
    font-weight: 600;
    font-size: var(--f-klein);
    color: #f2f4fa;
    text-shadow: 0 1px 4px rgba(0, 0, 0, .8);
    background: linear-gradient(180deg, transparent, rgba(6, 8, 14, .78));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.spieler__rolle { font-size: var(--f-winzig); color: var(--text-still); }

.spieler__stimmen {
    position: absolute;
    top: -.5rem; right: -.5rem;
    min-width: 1.6rem; height: 1.6rem;
    padding-inline: .35rem;
    border-radius: var(--r-rund);
    background: var(--blut);
    color: #fff;
    font-size: var(--f-winzig);
    font-weight: 700;
    display: grid;
    place-items: center;
}

/* Der blaue Lautsprecher rückt neben den grünen Haken statt darauf. Beide
   sind reine Anzeige: bereit zum Spiel und bereit zum Reden. */
.spieler__stimmen--stimme {
    right: 1.3rem;
    background: var(--dorf);
}

/* Für wen diese Kachel gestimmt hat — bei offener Abstimmung, mit Namen und
   Pfeil voran. Im Raster eine Zeile unter dem Bild; der Ring stellt sie als
   Plakette unter den Namen (aufbau.css). */
.spieler__wahl {
    font-size: var(--f-winzig);
    color: var(--mond);
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

/* Das Herz der Verliebten: an der eigenen Kachel und an der des Partners,
   nur für die beiden (der Server schickt `lover`/`isLover` sonst niemandem).
   Rechts unten, damit es weder Stimmenzähler noch Rabenzeichen berührt. */
.spieler__herz {
    position: absolute;
    right: -.4rem; bottom: 1.6rem;
    z-index: 2;
    font-size: 1.1rem;
    line-height: 1;
    color: var(--blut);
    text-shadow: 0 1px 4px rgba(0, 0, 0, .8);
    pointer-events: none;
}

/* Das Zeichen des Raben — gegenüber dem Stimmenzähler, damit sich beide
   nicht überdecken, wenn der Gezeichnete auch Stimmen bekommt. */
.spieler__zeichen {
    position: absolute;
    top: -.5rem; left: -.5rem;
    width: 1.6rem; height: 1.6rem;
    border-radius: var(--r-rund);
    background: var(--flaeche-hoch);
    border: 1px solid var(--rand-hell);
    font-size: var(--f-winzig);
    display: grid;
    place-items: center;
}

/*
 * Werwölfe erkennen einander. Diese Markierung erscheint nur dort, wo der
 * Server die Rolle überhaupt mitgeliefert hat — für Dorfbewohner steht in
 * der Antwort schlicht nichts.
 */
.spieler--wolf {
    border-color: color-mix(in srgb, var(--blut) 60%, var(--rand));
    background: linear-gradient(160deg,
                color-mix(in srgb, var(--blut) 14%, var(--flaeche)), var(--flaeche));
}
.spieler--wolf .spieler__rolle { color: var(--blut-schrift); font-weight: 650; }
.spieler--wolf .spieler__bild::before {
    content: "🐺";
    position: absolute;
    left: -.35rem; bottom: -.35rem;
    font-size: .9rem;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6));
}

/* Das Rudel auf der Rollenkarte */
.rudel { display: flex; flex-wrap: wrap; gap: var(--s2); }
.rudel__wolf {
    display: inline-flex;
    align-items: center;
    gap: var(--s1);
    padding: .2em .7em;
    border-radius: var(--r-rund);
    background: color-mix(in srgb, var(--blut) 18%, var(--flaeche));
    border: 1px solid color-mix(in srgb, var(--blut) 50%, transparent);
    font-size: var(--f-klein);
    font-weight: 600;
}
.rudel__wolf--tot { opacity: .5; text-decoration: line-through; }

/* Ein Ring zeigt, wer gerade spricht. */
.spieler--spricht { border-color: var(--gruen); }
.spieler--spricht .spieler__bild {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--gruen) 55%, transparent);
}

/* ------------------------------------------------------------- Rollenkarte */

.rollenkarte {
    position: relative;
    padding: var(--s5);
    border-radius: var(--r-gross);
    background: linear-gradient(155deg, var(--flaeche-hoch), var(--flaeche));
    border: 1px solid var(--rand-hell);
    overflow: hidden;
}
.rollenkarte--wolf {
    background: linear-gradient(155deg, #2a1418, #1b1015);
    border-color: color-mix(in srgb, var(--blut) 50%, transparent);
}
.rollenkarte--dorf {
    border-color: color-mix(in srgb, var(--dorf) 40%, transparent);
}

/* Das Rollenbild als Kartenkopf. Negative Ränder ziehen es über das
   Kartenpolster bis an die Kanten; das untere Drittel der Bilder ist
   von der Generierung her dunkel — dort sitzt der Name. */
.rollenbanner {
    position: relative;
    aspect-ratio: 3 / 2;
    margin: calc(var(--s5) * -1) calc(var(--s5) * -1) var(--s4);
    overflow: hidden;
    display: flex;
    align-items: flex-end;
    /* Oben rund wie die Karte — nötig überall dort, wo die Karte selbst
       nicht beschneidet (z. B. Rollenübersicht). */
    border-radius: var(--r-gross) var(--r-gross) 0 0;
}
.rollenbanner__bild {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 22%;
}
/* In der Rollenübersicht ist Platz nach unten: Die Bilder sind hochkant
   (640×936), im 3:2-Ausschnitt fehlte die halbe Figur. Quadratisch zeigt
   deutlich mehr, ohne die Karten endlos zu strecken. */
/* In der Rollenübersicht („Spielregeln & Rollen") ist das Bild die Sache
   selbst und nicht Kopfschmuck einer Karte: Dort soll die Figur GANZ zu
   sehen sein. Das quadratische Banner schnitt bei 640×936-Karten fast ein
   Viertel unten ab (2026-09-03). Deshalb steht hier das Format der Karte
   selbst; beschnitten wird nur ein Hauch links und rechts. */
.rollenbanner--hoch { aspect-ratio: 2 / 3; }
.rollenbanner--hoch .rollenbanner__bild { object-position: 50% 50%; }
/* Der Verlauf trägt hier keinen Namen (der steht darunter) — er darf das
   Bild also nicht auf dem letzten Viertel eintrüben. */
.rollenbanner--hoch .rollenbanner__scrim {
    background: linear-gradient(180deg, transparent 78%,
        color-mix(in srgb, var(--flaeche) 88%, transparent) 100%);
}
.rollenbanner__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 40%,
        color-mix(in srgb, var(--flaeche) 92%, transparent) 96%);
    pointer-events: none;
}
.rollenbanner__name {
    position: relative;
    margin: 0;
    padding: var(--s3) var(--s5);
    font-family: var(--schrift-display);
    font-size: var(--f-titel);
    font-weight: 700;
    line-height: 1.1;
    text-shadow: 0 1px 8px rgba(0, 0, 0, .55);
}
:root[data-theme="light"] .rollenbanner__name { text-shadow: none; }
/* Die Kartenköpfe der Startseite sind quer gemalt (3 : 2) — nichts zu
   beschneiden, die Mitte ist die Mitte. Der Verlauf ist kürzer, weil kein
   Name darauf steht; die Überschrift folgt unter dem Bild. */
.rollenbanner--start .rollenbanner__bild { object-position: 50% 50%; }
/* Kein Farbverlauf ÜBER dem Bild: Die Karte trägt eine Holztextur, und eine
   flache Farbe darüber ergab eine harte Kante (Rückmeldung 07.09.). Statt-
   dessen wird das Bild selbst im unteren Drittel durchsichtig — die Bohlen
   der Karte scheinen durch, der Übergang fließt. */
.rollenbanner--start {
    -webkit-mask-image: linear-gradient(180deg, #000 78%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 78%, transparent 100%);
}
.rollenbanner--start .rollenbanner__scrim { display: none; }

.rollenkarte__name {
    font-size: var(--f-titel);
    font-weight: 700;
    margin: 0 0 var(--s1);
}

/* Das Bild im Erkenntnis-Dialog (Seherin-Vision, Mädchen-Blick): zieht sich
   über das Dialog-Polster, gleicher Zuschnitt wie das Rollenbanner. */
.erkenntnis__bild {
    position: relative;
    /* Das volle Rollenbild statt eines Querstreifens (2026-08-28): Die
       Erkenntnis der Seherin — und die Karten des Diebs — zeigen die
       Karte, wie sie ist. 832/1216 ist das Maß der Dateien selbst; bei
       passendem Verhältnis beschneidet `cover` nichts mehr. Damit der
       Dialog auf flachen Bildschirmen nicht sprengt, deckelt eine
       Höhengrenze, und das Bild bleibt dann eben schmaler statt
       angeschnitten. */
    aspect-ratio: 832 / 1216;
    max-height: min(58vh, 34rem);
    margin: calc(var(--s5) * -1) auto var(--s4);
    border-radius: var(--r-gross) var(--r-gross) 0 0;
    overflow: hidden;
}
.rollenkarte__text { color: var(--text-leise); font-size: var(--f-klein); }
.rollenkarte__abschnitt { margin-top: var(--s4); }
.rollenkarte__abschnitt h4 {
    font-size: var(--f-winzig);
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--text-still);
    margin: 0 0 var(--s1);
}

/* Der Dieb: die beiden Karten, die beim Austeilen liegen geblieben sind. */
.restkarten {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: var(--s3);
}
.restkarte {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s2);
    text-align: center;
    padding: var(--s3);
    border: 1px solid var(--rand-hell);
    border-radius: var(--r-gross);
    background: var(--flaeche);
}
/* Im Dialog zieht das Bild bündig nach oben — hier sitzt es in einer Kachel
   und braucht seine eigenen Kanten. */
.restkarte .erkenntnis__bild {
    margin: 0;
    width: 100%;
    border-radius: var(--r-gross);
}

.traenke { display: flex; gap: var(--s3); flex-wrap: wrap; }
.trank {
    display: flex; align-items: center; gap: var(--s2);
    padding: var(--s2) var(--s4);
    border-radius: var(--r-rund);
    border: 1px solid var(--rand-hell);
    background: var(--flaeche);
    cursor: pointer;
    min-height: var(--tippziel);
}
.trank--aktiv { border-color: var(--mond); background: color-mix(in srgb, var(--mond) 15%, var(--flaeche)); }
.trank--leer  { opacity: .4; cursor: not-allowed; }

/* Wen das Gift trifft — ohne diese Zeile war das Ziel nirgends abzulesen. */
.gift__ziel { margin: 0; text-align: center; }

/* ------------------------------------------------------------- Spielverlauf */

.verlauf {
    max-height: 14rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    font-size: var(--f-klein);
}
.verlauf__eintrag {
    padding: var(--s2) var(--s3);
    border-left: 2px solid var(--rand-hell);
    color: var(--text-leise);
}
.verlauf__eintrag--wichtig { border-left-color: var(--blut); color: var(--text); }

/* -------------------------------------------------------------------- Chat */

.chat { display: flex; flex-direction: column; height: 100%; min-height: 0; }

.chat__kanaele {
    display: flex; gap: var(--s1);
    padding-bottom: var(--s2);
    overflow-x: auto;
    scrollbar-width: none;
}
.chat__kanaele::-webkit-scrollbar { display: none; }

.chat__kanal {
    padding: var(--s2) var(--s3);
    border-radius: var(--r-rund);
    border: 1px solid var(--rand);
    background: transparent;
    color: var(--text-leise);
    font-size: var(--f-klein);
    cursor: pointer;
    white-space: nowrap;
    min-height: 2.25rem;
}
.chat__kanal--aktiv { background: var(--flaeche-hoch); color: var(--text); border-color: var(--rand-hell); }
.chat__kanal--wolf.chat__kanal--aktiv { color: var(--blut-schrift); border-color: var(--blut); }

.chat__verlauf {
    flex: 1;
    min-height: 8rem;
    max-height: 22rem;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    padding: var(--s3) 0;
}

.nachricht { font-size: var(--f-klein); line-height: 1.45; }
.nachricht__wer { font-weight: 650; color: var(--mond); }
.nachricht--system { color: var(--text-still); font-style: italic; }

/* Das Meldefähnchen an fremden Chatzeilen. Zurückhaltend, aber auffindbar —
   es soll erreichbar sein, nicht zum Melden auffordern. Kein display:none
   bei Ruhe: Auf dem Handy gibt es kein Hover, dort ist die Ruhedeckkraft
   der Dauerzustand — und mit 0,35 war sie dort kaum zu entdecken
   (Rückmeldung vom 2026-08-14: „dezent heller"). 0,55 bleibt leise, ist
   aber ohne Suchen zu sehen. */
.nachricht__melden {
    border: 0; background: none; cursor: pointer; padding: 0 var(--s1);
    color: var(--text-still); opacity: .55; font-size: .85em;
}
.nachricht:hover .nachricht__melden,
/* Dasselbe Fähnchen hängt auch an den Zeilen privater Gespräche. */
.pn__zeile:hover .nachricht__melden,
.nachricht__melden:focus-visible { opacity: .9; }

.chat__eingabe { display: flex; gap: var(--s2); }
.chat__eingabe .eingabe { flex: 1; }

/* --------------------------------------------------------------- Sprachchat */

.stimme {
    display: flex;
    align-items: center;
    gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-radius: var(--r-mittel);
    background: var(--flaeche);
    border: 1px solid var(--rand);
}

.sprechtaste {
    flex: 1;
    min-height: 3.5rem;
    /* Der Zähler liegt absolut in der Taste. Ohne diese Zeile suchte er
       sich den nächsten positionierten Vorfahren — in der Handkante steht
       sie ohnehin, aber sie gehört an die Taste selbst und nicht an einen
       Aufbau, der sich ändern kann. */
    position: relative;
    border-radius: var(--r-rund);
    border: 2px solid var(--rand-hell);
    background: var(--flaeche-hoch);
    font-weight: 700;
    cursor: pointer;
    touch-action: none;   /* kein Scrollen beim Gedrückthalten */
    user-select: none;
    transition: background var(--zeit-kurz) var(--kurve);
}
.sprechtaste--an {
    background: var(--gruen);
    border-color: var(--gruen);
    color: #06210f;
}
.sprechtaste:disabled { opacity: .4; cursor: not-allowed; }

/* ------------------------------------------------------- Spielbereich-Gitter */

.spielraum {
    display: grid;
    gap: var(--s5);
    grid-template-columns: 1fr;
}
@media (min-width: 62rem) {
    .spielraum { grid-template-columns: minmax(0, 1fr) 22rem; align-items: start; }
    .spielraum__seite { position: sticky; top: 5rem; }
}

/* Die Nacht legt sich sichtbar über den Bildschirm. */
.nachtschleier {
    position: fixed;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(90rem 60rem at 50% 0%, transparent, rgba(4, 6, 12, .55));
    z-index: 1;
    opacity: 0;
    transition: opacity 1.2s var(--kurve);
}
.nachtschleier--an { opacity: 1; }

/* Der Wortrand: grüne Einfassung des ganzen Schirms, solange ich das Wort
   habe (Meldeliste). Über der Handkante (40), unter Meldungen (60) und
   Dialogen; lässt jeden Tipp durch. */
.wortrand {
    position: fixed;
    inset: 0;
    z-index: 45;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--zeit) var(--kurve);
    box-shadow: inset 0 0 0 4px var(--gruen),
                inset 0 0 32px color-mix(in srgb, var(--gruen) 55%, transparent);
}
.wortrand--an {
    opacity: 1;
    animation: wortrand-atmen 1.6s ease-in-out infinite;
}
@keyframes wortrand-atmen {
    50% {
        box-shadow: inset 0 0 0 6px var(--gruen),
                    inset 0 0 48px color-mix(in srgb, var(--gruen) 70%, transparent);
    }
}
@media (prefers-reduced-motion: reduce) {
    .wortrand--an { animation: none; }
}

/* ------------------------------------------------------ Rollenenthüllung */

/*
 * Der Auftakt in zwei Abschnitten: erst das Auslosen, dann die Auflösung.
 *
 * Die Drehung läuft über `transform: rotateY` auf zwei Flächen, die
 * rückseitig unsichtbar sind — kein Nachbau mit Ein- und Ausblenden, sondern
 * eine echte Drehung, damit sie sich auch wie eine anfühlt.
 */
.enthuellung {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: grid;
    place-items: center;
    align-content: center;
    gap: var(--s5);
    padding: var(--s5);
    /* DECKEND. Der Verlauf lag früher bei .82 bis .96 — die Seite darunter
       schimmerte also mit vier bis achtzehn Prozent durch. Solange das Bild
       den ganzen Schirm füllte, fiel das nicht auf; seit es auf breiten
       Bildschirmen nur noch die Mitte einnimmt, sah man links und rechts den
       Spieltisch stehen (gemeldet am 24.08.). Ein Übergang, durch den die
       Seite blickt, die er gerade zudecken soll, ist keiner.
       Das `backdrop-filter: blur(3px)` steht deshalb auch nicht mehr hier:
       Hinter einem deckenden Grund gibt es nichts zu weichzeichnen, es kostete
       nur Rechenzeit auf schwachen Geräten. */
    background: radial-gradient(60rem 40rem at 50% 50%, rgb(13, 15, 22), rgb(4, 6, 12));
    overflow: hidden;
    opacity: 0;
    transition: opacity .45s var(--kurve);
    cursor: pointer;
}
.enthuellung--sichtbar,
.enthuellung--enthuellt,
.enthuellung--sparsam { opacity: 1; }

/* Die Wirtshaus-Szene hinter dem Ziehen. Volldeckend und stark
   abgedunkelt — durch die halbtransparente Grundfläche geisterte sonst
   die Seite dahinter (Überschrift, Knöpfe) mitten durchs Bild. Fällt das
   Bild aus, bleibt die alte Milchglas-Fläche als Rückfall. Im schwarzen
   Abschnitt verschwindet die Szene mit. */
.enthuellung__szene {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 30%;
    filter: brightness(.30) saturate(.85);
    transition: opacity .8s var(--kurve);
}
.enthuellung--schwarz .enthuellung__szene { opacity: 0; }

/*
 * Der schwarze Abschnitt.
 *
 * Im Klang liegen zwischen dem Trommeln und dem Schlag gut zwei Sekunden
 * völlige Stille. Die bleiben nicht ungenutzt: Das Bild geht mit, die Karte
 * verschwindet in der Dunkelheit, und aus ihr heraus kommt die Auflösung.
 * Eine Pause, in der nichts passiert, wirkt wie ein Aussetzer — eine, in der
 * es dunkel wird, wie eine Ankündigung.
 */
.enthuellung--schwarz {
    background: #04060c;
    backdrop-filter: blur(6px);
    transition: background .8s var(--kurve), backdrop-filter .8s var(--kurve);
}
.enthuellung--schwarz .enthuellung__karte {
    opacity: 0;
    transform: rotateY(180deg) scale(.86);
    transition: opacity .7s var(--kurve), transform .7s var(--kurve);
}
.enthuellung--schwarz.enthuellung--enthuellt .enthuellung__karte {
    opacity: 1;
    transform: rotateY(0deg) scale(1);
    transition: opacity .5s var(--kurve), transform 1s cubic-bezier(.4, 0, .2, 1);
}

/*
 * Die ausblendende Karte darf nichts mehr abfangen. Ohne das bliebe sie eine
 * knappe halbe Sekunde lang ein Klickziel über dem Spiel — wer zum Schließen
 * tippt und gleich weitertippt, verlöre den zweiten Tipp.
 */
.enthuellung--zu { opacity: 0; pointer-events: none; }

.enthuellung__karte {
    position: relative;
    width: min(22rem, 82vw);
    aspect-ratio: 3 / 4;
    transform-style: preserve-3d;
    transform: rotateY(180deg);
    transition: transform 1s cubic-bezier(.5, 0, .2, 1);
}
.enthuellung--enthuellt .enthuellung__karte { transform: rotateY(0deg); }

.enthuellung__los,
.enthuellung__vorderseite {
    position: absolute;
    inset: 0;
    border-radius: var(--r-gross);
    /* Ohne das scheint bei manchen Browsern die abgewandte Seite durch. */
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    box-shadow: var(--schatten), var(--schatten-mond);
}

/* ---- Abschnitt 1: das Auslosen */

.enthuellung__los {
    transform: rotateY(180deg);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: var(--s4);
    padding: var(--s5);
    text-align: center;
    background:
        repeating-linear-gradient(45deg,
            rgba(240, 163, 92, .04) 0 10px, transparent 10px 20px),
        linear-gradient(155deg, var(--flaeche-hoch), var(--grund));
    border: 1px solid var(--rand-hell);
}

.enthuellung__losfrage {
    margin: 0;
    font-size: var(--f-klein);
    text-transform: uppercase;
    letter-spacing: .18em;
    color: var(--text-still);
}

/*
 * Der durchlaufende Name. Feste Höhe und mittige Ausrichtung, damit die
 * Karte bei langen Namen nicht springt — ein zappelndes Kartenbild würde
 * das Ausrollen zunichtemachen.
 */
.enthuellung__losname {
    margin: 0;
    min-height: 2.4em;
    display: grid;
    place-items: center;
    font-family: var(--schrift-display);
    font-size: var(--f-gross);
    font-weight: 700;
    color: var(--mond);
    text-shadow: 0 0 18px color-mix(in srgb, var(--mond) 45%, transparent);
}

/* ---- Abschnitt 2: die Auflösung */

.enthuellung__vorderseite {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: var(--s3);
    padding: var(--s5);
    text-align: center;
    overflow: hidden;
    background: linear-gradient(155deg, var(--flaeche-hoch), var(--flaeche));
    border: 1px solid color-mix(in srgb, var(--dorf) 45%, transparent);
}
.enthuellung__karte--wolf .enthuellung__vorderseite {
    background: linear-gradient(155deg, #2a1418, #14090c);
    border-color: color-mix(in srgb, var(--blut) 55%, transparent);
}

/* Das Rollenbild füllt die Karte; der Scrim dunkelt das untere Drittel
   zusätzlich ab, damit Beschreibung und Ziel sicher lesbar sind. Der Text
   sitzt deshalb unten (justify-content: flex-end) — in der von der
   Generierung eingeplanten dunklen Zone. */
.enthuellung__bild {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
}
.enthuellung__bildscrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 35%, rgba(6, 8, 14, .88) 90%);
    pointer-events: none;
}
/* Die GANZE Vorderseite bleibt bis zur Auflösung strikt unsichtbar:
   backface-visibility verdeckt positionierte Kinder einer 3D-Drehung
   nicht verlässlich — Bild, Rand und Text blitzten während des
   Namenslaufs durch die Rückseite. */
.enthuellung__vorderseite { visibility: hidden; }
.enthuellung--enthuellt .enthuellung__vorderseite,
.enthuellung--sparsam .enthuellung__vorderseite {
    visibility: visible;
}
.enthuellung__vorderseite > :not(.enthuellung__bild):not(.enthuellung__bildscrim) {
    position: relative;
}

/* In der Spalte würde die Marke sonst über die ganze Breite gezogen. */
.enthuellung__vorderseite .marke { align-self: center; }

.enthuellung__name {
    font-family: var(--schrift-display);
    font-size: var(--f-riesig);
    font-weight: 700;
    line-height: 1.1;
    margin: 0;
    /* Der Name kommt eine Spur später als die Drehung — erst die Karte,
       dann der Name, sonst nimmt man beides auf einmal nicht wahr. */
    opacity: 0;
    transform: translateY(.5rem);
    transition: opacity .45s var(--kurve) .5s, transform .45s var(--kurve) .5s;
}
.enthuellung--enthuellt .enthuellung__name { opacity: 1; transform: none; }

.enthuellung__text { color: var(--text-leise); font-size: var(--f-klein); margin: 0; }
.enthuellung__ziel {
    color: var(--mond);
    font-size: var(--f-klein);
    margin: 0;
    border-top: 1px solid var(--rand);
    padding-top: var(--s3);
}

/*
 * Die gesprochene Ansage, mitgeschrieben.
 *
 * Sie erscheint mit der Drehung, eine Spur nach dem Namen — dieselbe
 * Staffelung wie dort: erst die Karte, dann der Name, dann der Satz. Alles
 * gleichzeitig nimmt niemand auf.
 */
.enthuellung__ansage {
    position: relative;   /* über der Szenen-Ebene */
    max-width: 34ch;
    margin: 0;
    text-align: center;
    text-wrap: balance;
    color: var(--mond);
    font-family: var(--schrift-display);
    font-size: var(--f-gross);
    line-height: 1.35;
    opacity: 0;
    transform: translateY(.4rem);
    transition: opacity .5s var(--kurve) .8s, transform .5s var(--kurve) .8s;
}
.enthuellung--enthuellt .enthuellung__ansage { opacity: 1; transform: none; }
.enthuellung--sparsam .enthuellung__ansage { transition-delay: 0s; }
@media (prefers-reduced-motion: reduce) {
    .enthuellung__ansage { transition-delay: 0s; }
}

.enthuellung__hinweis {
    position: relative;   /* über der Szenen-Ebene */
    color: var(--text-still);
    font-size: var(--f-klein);
    margin: 0;
}

/*
 * Wer Bewegung nicht verträgt, bekommt dieselbe Karte ohne Auslosen und ohne
 * Drehung. Die Angabe wird zusätzlich am Element gesetzt, weil manche
 * eingebettete Browser die Systemeinstellung nicht an die Medienabfrage
 * weiterreichen.
 */
@media (prefers-reduced-motion: reduce) {
    .enthuellung__karte { transition: none; transform: none; }
    .enthuellung__los { display: none; }
    .enthuellung__name { transition-delay: 0s; }
}
.enthuellung--sparsam .enthuellung__karte { transition: none; transform: none; }
.enthuellung--sparsam .enthuellung__los { display: none; }
.enthuellung--sparsam .enthuellung__name { transition-delay: 0s; }

/* ============================================================== Übergänge
 *
 * Die Blende zwischen zwei Abschnitten. Sie liegt über allem, lässt aber
 * jeden Klick durch (`pointer-events: none`) — sie erzählt, sie bedient
 * nicht. Wer während des Übergangs schon etwas anwählen will, kann das.
 */
.uebergang {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: grid;
    place-items: center;
    pointer-events: none;
    opacity: 0;
    transition: opacity .5s var(--kurve);
}
.uebergang--an   { opacity: 1; }
.uebergang--fort { opacity: 0; }

/* Die Scheibe selbst: eine Farbwand, die von oben und unten zusammenzieht. */
.uebergang::before,
.uebergang::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    height: 52%;
    background: var(--uebergang-farbe, var(--grund));
    transition: transform .55s var(--kurve);
}
.uebergang::before { top: 0;    transform: translateY(-100%); }
.uebergang::after  { bottom: 0; transform: translateY(100%); }
.uebergang--an::before,
.uebergang--an::after { transform: none; }
.uebergang--fort::before { transform: translateY(-100%); }
.uebergang--fort::after  { transform: translateY(100%); }

.uebergang--nacht   { --uebergang-farbe: #070911; }
.uebergang--morgen  { --uebergang-farbe: #2a2233; }
.uebergang--tag     { --uebergang-farbe: #1b2030; }
.uebergang--gericht { --uebergang-farbe: #1a1420; }

/* Das Szenenbild zwischen Farbwand und Schriftzug: Es schimmert gedämpft
   durch und zieht ganz langsam auf (Ken-Burns) — bei reduzierter Bewegung
   erscheint der Übergang ohnehin gar nicht (siehe zeigeUebergang). */
.uebergang__szene {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 30%;
    z-index: 1;
    opacity: 0;
    transition: opacity .6s var(--kurve);
}
.uebergang--an .uebergang__szene {
    opacity: .5;
    /* Langsamer Zug über die ganze (gehaltene) Standzeit, statt nach
       drei Sekunden stillzustehen. */
    animation: szene-zoom 12s var(--kurve) forwards;
}
.uebergang--fort .uebergang__szene { opacity: 0; }
@keyframes szene-zoom { to { transform: scale(1.08); } }

.uebergang__mitte {
    position: relative;
    z-index: 2;
    text-align: center;
    opacity: 0;
    transform: scale(.86);
    transition: opacity .45s var(--kurve) .25s, transform .6s var(--kurve) .25s;
}
.uebergang--an .uebergang__mitte   { opacity: 1; transform: none; }
.uebergang--fort .uebergang__mitte { opacity: 0; transform: scale(1.08); }

.uebergang__wort {
    color: var(--mond);
    font-family: var(--schrift-display);
    font-size: var(--f-gross);
    font-weight: 700;
    letter-spacing: .06em;
}

/* ============================================================ Endsequenz
 *
 * Das Schlussbild. Anders als der Übergang nimmt es die Bedienung an sich:
 * Hier soll man lesen, wer was war, und nicht versehentlich weiterklicken.
 */
.endsequenz {
    position: fixed;
    inset: 0;
    z-index: 80;
    display: grid;
    justify-items: center;

    /*
     * `safe` ist hier kein Feinschliff, sondern der Unterschied zwischen
     * bedienbar und nicht.
     *
     * Mit `place-items: center` wird ein Inhalt, der HÖHER ist als der
     * Bildschirm, nach BEIDEN Seiten über den Rand geschoben — oben wie
     * unten. Was oben hinausragt, lässt sich nicht zurückscrollen, und der
     * „Weiter"-Knopf am Fuß bleibt unerreichbar. Die Schicht liegt dann
     * über dem Spieltisch und verdeckt „Gleiche Runde weiter".
     *
     * Genau das trat ein, sobald jemand mehrere Auszeichnungen auf einmal
     * bekam — also ausgerechnet im schönsten Moment der Partie.
     *
     * `safe center` zentriert, solange Platz ist, und fällt bei Überlänge
     * auf `start` zurück. Nichts ragt mehr oben hinaus.
     */
    align-content: safe center;
    padding: var(--s5);
    overflow-y: auto;
    /* Deckend — siehe .enthuellung. */
    background: radial-gradient(circle at 50% 35%,
                rgb(20, 24, 36), rgb(5, 6, 10));
    opacity: 0;
    transition: opacity .6s var(--kurve);
}

/* Das Siegbild hinter der Auflösung — die Kartenzeile liegt ohnehin auf
   dem dunklen unteren Bilddrittel. `fixed` hält es beim Scrollen der
   langen Kartenliste an Ort und Stelle. */
.endsequenz__szene {
    position: fixed;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 30%;
    opacity: 0;
    transition: opacity 1.2s var(--kurve);
}
/* Bis der Sieg feststeht, dämmert das Siegbild erst leise durch die
   Dunkelheit — dann tritt es vor und trägt die Auflösung. */
.endsequenz--sichtbar .endsequenz__szene { opacity: .16; }
.endsequenz--sieg .endsequenz__szene { opacity: .35; }
.endsequenz--sparsam .endsequenz__szene { opacity: .35; transition: none; }
.endsequenz--sichtbar { opacity: 1; }
.endsequenz--zu       { opacity: 0; }

.endsequenz__mitte { position: relative; text-align: center; max-width: 44rem; }

/*
 * Der Weiter-Knopf klebt am unteren Rand der Schicht.
 *
 * Auch mit `safe center` kann der Inhalt länger sein als der Bildschirm —
 * bei fünf Auszeichnungen ist er das. Klebend bleibt der Ausgang sichtbar,
 * ohne dass jemand erst ans Ende scrollen muss, um herauszufinden, wie er
 * hier wieder herauskommt.
 */
.endsequenz__knopf {
    position: sticky;
    bottom: 0;
    margin-top: var(--s5);
    /* Der Streifen dahinter, damit der Knopf nicht auf Text zu schweben
       scheint, wenn darunter noch etwas durchläuft. */
    box-shadow: 0 0 0 var(--s4) rgba(8, 10, 16, .92);
    background-clip: padding-box;
}

/*
 * Das Kreuz oben rechts — der zweite Weg hinaus.
 *
 * Es steht dort, wo man es sucht, und es ist immer sichtbar, egal wie lang
 * der Inhalt ist. Der Weiter-Knopf am Fuß bleibt trotzdem: Er ist der
 * Abschluss der Auflösung, das Kreuz ist der Notausgang.
 */
.endsequenz__zu {
    position: fixed;
    top: calc(var(--s4) + env(safe-area-inset-top));
    right: calc(var(--s4) + env(safe-area-inset-right));
    z-index: 1;
    width: var(--tippziel);
    height: var(--tippziel);
    padding: 0;
    border-radius: 50%;
    font-size: 1.4rem;
    line-height: 1;
}

.endsequenz--dorf   { --endfarbe: var(--dorf); }
.endsequenz--woelfe { --endfarbe: var(--blut); }
.endsequenz--liebe  { --endfarbe: var(--liebe); }
/* Kein Sieger, also auch keine Fraktionsfarbe: das gedämpfte Grau der
   stillen Schrift. Ein Bernstein- oder Blutton würde Partei ergreifen. */
.endsequenz--unentschieden { --endfarbe: var(--text-still); }

.endsequenz__titel,
.endsequenz__unter,
.endsequenz__erzaehlung,
.endsequenz__karten,
.endsequenz__knopf {
    opacity: 0;
    transform: translateY(.75rem);
    transition: opacity .6s var(--kurve), transform .6s var(--kurve);
}
.endsequenz--sieg .endsequenz__titel,
.endsequenz--sieg .endsequenz__unter { opacity: 1; transform: none; }
.endsequenz--text .endsequenz__erzaehlung { opacity: 1; transform: none; }
.endsequenz--karten .endsequenz__karten,
.endsequenz--karten .endsequenz__knopf { opacity: 1; transform: none; }

.endsequenz__titel {
    font-family: var(--schrift-display);
    font-size: var(--f-riesig);
    color: var(--endfarbe, var(--mond));
    margin: var(--s4) 0 var(--s2);
    line-height: 1.05;
}
.endsequenz__unter { color: var(--text-leise); margin: 0; }
.endsequenz__erzaehlung {
    margin: var(--s5) auto 0;
    max-width: 34rem;
    font-style: italic;
    font-size: var(--f-gross);
    line-height: 1.55;
    color: var(--text);
}

.endsequenz__karten { margin-top: var(--s6); }
.endsequenz__kartenkopf {
    font-size: var(--f-klein);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--text-still);
    margin: 0 0 var(--s3);
}
.endsequenz__reihe {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s2);
}
.endsequenz__karte {
    display: flex;
    align-items: center;
    gap: var(--s2);
    padding: var(--s2) var(--s3);
    border: 1px solid var(--rand);
    border-radius: var(--r-rund);
    background: var(--flaeche);
    font-size: var(--f-klein);
    opacity: 0;
    transform: translateY(.5rem);
    transition: opacity .4s var(--kurve), transform .4s var(--kurve);
}
.endsequenz--karten .endsequenz__karte { opacity: 1; transform: none; }
.endsequenz__karte--tot { opacity: .55; }

/* Gezeichnete Avatare auch im Schlussbild rund und klein. */
.endsequenz__bild {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 1.8rem; height: 1.8rem;
    border-radius: 50%;
    overflow: hidden;
    flex: none;
}
.endsequenz--karten .endsequenz__karte--tot { opacity: .55; }
.endsequenz__spieler { font-weight: 600; }
.endsequenz__rolle   { color: var(--mond); }
.endsequenz__kreuz   { color: var(--blut); font-weight: 700; }
.endsequenz__knopf   { margin-top: var(--s6); }

/* Ohne Bewegung liegt alles sofort offen da. */
.endsequenz--sparsam :is(.endsequenz__titel, .endsequenz__unter,
    .endsequenz__erzaehlung, .endsequenz__karten, .endsequenz__karte,
    .endsequenz__knopf) {
    opacity: 1;
    transform: none;
    transition: none;
}

/* ====================================================== Redekasten (Melden)
 *
 * Rot oder grün, groß genug, um aus dem Augenwinkel erkennbar zu sein. Das
 * ist die Antwort auf die einzige Frage, die in dieser Betriebsart zählt:
 * Darf ich jetzt reden?
 */
.redekasten {
    border-radius: var(--r-mittel);
    border: 2px solid;
    padding: var(--s3) var(--s4);
}
.redekasten--gruen {
    border-color: var(--gruen);
    background: color-mix(in srgb, var(--gruen) 16%, transparent);
}
.redekasten--rot {
    border-color: var(--blut);
    background: color-mix(in srgb, var(--blut) 14%, transparent);
}
.redekasten__zeile {
    display: flex;
    align-items: center;
    gap: var(--s3);
}
.redekasten__wort { font-weight: 700; font-size: var(--f-gross); }
.redekasten__uhr {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-size: var(--f-gross);
    font-weight: 700;
}
.redekasten__hinweis {
    margin: var(--s2) 0 0;
    color: var(--text-leise);
    font-size: var(--f-klein);
}

/* Die Rednerliste — wer nach wem. */
.warteliste {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s2);
}
.warteliste__platz {
    padding: var(--s1) var(--s3);
    border-radius: var(--r-rund);
    background: var(--flaeche-hoch);
    font-size: var(--f-klein);
    color: var(--text-leise);
}
.warteliste__platz--ich {
    background: var(--mond);
    color: #1a1408;
    font-weight: 700;
}

/* Wie viele sind bereit zur Abstimmung. */
.fortschritt {
    height: 6px;
    border-radius: var(--r-rund);
    background: var(--flaeche-hoch);
    overflow: hidden;
}
.fortschritt__balken {
    height: 100%;
    background: var(--mond);
    transition: width var(--zeit) var(--kurve);
}
.fortschritt--voll .fortschritt__balken { background: var(--gruen); }

/* ========================================================= Spielleiterkarte
 *
 * Der geschriebene Zwilling der gesprochenen Anleitung. Bewusst ruhig
 * gehalten und nicht als „Karte": Sie steht über der Handlung und soll sie
 * nicht optisch verdrängen.
 */
.anleitung {
    display: flex;
    align-items: flex-start;
    gap: var(--s3);
    padding: var(--s3) var(--s4);
    border-left: 3px solid var(--mond);
    border-radius: 0 var(--r-klein) var(--r-klein) 0;
    background: color-mix(in srgb, var(--mond) 8%, transparent);
}
.anleitung__text {
    margin: 0;
    flex: 1;
    font-size: var(--f-klein);
    line-height: 1.55;
    color: var(--text-leise);
}

/* =========================================================== Galgen-Moment
 *
 * Die Auflösung der Abstimmung: verdunkeln, trommeln, dann der Name.
 * Gleiche Familie wie Enthüllung und Endsequenz — nur knapper, denn sie
 * kommt jede Runde.
 */
.galgen {
    position: fixed;
    inset: 0;
    z-index: 75;
    display: grid;
    place-items: center;
    padding: var(--s5);
    /* Deckend — siehe .enthuellung. */
    background: radial-gradient(circle at 50% 40%,
                rgb(26, 20, 32), rgb(5, 6, 10));
    opacity: 0;
    transition: opacity .5s var(--kurve);
    cursor: pointer;
}
.galgen--an { opacity: 1; }
.galgen--zu { opacity: 0; }

/* Die Galgen-Szene hinter dem Urteil — gedämpft, das Radial bleibt oben. */
.galgen__szene {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 30%;
    opacity: .30;
}
.galgen:not(.galgen--sparsam) .galgen__szene {
    animation: szene-zoom 8s var(--kurve) forwards;
}

.galgen__mitte { position: relative; text-align: center; max-width: 34rem; }

.galgen__frage {
    margin: var(--s4) 0 0;
    color: var(--text-leise);
    font-size: var(--f-gross);
    font-style: italic;
}

.galgen__urteil {
    opacity: 0;
    transform: translateY(.75rem);
    transition: opacity .45s var(--kurve), transform .45s var(--kurve);
}
.galgen--aufgeloest .galgen__urteil { opacity: 1; transform: none; }
.galgen--aufgeloest .galgen__frage  { opacity: .5; }

.galgen__name {
    margin: var(--s4) 0 var(--s2);
    font-family: var(--schrift-display);
    font-size: var(--f-riesig);
    font-weight: 700;
    line-height: 1.05;
    color: var(--blut);
}
.galgen__zusatz { margin: 0; color: var(--text); font-size: var(--f-gross); }
/* Das Patt (10.09.2026): kein Blut im Wort „Niemand" — die Auflösung ist
 * die Erleichterung, nicht der Schlag. */
.galgen--patt .galgen__name { color: var(--mond); }
.galgen__rolle  { margin: var(--s2) 0 0; color: var(--mond); }

/*
 * Die Karte des Gehängten — dieselbe wie am Morgen (js/ui/opferkarte.js).
 *
 * Am Morgen stehen bis zu drei davon nebeneinander in `.buehne__reihe`, die
 * für Breite und Ausrichtung sorgt. Hier steht genau eine, und sie steht
 * allein in der Mitte: `margin-inline: auto` ersetzt die Reihe.
 *
 * Etwas größer als am Morgen (12 statt 10 rem), weil sie hier nicht mit
 * Geschwistern um den Platz konkurriert — der Galgen ist ein Auftritt für
 * einen. Der Name unter der Karte übernimmt die Rolle von `.galgen__name`,
 * das nur noch beim Duell erscheint (zwei Namen, keine Karte).
 */
.galgen__urteil .buehne__opfer {
    width: min(15rem, 58vw, 30vh);
    margin: 0 auto var(--s3);
}

/* Wen der Tod noch mitgerissen hat — leiser als das Urteil selbst, damit
   der Blick zuerst beim Gehängten bleibt. */
.galgen__weitere {
    margin-top: var(--s4);
    padding-top: var(--s3);
    border-top: 1px solid var(--rand);
    display: grid;
    gap: var(--s2);
}
.galgen__weitere .galgen__zusatz { font-size: var(--f-normal); color: var(--text-still); }

/*
 * Wer für wen gestimmt hat — die knappe Nachlese unter dem Urteil.
 *
 * Eine Zeile je Ziel: links der Name in Weiß, rechts seine Wähler klein und
 * still. Bewusst als Raster mit zwei Spalten, damit die Namen der Ziele
 * untereinander stehen und das Auge die Mehrheit auf einen Blick findet.
 * Auf schmalem Schirm bricht die Wählerliste unter das Ziel.
 */
.galgen__stimmen {
    margin-top: var(--s4);
    padding-top: var(--s3);
    border-top: 1px solid var(--rand);
    /* EIN Raster über alle Zeilen (die Absätze lösen sich mit
     * `display: contents` darin auf): Nur so stehen die Wähler aller Zeilen
     * in derselben Spalte, und das Auge findet die Mehrheit von oben nach
     * unten. Je Zeile ein eigenes Raster ergäbe eine ausgefranste Kante. */
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--s1) var(--s2);
    align-items: baseline;
    width: fit-content;
    max-width: 100%;
    margin-inline: auto;
    font-size: var(--f-klein);
    text-align: left;
}
.galgen__stimme { display: contents; }
.galgen__stimmeZiel {
    color: var(--text);
    font-weight: 600;
    white-space: nowrap;
}
.galgen__stimmeZiel::after { content: " ←"; color: var(--text-still); font-weight: 400; }
.galgen__stimmeWaehler { color: var(--text-still); }

/* Auch am Handy bleiben es zwei Spalten. Der Versuch, dort untereinander
 * zu setzen, verdoppelte die Höhe der Nachlese — und „möglichst kompakt"
 * war der ganze Auftrag. Die Namen der Ziele sind kurz, und die Wähler
 * umbrechen in ihrer Spalte, ohne die Kante zu verlieren.
 */

.galgen__hinweis {
    margin-top: var(--s6);
    color: var(--text-still);
    font-size: var(--f-klein);
}

.galgen--sparsam .galgen__urteil  { transition: none; }

/* ============================================================ Morgenbühne */

/*
 * Dieselbe Machart wie der Galgen — dunkler Vorhang, Szene dahinter, ein Tipp
 * überspringt. Eigene Klassen, weil hier bis zu drei Gesichter nebeneinander
 * stehen statt eines großen Namens.
 */
.buehne {
    position: fixed;
    inset: 0;
    z-index: 75;
    display: grid;
    place-items: center;
    /* Drei Karten samt Namen sind auf einem kleinen Gerät höher als der
       Schirm. Ohne dies wäre der dritte Name schlicht abgeschnitten. Quer
       ausdrücklich nicht: Sobald eine Achse rollt, macht CSS die andere von
       selbst rollbar — und ein Bild, das sich seitlich schieben lässt, sieht
       nach Fehler aus. */
    overflow-y: auto;
    overflow-x: hidden;
    padding: var(--s5);
    /* Außen ganz deckend: Der Spieltisch darunter ist hell genug, um durch
       drei Prozent Rest noch durchzuscheinen — und ein durchscheinender
       Tisch nimmt dem Augenblick die Ruhe. */
    /* Deckend — siehe .enthuellung. */
    background: radial-gradient(circle at 50% 40%,
                rgb(30, 26, 22), rgb(6, 7, 11));
    opacity: 0;
    transition: opacity .5s var(--kurve);
}
.buehne--an { opacity: 1; }
.buehne--zu { opacity: 0; }
.buehne--sparsam { opacity: 1; transition: none; }

.buehne__szene {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 40%;
    opacity: .28;
}
.buehne:not(.buehne--sparsam) .buehne__szene {
    animation: szene-zoom 10s var(--kurve) forwards;
}

/* ======================================== Breite Bildschirme
 *
 * Hier stand bis zum 27.08. eine Notlösung: Die Szenenbilder waren hochkant
 * (832 × 1216), und auf einem breiten Bildschirm rechnete `cover` sie auf die
 * BREITE hoch — von 1216 Punkten Höhe blieb ein Streifen von gut einem
 * Drittel übrig, Nacht für Nacht derselbe obere Ausschnitt. Gemeldet am
 * 24.08.
 *
 * Der Ausweg damals: die Box auf das Seitenmaß des Bildes eindampfen
 * (`aspect-ratio: 832 / 1216`, volle Höhe, `width: auto`) und die dabei
 * entstehenden harten Kanten links und rechts mit einer `mask-image`-Blende
 * ausblenden.
 *
 * **Beides ist entfallen.** Seit dem 27.08. sind die Szenenbilder selbst
 * 2176 × 1216 — links und rechts ergänzt, siehe werkzeuge/szenen-breit.py.
 * Damit füllt schlichtes `cover` den Bildschirm auf jedem Gerät richtig: Am
 * Handy zeigt es dieselben 562 Punkte Bildbreite wie vorher, am PC die vollen
 * 2162 von 2176.
 *
 * Die alte Regel wäre jetzt aktiv schädlich: Sie presste das breite Bild in
 * eine HOCHKANT-Box zurück und beschnitt es dabei auf denselben schmalen
 * Ausschnitt — die Ergänzung wäre umsonst gewesen. Und die seitliche Blende
 * hätte gerade die neu hinzugekommenen Ränder weggeblendet.
 *
 * **Eine Grenze hat `cover` doch (gemeldet 2026-09-05):** Ist der Bildschirm
 * BREITER als das Bild (2176 : 1216, also breiter als 16:9 — Ultrawide),
 * füllt `cover` die Breite und schneidet oben und unten ab. Dort soll das
 * Bild lieber die volle Höhe behalten und links und rechts Luft lassen:
 * `contain` ab diesem Seitenverhältnis. Am Handy und am gewöhnlichen
 * Monitor ändert das nichts, dort greift weiter `cover`.
 */
@media (min-aspect-ratio: 2176 / 1216) {
    .uebergang__szene,
    .endsequenz__szene,
    .galgen__szene,
    .buehne__szene,
    .enthuellung__szene {
        object-fit: contain;
    }
}

.buehne__mitte { position: relative; text-align: center; max-width: 40rem; }

.buehne__frage {
    margin: 0;
    color: var(--text-leise);
    font-size: var(--f-gross);
    font-style: italic;
}

.buehne__aufloesung {
    opacity: 0;
    transform: translateY(.75rem);
    transition: opacity .5s var(--kurve), transform .5s var(--kurve);
}
.buehne--aufgeloest .buehne__aufloesung { opacity: 1; transform: none; }
.buehne--aufgeloest .buehne__frage      { opacity: .45; }
.buehne--sparsam    .buehne__aufloesung { transition: none; }

.buehne__titel {
    margin: var(--s5) 0 var(--s4);
    font-family: var(--schrift-display);
    font-size: var(--f-titel);
    color: var(--blut);
}
/* Dass niemand gestorben ist, ist eine gute Nachricht — nicht blutrot. */
.buehne__titel--heil { color: var(--gruen); }

.buehne__reihe {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s5);
}

/* Auf schmalen Geräten schrumpfen die Karten mit, statt umzubrechen: Drei
   Tote in einer Nacht sind selten, aber dann sollen sie nebeneinander
   stehen — untereinander wäre es eine Liste, kein Bild. */
.buehne__opfer { width: min(10rem, 27vw); }
/* Ein einzelner Toter bekommt die große Karte (17.10.2026, Partie UJEX9:
   „Wenn Menschen ausscheiden, muss deutlicher werden, wie sie hießen und
   welche Figur sie hatten … die Karte muss größer angezeigt werden"). */
.buehne__reihe--einzeln .buehne__opfer { width: min(15rem, 60vw, 32vh); }
.buehne__reihe--einzeln .buehne__name { font-size: var(--f-titel); }

/* Der Satz unter der Karte: „Sonja war Amor." — Name und Rolle in Worten,
   nicht nur im Bild. */
.buehne__satz {
    margin: var(--s2) 0 0;
    font-size: var(--f-gross);
    font-weight: 600;
    color: var(--text);
    line-height: 1.3;
}

/*
 * Die Karte der Rolle, die dieser Spieler gespielt hat — im Hochformat der
 * Rollenbilder (640 × 936). Graustufen: Wer tot ist, ist aus dem Spiel; das
 * sieht man, bevor man den Namen gelesen hat.
 */
.buehne__karte {
    position: relative;
    width: 100%;
    aspect-ratio: 640 / 936;
    margin-bottom: var(--s3);
    border-radius: var(--r-mittel);
    overflow: hidden;
    background: var(--flaeche);
    border: 1px solid color-mix(in srgb, var(--blut) 45%, var(--rand));
    box-shadow: var(--schatten);
    filter: grayscale(.7);
}
.buehne__rollenbild {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: 50% 22%;
}
/* Nach unten dunkel auslaufen, damit das Sinnbild in der Ecke steht und
   nicht im Bild versinkt. */
.buehne__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 45%, rgba(6, 7, 11, .85) 100%);
    pointer-events: none;
}

/* Ohne aufgedeckte Rolle gibt es kein Rollenbild — dann trägt die Karte nur
   das Gesicht, und zwar mittig statt in der Ecke. */
.buehne__karte--leer {
    display: grid;
    place-items: center;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
}

/*
 * Das Sinnbild des Spielers: unten links AUF der Karte. Es beantwortet die
 * zweite Frage — die Rolle sagt, was das Dorf verloren hat, das Gesicht, wer
 * es war.
 */
.buehne__bild {
    position: absolute;
    left: var(--s2);
    bottom: var(--s2);
    width: 3.2rem; height: 3.2rem;
    border-radius: 50%;
    overflow: hidden;
    display: grid;
    place-items: center;
    font-size: 1.6rem;
    background: var(--flaeche);
    border: 2px solid color-mix(in srgb, var(--mond) 70%, var(--rand));
    box-shadow: 0 2px 10px rgba(0, 0, 0, .6);
}
.buehne__karte--leer .buehne__bild {
    position: static;
    width: 5.5rem; height: 5.5rem;
    font-size: 2.75rem;
}

.buehne__name {
    margin: 0;
    font-weight: 700;
    font-size: var(--f-gross);
    color: var(--text);
}
.buehne__rolle {
    margin: var(--s1) 0 0;
    color: var(--mond);
    font-size: var(--f-klein);
}
.buehne__art {
    margin: var(--s2) 0 0;
    color: var(--text-leise);
    font-size: var(--f-klein);
    line-height: 1.35;
}

.buehne__hinweis {
    margin-top: var(--s6);
    color: var(--text-still);
    font-size: var(--f-klein);
}

/* ========================================================== Morgenbericht */
.morgen__zeile {
    display: flex;
    align-items: baseline;
    gap: var(--s2);
    padding: var(--s1) 0;
}

/* ========================================================= Bilderwelt-Wahl
   Der erste Bildschirm überhaupt: Bevor Lobby oder Anmeldung erscheinen,
   wählt jedes Gerät seine Bildfassung (Erwachsene/Jugend/Kinder). */

.bildwahl {
    position: fixed;
    inset: 0;
    z-index: 220;
    display: grid;
    place-items: center;
    overflow: auto;
    padding: var(--s5);
    /* Die Kulisse des ersten Blicks: die Glut des Lagerfeuers, dahinter
       das Dorf im Nebel (Casting 2026-08-28, Wurf „glut", 2176×1216).
       Das Standbild trägt den Bildschirm, bis die Schleife darüber geladen
       ist, und es trägt ihn allein, wo die Schleife nicht läuft
       (abgeschaltete Bewegung, fehlende Datei). Es liegt seit dem
       13.09.2026 in einer eigenen Ebene (.bildwahl__standbild) statt hier —
       siehe dort. Der Schleier liegt in ::after, sonst läge er unter dem
       Feuer und dämpfte nur das Standbild.
       Der Grund ist SCHWARZ, nicht --grund: Neben der Kulisse soll nichts
       stehen als Schwarz, in das ihre Ränder übergehen (siehe ::before). */
    background: #000;
}

/* Die Kulisse hängt an der HÖHE, nicht an der Breite (13.09.2026).
 *
 * `cover` rechnet mit der längeren Seite: Auf einem breiten, flachen
 * Fenster (2000 × 790 etwa) zog es das Bild auf 2000 Pixel Breite und
 * schnitt oben und unten je ein Sechstel ab — das Dorf verlor seine
 * Dächer, das Feuer seinen Fuß. Elmar am 13.09.: „die Hintergründe sollen
 * alle an der Höhe angepasst sein, auch wenn der Bildschirm breiter ist."
 *
 * `auto 100%` stellt das ganze Bild in voller Höhe hin. Auf schmalen
 * Geräten ändert das nichts — dort war die Höhe ohnehin schon das Maß.
 * Auf breiten bleiben links und rechts Streifen frei; die füllt der
 * weichgezeichnete Grund in ::before.
 */
.bildwahl__standbild {
    position: fixed;
    inset: 0;
    z-index: 0;
    background: url("../assets/bilder/erstwahl/lagerfeuer.webp") center / auto 100% no-repeat;
    pointer-events: none;
}

/* Die Seiten laufen ins Schwarze (13.09.2026).
 *
 * Zuerst stand hier dasselbe Bild noch einmal, formatfüllend und
 * weichgezeichnet, als Füllung der Ränder. Elmar wollte das nicht: „Die
 * Seiten der Bilder sollen einfach ins Schwarze verlaufen. Also das letzte
 * Fünftel soll ins Schwarze verlaufen und somit die Hintergrundfarbe
 * komplett schwarz."
 *
 * Der Verlauf ist deshalb genau so breit wie die Kulisse selbst
 * (Bildhöhe × 2176/1216) und liegt mittig über ihr: Das äußere Fünftel
 * jeder Seite geht in Schwarz über, und was daneben noch bleibt, ist der
 * schwarze Grund der Wand. Auf schmalen Geräten ist der Verlauf breiter
 * als der Schirm — dort fällt er hinaus und ist nicht zu sehen.
 *
 * Er liegt über Standbild UND Feuer (beide z-index 0), aber unter dem
 * Schleier in ::after: gleicher z-index, und ::after kommt später.
 */
.bildwahl::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background-image: linear-gradient(90deg,
        #000 0%,
        rgba(0, 0, 0, 0) 20%,
        rgba(0, 0, 0, 0) 80%,
        #000 100%);
    background-size: calc(100dvh * 2176 / 1216) 100%;
    background-position: center;
    background-repeat: no-repeat;
}

/* Das bewegte Feuer (2026-09-01): dieselbe Kulisse als nahtlose Schleife,
   1920×1088 und 3,5 s. `fixed` wie der Schleier und das Tor — die Wand
   darf scrollen, die Kulisse dahinter soll stehen bleiben, genau wie es
   ein Hintergrundbild täte. */
.bildwahl__feuer {
    /* An der Höhe, wie das Standbild darunter (siehe .bildwahl__standbild).
       Nicht `object-fit`: `contain` legte auf schmalen Geräten Balken OBEN
       und unten an, `cover` schnitt auf breiten die Höhe ab. Eine Höhe von
       100 % bei automatischer Breite trifft beides — der Film steht immer
       in voller Höhe, mittig, und läuft seitlich über, wo er muss. */
    position: fixed;
    top: 0;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: auto;
    max-width: none;
    height: 100%;
    z-index: 0;
    pointer-events: none;
}

/* Der Schleier über der Kulisse, damit Logo und Schrift auf jedem
   Ausschnitt lesbar bleiben — über Standbild UND Feuer, aber unter allem,
   was gelesen oder gedrückt wird. */
.bildwahl::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(rgba(13, 15, 22, .42), rgba(13, 15, 22, .30));
}

/* Die Bühne des ersten Blicks: drei ECHTE Drittel der Bildhöhe — oben
   allein das Logo, mittig der Schriftzug, unten die Sprecher am Feuer
   samt Mitleszeile. Flex-Drittel statt gerechneter Pixel: Sie stimmen
   auf jedem Gerät. */
.bildwahl__buehne {
    min-height: calc(100dvh - 2 * var(--s5));
    display: flex;
    flex-direction: column;
}
.bildwahl__drittel {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 0;
}
/* Das Logo rutscht in seinem Drittel etwas nach unten (Wunsch
   2026-08-28) — nur das Logo, die übrigen Drittel bleiben unberührt. */
.bildwahl__drittel--logo .bildwahl__logo { margin: 7vh 0 0; }
.bildwahl__drittel .bildwahl__kopf { margin: 0; }
/* Logo und Schriftzug rücken zusammen (Wunsch 3.9.2026): Das Logo sitzt am
   unteren Rand seines Drittels, der Schriftzug am oberen des seinen — der
   Abstand zwischen beiden ist damit ein fester kleiner Wert statt eines
   Drittels der Bildhöhe. Die Sprecher rutschen dafür etwas nach unten; die
   Mitleszeile ist aus dem Bild (unten), das Drittel gehört den Gesichtern. */
.bildwahl__drittel--logo { flex: .8; justify-content: flex-end; padding-bottom: var(--s2); }
.bildwahl__drittel--kopf { flex: .7; justify-content: flex-start; }
/* Die Gesichter rücken vom Feuer weg nach oben (Wunsch 3.9.2026, zweite
   Runde): ihr Drittel beginnt oben statt in der Mitte. */
.bildwahl__drittel--feuer { flex: 1.5; justify-content: flex-start; }
.bildwahl__drittel--feuer .sprecherwahl { margin: 1vh 0 .6rem; }

/* Über den Schleier gehoben: ohne eigene Ebene läge der Inhalt unter dem
   ::after und damit hinter dem Nebel, den er nur durchscheinen lassen soll. */
.bildwahl__innen { max-width: 60rem; text-align: center; position: relative; z-index: 2; }

/* Das Logo über dem Titel — gezeichnet in halber Größe der 192er-Datei,
   damit es auf hochauflösenden Bildschirmen scharf bleibt. */
.bildwahl__logo {
    display: block;
    /* Präsenter (2026-08-28): Das Logo ist der Absender des ganzen ersten
       Eindrucks — von 6 auf 9 rem, mit einem Hauch Mondschein dahinter. */
    width: 9rem;
    height: 9rem;
    margin: 0 auto var(--s3);
    filter: drop-shadow(0 0 24px rgba(240, 163, 92, .35));
}

.bildwahl__kopf {
    font-family: var(--schrift-display);
    font-size: var(--f-riesig);
    margin-bottom: var(--s2);
}

/* ---- Die Spielführer am Lagerfeuer (Erstwahl) ----
 *
 * Fünf runde Porträts wie die olympischen Ringe: drei oben, zwei darunter
 * mittig. Zwei Zustände, zwei Zeichen — beide bewusst getrennt gehalten:
 *
 *   grün, pulsierend   „spricht gerade" — dieselbe Sprache wie die
 *                      Sprechanzeige im Sprachchat und in der Vorführung
 *   Glut, ruhig        „gewählt" — die Farbe des glühenden Eisens, in der
 *                      auch die Knöpfe des Spiels gehalten sind
 *
 * Wären beide grün, hieße dasselbe Zeichen zwei verschiedene Dinge.
 */
.sprecherwahl {
    display: flex;
    flex-direction: column;
    gap: .55rem;
    /* Etwas Luft unter dem Schriftzug — die Runde am Feuer ist ein eigener
       Auftritt, kein Anhängsel der Überschrift. Nach unten versetzt und
       vergrößert (2026-08-28): Die Gesichter SIND der Auftritt. */
    margin: 2.2rem 0 1.1rem;
}
.sprecherwahl__reihe {
    display: flex;
    justify-content: center;
    gap: clamp(.8rem, 4vw, 1.6rem);
}
.sprecher {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .3rem;
}
.sprecher__bild {
    /* Eng beschnittene Gesichter — nur so bleiben sie auch mit 64 Punkten
       am Handy erkennbar. Die Untergrenze ist zugleich das Tippziel. */
    width: clamp(78px, 19.5vw, 118px);
    height: clamp(78px, 19.5vw, 118px);
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--rand, #444);
    transition: border-color .25s var(--kurve), box-shadow .25s var(--kurve),
                transform .15s var(--kurve);
}
/* Rahmen für Porträt und Sprechfilm übereinander (3.9.2026): Der Clip, in
   dem der Spielführer seinen Satz spricht, liegt innerhalb des 3-px-Rands
   über dem Standbild und blendet ein, sobald er läuft — Bild 0 des Clips ist
   das Porträt selbst, also springt nichts. Der grüne Puls bleibt am Bild. */
.sprecher__rahmen {
    position: relative;
    line-height: 0;
    transition: transform .15s var(--kurve);
}
.sprecher__film {
    position: absolute;
    inset: 3px;
    width: calc(100% - 6px);
    height: calc(100% - 6px);
    border-radius: 50%;
    object-fit: cover;
    opacity: 0;
    transition: opacity .25s var(--kurve);
    pointer-events: none;
}
.sprecher__film--an { opacity: 1; }
.sprecher:hover .sprecher__rahmen { transform: scale(1.05); }
.sprecher:focus-visible { outline: none; }
.sprecher:focus-visible .sprecher__bild { box-shadow: 0 0 0 3px var(--dorf); }
.sprecher--spricht .sprecher__bild {
    border-color: var(--gruen);
    animation: sprecher-puls 1.6s ease-in-out infinite;
}
.sprecher--gewaehlt .sprecher__bild {
    border-color: var(--eisen-glut);
    box-shadow: 0 0 14px rgba(240, 163, 92, .45);
}
/* Gewählt UND sprechend (die Antwort nach dem Tippen): Der Puls hat
   Vortritt — dass gesprochen wird, ist der flüchtigere Zustand. */
.sprecher--gewaehlt.sprecher--spricht .sprecher__bild { border-color: var(--gruen); }
.sprecher__name {
    font-size: var(--f-klein);
    color: var(--text-leise);
}
.sprecher--gewaehlt .sprecher__name { color: var(--eisen-glut); }
@keyframes sprecher-puls {
    50% { box-shadow: 0 0 0 6px rgba(95, 184, 122, .25); }
}
@media (prefers-reduced-motion: reduce) {
    .sprecher--spricht .sprecher__bild { animation: none; box-shadow: 0 0 0 4px rgba(95, 184, 122, .3); }
    .sprecher:hover .sprecher__rahmen { transform: none; }
}

/* Die Stimmenwahl im Profil — dieselben Gesichter, im Kleinen.
 *
 * Einzeilig, aber nicht winzig: Die fünf Köpfe standen bis zum 2026-08-31
 * fest auf 44 Punkten, während im Dialog am Schreibtisch 479 px zur Verfügung
 * standen — mehr als die Hälfte der Zeile blieb leer, und eine Stimme soll
 * sich nach ihrem Gesicht wählen lassen. Jetzt teilen sie sich die Breite
 * und wachsen bis 5,5 rem mit: gemessen rund 44 px auf einem 320er Handy
 * (also so groß wie bisher, jetzt aber garantiert innerhalb der Zeile) und
 * rund 88 px am Schreibtisch — doppelt so groß wie zuvor. Die untere
 * Schranke hält das Tippziel brauchbar, der mitwachsende Abstand die Reihe
 * einzeilig. Gewählt trägt denselben Glutrand wie am Lagerfeuer — nur dünner.
 */
.stimmwahl {
    display: flex;
    gap: clamp(.3rem, 1.4vw, .55rem);
    flex-wrap: nowrap;
    margin: .3rem 0 .2rem;
}
.stimmwahl__knopf {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .15rem;
    /* Sie teilen sich die Zeile, statt auf 44 Punkten zu verharren — siehe
       den Absatz über dieser Regel. */
    flex: 1 1 0;
    min-width: 2.5rem;
    max-width: 5.5rem;
}
.stimmwahl__knopf:disabled { opacity: .35; cursor: default; }
.stimmwahl__bild {
    width: 100%;
    height: auto;
    aspect-ratio: 1;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--rand, #444);
    transition: border-color .2s var(--kurve), box-shadow .2s var(--kurve);
}
.stimmwahl__knopf--aktiv .stimmwahl__bild {
    border-color: var(--eisen-glut);
    box-shadow: 0 0 8px rgba(240, 163, 92, .4);
}
.stimmwahl__name {
    font-size: var(--f-klein);
    color: var(--text-leise);
    /* „Mechthild" ist breiter als ihr Kopf auf einem schmalen Gerät — der
       Name wird gekürzt, statt die Reihe auseinanderzuziehen. */
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.stimmwahl__knopf--aktiv .stimmwahl__name { color: var(--eisen-glut); }
.stimmwahl__knopf:focus-visible { outline: none; }
.stimmwahl__knopf:focus-visible .stimmwahl__bild { box-shadow: 0 0 0 3px var(--dorf); }

/* Die Weltwahl im Profil — dieselben Karten wie am Lagerfeuer, im Kleinen.
 *
 * Vier Karten teilen sich EINE Zeile (`flex: 1 1 0`), damit die Reihe auch im
 * Dialog auf einem 320er Handy vollständig dasteht: dort bleiben innen 238 px,
 * abzüglich dreier Lücken also rund 53 px je Karte — im Hochformat der
 * Rollenbilder ergibt das etwa 53 × 78. Klein, aber man sieht sofort, ob das
 * Dorf düster oder freundlich ist, und genau darum geht es bei dieser Wahl.
 * Nach oben deckelt `max-width`: Am Schreibtisch sollen daraus keine Plakate
 * werden — das Profil ist eine Liste, kein zweiter Auftritt.
 */
.weltwahl {
    display: flex;
    flex-wrap: nowrap;
    gap: .55rem;
    margin: .3rem 0 .2rem;
}

.weltwahl__karte {
    /* Kein Warten auf einen möglichen Doppeltipp — siehe .knopf. */
    touch-action: manipulation;
    flex: 1 1 0;
    min-width: 0;
    max-width: 7rem;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .2rem;
}
.weltwahl__karte:disabled { opacity: .35; cursor: default; }

.weltwahl__bild {
    width: 100%;
    height: auto;
    aspect-ratio: 640 / 936;
    object-fit: cover;
    border-radius: var(--r-klein);
    border: 2px solid var(--rand);
    transition: border-color .2s var(--kurve), box-shadow .2s var(--kurve);
}
/* Gewählt trägt denselben Glutrand wie die Sprecherwahl darunter. */
.weltwahl__karte--aktiv .weltwahl__bild {
    border-color: var(--eisen-glut);
    box-shadow: 0 0 8px rgba(240, 163, 92, .4);
}

.weltwahl__name {
    font-size: var(--f-klein);
    color: var(--text-leise);
    /* Lange Namen kürzen, statt die Karte breiter zu ziehen — sonst bricht
       die Reihe genau auf dem schmalen Gerät, für das sie gebaut ist. */
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.weltwahl__karte--aktiv .weltwahl__name { color: var(--eisen-glut); }

.weltwahl__karte:focus-visible { outline: none; }
.weltwahl__karte:focus-visible .weltwahl__bild { box-shadow: 0 0 0 3px var(--dorf); }

.bildwahl__frage {
    color: var(--text-leise);
    max-width: 34rem;
    margin: 0 auto var(--s6);
}

.bildwahl__reihe {
    display: grid;
    gap: var(--s4);
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
}

.bildwahl__kachel {
    /* Kein Warten auf einen möglichen Doppeltipp — siehe .knopf. */
    touch-action: manipulation;
    display: flex;
    flex-direction: column;
    gap: var(--s2);
    padding: var(--s3) var(--s3) var(--s4);
    border: 1px solid var(--rand);
    border-radius: var(--r-gross);
    background: var(--flaeche);
    cursor: pointer;
    transition: transform var(--zeit-kurz) var(--kurve),
                border-color var(--zeit-kurz) var(--kurve),
                box-shadow var(--zeit-kurz) var(--kurve);
}
@media (hover: hover) {
    .bildwahl__kachel:hover, .bildwahl__kachel:focus-visible {
        transform: translateY(-3px);
        border-color: color-mix(in srgb, var(--mond) 60%, var(--rand));
        box-shadow: var(--schatten-mond);
    }
}


.bildwahl__bildrahmen { position: relative; width: 100%; aspect-ratio: 640 / 936; }
.bildwahl__bild {
    width: 100%;
    height: auto;
    aspect-ratio: 640 / 936;
    object-fit: cover;
    border-radius: var(--r-mittel);
}
/* Der Film liegt über dem Standbild und wird beim Beleben eingeblendet —
   das Standbild bleibt darunter, falls das Video hakt (3.9.2026). */
.bildwahl__film {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--r-mittel);
    opacity: 0;
    transition: opacity var(--zeit-kurz) var(--kurve);
    pointer-events: none;
}
.bildwahl__film--an { opacity: 1; }

.bildwahl__titel {
    font-family: var(--schrift-display);
    font-weight: 700;
    font-size: var(--f-gross);
    color: var(--text);
}

.bildwahl__text { color: var(--text-leise); font-size: var(--f-klein); }

/* Die mitzulesende Begrüßung — DIREKT unter den Gesichtern, die dazu grün
   pulsieren (vorher stand sie unter den Kacheln, 1770 px von den Sprechern
   entfernt). Mindesthöhe, damit nichts springt, wenn die erste Stimme
   einsetzt. */
.bildwahl__ansage {
    /* Seit 3.9.2026 nicht mehr im Bild (Wunsch Elmar): Die Begrüßung wird
       gesprochen, nicht gelesen. Die Zeile bleibt als Live-Region für
       Bildschirmleser — unsichtbar wie .nur-vorlesen (base.css). */
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ---- Das Tor (2026-08-28) ----
 *
 * Ein Versprechen und EIN Knopf — und der Knopf ist die Nutzergeste, ohne
 * die kein Browser Ton abspielt. Deshalb Vollbild-Schleier statt Banner in
 * der Ecke: Ein Banner wird ignoriert, und ignoriert hieße stummes Feuer,
 * wie all die Monate zuvor. Der Seiteninhalt bleibt dahinter im DOM. */
.bildwahl__tor {
    position: fixed;
    inset: 0;
    z-index: 230;
    display: grid;
    place-items: center;
    padding: var(--s5);
    background: color-mix(in srgb, var(--grund) 55%, transparent);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}
.bildwahl__torkarte {
    max-width: 26rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: var(--s4);
    padding: var(--s6) var(--s5);
    background: var(--grund-erhoben);
    border: 1px solid color-mix(in srgb, var(--mond) 30%, var(--rand));
    border-radius: var(--r-gross);
    box-shadow: var(--schatten), var(--schatten-mond);
}
.bildwahl__torzeile {
    font-family: var(--schrift-display);
    font-size: var(--f-gross);
    margin: 0;
    text-wrap: balance;
}
.bildwahl__tortext { color: var(--text-leise); margin: 0; }
.bildwahl__torton  { color: var(--text-still); font-size: var(--f-klein); margin: 0; }

/* Pflichtangaben am Tor (14.09.2026). Das Tor deckt die Seite vollständig
   ab — auch die Fußzeile und den Fuß der Erstwahl darunter. Impressum und
   Datenschutz müssen aber vom allerersten Bildschirm an erreichbar sein,
   also stehen sie hier noch einmal. Der KI-Hinweis darüber (.ki-hinweis)
   steht rechtsbündig in der Ecke der Karte, wie überall an einer Wahl. */
.bildwahl__torfuss {
    margin-top: calc(var(--s2) * -1);
    font-size: var(--f-winzig);
}
.bildwahl__torfuss a { color: var(--text-still); margin: 0 var(--s3); }

/* Die Abkürzung für Eilige — dezent in der Ecke, über dem Inhalt, unter
   dem Tor. Nach der Vorstellungsrunde entfernt sie sich selbst. */
.bildwahl__abkuerzung {
    position: fixed;
    top: var(--s4);
    right: var(--s4);
    z-index: 225;
}

/* Die Pflichtlinks am Ende der Erstwahl — dieselben vier Ziele wie im
   Seitenfuß, den das Vollbild der Erstwahl sonst verdeckt. */
.bildwahl__fuss {
    margin-top: var(--s6);
    padding: var(--s4) 0 var(--s2);
    font-size: var(--f-winzig);
    text-align: center;
}
.bildwahl__fuss a {
    color: var(--text-still);
    margin: 0 var(--s3);
}

/* Die Weltwahl wartet auf ihr Stichwort (Zeile 07). Verborgen heißt:
   unsichtbar und unklickbar, aber der Platz ist schon vergeben — beim
   Erscheinen springt nichts, es wird nur hell. */
.bildwahl__weltwahl {
    transition: opacity .9s var(--kurve), transform .9s var(--kurve);
}
.bildwahl__weltwahl--verborgen {
    opacity: 0;
    visibility: hidden;
    transform: translateY(14px);
}

/* Auf schmalen Bildschirmen: die vier Welten als 2×2 statt als Turm —
   alle auf einen Blick, wenn Jutta sie ankündigt. Die Beschreibungszeile
   weicht dem Platz; Titel und Bild sagen genug, und die Frage darüber
   erklärt den Rest. Die Bilder behalten dabei ihr volles Hochformat
   (640/936, das Maß der Dateien selbst) — beschnittene Werwölfe waren
   kein Schaufenster (Wunsch 2026-08-28). */
@media (max-width: 34rem) {
    .bildwahl__reihe { grid-template-columns: 1fr 1fr; gap: var(--s3); }
    .bildwahl__text { display: none; }
    .bildwahl__kachel { padding: var(--s2) var(--s2) var(--s3); }
}

/* Sinnbild in Listengröße — Freundesliste, Anfragen, Gesprächskopf.
   Steht hier und nicht in components.css: .spieler__bild darüber setzt
   `width: 100%`, und diese Datei wird später geladen. Bei gleicher
   Spezifität gewinnt die spätere Regel. */
.spieler__bild--klein {
    width: 2rem;
    height: 2rem;
    flex: none;
    font-size: 1.1rem;
    border-radius: 50%;
}

/* ============================================================ Fingerübung
   Der Zeitvertreib für alle, die nachts nichts zu tun haben („Jeder sein
   Gerät", 17.10.2026) — siehe ui/fingeruebung.js. */
.finger__kopf { display: flex; justify-content: space-between; align-items: center; gap: var(--s3); }
.finger__marke {
    font-size: var(--f-winzig);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-still);
}
.finger__zaehler { font-size: var(--f-klein); color: var(--mond); font-variant-numeric: tabular-nums; }
.finger__titel { margin: 0; }
.finger__flaeche {
    position: relative;
    height: 13.5rem;
    border-radius: var(--r-mittel);
    background: radial-gradient(ellipse at 50% 30%, var(--flaeche-hoch), var(--grund) 75%);
    border: 1px solid var(--rand);
    overflow: hidden;
    touch-action: manipulation;
    user-select: none;
    -webkit-user-select: none;
}
.finger__ding {
    position: absolute;
    transform: translate(-50%, -50%);
    width: var(--tippziel); height: var(--tippziel);
    padding: 0;
    border-radius: 50%;
    border: 2px solid var(--rand-hell);
    background: var(--flaeche);
    color: var(--text);
    font: inherit;
    font-weight: 700;
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: left .18s var(--kurve), top .18s var(--kurve), opacity var(--zeit) var(--kurve),
                background var(--zeit-kurz) var(--kurve), border-color var(--zeit-kurz) var(--kurve);
    -webkit-tap-highlight-color: transparent;
}
.finger__ding--falsch { border-color: var(--blut); background: color-mix(in srgb, var(--blut) 25%, var(--flaeche)); }
.finger__ding--erledigt { opacity: .25; }

.finger__punkt { background: var(--mond); border-color: var(--mond-tief); box-shadow: var(--schatten-mond); }

.finger__gluehwurm { opacity: .12; border-color: transparent; background: var(--eigen); width: 2.4rem; height: 2.4rem; }
.finger__gluehwurm--an { opacity: 1; box-shadow: 0 0 18px 6px color-mix(in srgb, var(--eigen) 60%, transparent); }

.finger__zahl { font-size: var(--f-gross); }

.finger__kerze {
    border-radius: 6px 6px 4px 4px;
    width: 2rem; height: 3.6rem;
    background: color-mix(in srgb, var(--text) 85%, var(--mond));
    border-color: transparent;
}
.finger__kerze::before {
    content: "";
    position: absolute;
    left: 50%; top: -1.1rem;
    width: .9rem; height: 1.3rem;
    transform: translateX(-50%);
    border-radius: 50% 50% 45% 45%;
    background: radial-gradient(circle at 50% 70%, #fff6c8, var(--eigen) 55%, transparent 72%);
    opacity: 0;
    transition: opacity var(--zeit-kurz) var(--kurve);
}
.finger__kerze--an::before { opacity: 1; animation: finger-flackern .5s infinite alternate; }
@keyframes finger-flackern { from { transform: translateX(-50%) scale(1); } to { transform: translateX(-52%) scale(1.12, .92); } }

.finger__mond {
    position: absolute;
    left: 50%; top: 50%;
    width: 7rem; height: 7rem;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: radial-gradient(circle at 38% 35%, #fffbe8, #f3e3b0 60%, #cdb77c);
    box-shadow: 0 0 40px rgba(255, 240, 190, .35);
}
.finger__nebel {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    grid-template-rows: repeat(5, 1fr);
    touch-action: none;
}
.finger__schwade {
    background: color-mix(in srgb, var(--text-still) 70%, var(--grund));
    transition: opacity .35s var(--kurve);
}
.finger__schwade--weg { opacity: 0; }

.finger__paare {
    position: absolute;
    inset: var(--s3);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s2);
}
.finger__paar,
.finger__zeichen {
    border-radius: var(--r-klein);
    border: 1px solid var(--rand-hell);
    background: var(--flaeche-hoch);
    color: var(--mond);
    font: inherit;
    font-size: 1.6rem;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.finger__paar--offen { background: var(--flaeche); }
.finger__paar:disabled { opacity: .45; }

.finger__raster {
    position: absolute;
    inset: var(--s3);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s2);
}
.finger__zeichen { color: var(--text); }

.finger__bahn {
    position: absolute;
    left: 8%; right: 8%; top: 32%;
    height: 3rem;
    border-radius: var(--r-rund);
    background: var(--grund);
    border: 1px solid var(--rand);
}
.finger__ziel {
    position: absolute;
    left: 40%; width: 16%; top: 0; bottom: 0;
    background: color-mix(in srgb, var(--mond) 25%, transparent);
    border-left: 2px solid var(--mond);
    border-right: 2px solid var(--mond);
    transition: background var(--zeit-kurz) var(--kurve);
}
.finger__ziel--treffer { background: color-mix(in srgb, var(--gruen) 60%, transparent); }
.finger__laterne {
    position: absolute;
    top: 50%;
    width: 8%; height: 2.2rem;
    transform: translateY(-50%);
    border-radius: 40%;
    background: radial-gradient(circle, #fff1c2, var(--eigen) 70%);
    box-shadow: 0 0 14px color-mix(in srgb, var(--eigen) 70%, transparent);
}
.finger__tipp { position: absolute; left: 50%; bottom: 12%; transform: translateX(-50%); min-width: 8rem; }

.finger__stern { color: var(--text-still); font-size: 1.4rem; background: transparent; border-color: var(--rand); }
.finger__stern--an { color: #fff6c8; border-color: var(--eigen); background: color-mix(in srgb, var(--eigen) 40%, transparent); }

.finger__schaf {
    left: -10%;
    font-size: 1.6rem;
    background: transparent;
    border-color: transparent;
    animation: finger-wiese linear forwards;
}
.finger__schaf--gezaehlt { opacity: 0; transform: translate(-50%, -90%) scale(1.3); }
@keyframes finger-wiese { from { left: -8%; } to { left: 108%; } }

@media (prefers-reduced-motion: reduce) {
    .finger__ding { transition: none; }
    .finger__kerze--an::before { animation: none; }
}
