/* Vibe Shot – Oberfläche. Mobil zuerst, Systemschrift, iOS-Systemfarben. */

:root {
    --bg: #ffffff;
    --text: #000000;
    --text2: rgba(60, 60, 67, 0.6);
    --text3: rgba(60, 60, 67, 0.4);
    --fill: #f2f2f7;
    --fill2: #e5e5ea;
    --line: rgba(60, 60, 67, 0.2);
    --line-fein: rgba(60, 60, 67, 0.14);
    --akzent: #007aff;
    --gefahr: #ff3b30;
    --leiste: rgba(249, 249, 249, 0.94);
    --kachel: #e9e9ee;
    --flaeche: #ffffff;
    --radius: 12px;
    --oben: env(safe-area-inset-top, 0px);
    --unten: env(safe-area-inset-bottom, 0px);
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #000000;
        --text: #ffffff;
        --text2: rgba(235, 235, 245, 0.6);
        --text3: rgba(235, 235, 245, 0.35);
        --fill: #1c1c1e;
        --fill2: #2c2c2e;
        --line: rgba(235, 235, 245, 0.18);
        --line-fein: rgba(235, 235, 245, 0.12);
        --akzent: #0a84ff;
        --gefahr: #ff453a;
        --leiste: rgba(22, 22, 24, 0.94);
        --kachel: #1c1c1e;
        --flaeche: #1c1c1e;
    }
}

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

html, body {
    margin: 0;
    min-height: 100%;
    overscroll-behavior-y: none;
    /* Beim Zoomwechsel läuft das Raster kurz über die Seitenbreite
       hinaus. "clip" schneidet das ab, ohne – anders als "hidden" –
       einen eigenen Scrollbereich aufzumachen; genau der hat vorher den
       hellen Streifen unten verursacht. */
    overflow-x: clip;
    /* Falls doch einmal etwas durchscheint: nicht weiß, sondern der
       Grundton der Oberfläche. */
    background: var(--bg);
}

body {
    /* Mindestens so hoch wie der GRÖSSTE Bildschirmausschnitt – also der
       mit eingezogenen Safari-Leisten. "100%" wäre der kleinste, und
       genau die Differenz stand vorher als heller Streifen unten: Auf
       der Fotowand fiel sie nicht auf, weil dort ohnehin tausende Kacheln
       darunter liegen, auf jeder kürzeren Seite schon. */
    min-height: 100vh;
    background: var(--bg);
    color: var(--text);
    font: 17px/1.4 -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", system-ui, sans-serif;
    -webkit-font-smoothing: antialiased;
    -webkit-text-size-adjust: 100%;
}

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--akzent); text-decoration: none; }

/* ---------------------------------------------------------- Grundgerüst */

/* Die Fotowand soll bis an alle vier Kanten reichen. Deshalb füllt das
   Blatt den ganzen Bildschirm, und Kopf wie Reiterleiste liegen darüber
   statt daneben – sonst nehmen sie der Wand oben und unten je hundert
   Pixel weg und hinterlassen genau die weißen Kästen, die stören. */
/* Gescrollt wird das Dokument selbst – nicht ein Kasten darin.
   Vorher hing die ganze Oberfläche in einer fixierten Hülle mit einem
   eigenen Scrollbereich. Das sieht auf dem Schreibtisch gleich aus,
   bricht auf dem iPhone aber an einer Stelle: Safari zieht die
   Adressleiste nur ein, wenn das DOKUMENT scrollt. Tut es das nicht,
   bleibt die Hülle so hoch wie der kleine Bildschirmausschnitt, und
   darunter scheint die Seitenfläche durch – der helle Streifen.

   Mit normalem Dokument-Scrollen verhält sich die Seite wie jede
   andere Webseite auch: Der Hintergrund reicht immer bis zur
   Unterkante, egal wo die Leisten gerade stehen. */
#app {
    display: block;
}

.blatt {
    padding-top: var(--oben);
    padding-bottom: calc(96px + var(--unten));
}

/* Randlos: Das Raster läuft hinter dem Glaskopf durch – aber es fängt
   nicht unter ihm an, sondern hinter ihm. Sonst liegen die obersten
   zwei Reihen für immer unter dem Kopf und sind nicht erreichbar: Man
   scrollt bis zum Anschlag und kommt trotzdem nicht an sie heran.

   iOS nennt das "content inset": So viel Platz oben, wie die Leiste
   hoch ist – gescrollt wird darunter durch. Die Höhe setzt app.js,
   weil sie von Schriftgröße und Statusleiste abhängt; der Wert hier
   ist nur die Notbremse, falls das Skript nicht dazu kommt. */
.blatt.randlos { padding-top: var(--kopfhoehe, 148px); }

.kopf {
    padding: 14px 16px 8px;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
}

.kopf h1 {
    margin: 0;
    font-size: 34px;
    line-height: 41px;
    font-weight: 700;
    letter-spacing: -0.4px;
}

.kopf-zeile {
    padding: 0 16px 10px;
    font-size: 13px;
    color: var(--text2);
}

.text-knopf.gefahr-text { color: var(--gefahr); font-size: 15px; padding: 0; }

.text-knopf {
    border: 0;
    background: transparent;
    color: var(--akzent);
    font-size: 17px;
    padding: 0 0 6px;
    min-height: 44px;
}

/* --------------------------------------------------------- Glaskopf

   Titel, Hochladen und Segmentwähler schweben über der Fotowand. Der
   Milchglas-Streifen darunter löst sich nach unten auf – ohne diese
   Auflösung säße eine harte Kante mitten auf den Bildern, und genau
   die liest sich als weißer Kasten.                                   */

.kopf-glas {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 5;
    padding: calc(var(--oben) + 6px) 0 14px;
    transition: padding 0.22s ease;
    /* Deutlich leichter als vorher. Die Deckung macht jetzt die
       Unschärfe darunter, nicht die Farbe: 0,94 Weiß hat die Fotos
       ausgebleicht, statt sie durchscheinen zu lassen. */
    background: linear-gradient(to bottom,
        rgba(250, 250, 252, 0.62) 0%,
        rgba(250, 250, 252, 0.54) 52%,
        rgba(250, 250, 252, 0.3) 80%,
        rgba(250, 250, 252, 0) 100%);
}

/* Das Milchglas liegt auf den FOTOS, nicht auf der Schrift.
   Eine eigene Schicht mit Maske: oben voll, nach unten auslaufend – so
   gibt es keine harte Kante, an der die Unschärfe aufhört.

   "z-index: -1" ist hier der entscheidende Teil und diesmal belegt,
   nicht gehofft: Innerhalb eines Stapelzusammenhangs werden negative
   Kinder NACH dem Hintergrund des Elements gemalt, aber VOR dessen
   Inhalt. Der Kopf ist wegen "position: fixed" und "z-index: 5" ein
   eigener Stapelzusammenhang, die Schicht kann also nicht daraus
   ausbrechen – und über dem Titel landen kann sie ebenso wenig.
   Genau daran war der erste Anlauf gescheitert: Die Scheibe war ein
   Geschwisterelement, kein negatives Kind. */
.kopf-glas::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    -webkit-backdrop-filter: blur(18px) saturate(170%);
    backdrop-filter: blur(18px) saturate(170%);
    -webkit-mask-image: linear-gradient(to bottom,
        #000 0%, #000 58%, rgba(0, 0, 0, 0.45) 82%, transparent 100%);
    mask-image: linear-gradient(to bottom,
        #000 0%, #000 58%, rgba(0, 0, 0, 0.45) 82%, transparent 100%);
}

@media (prefers-color-scheme: dark) {
    .kopf-glas {
        /* Oben bewusst nicht ganz deckend: Sonst säuft der Kopf in
           Schwarz ab und wirkt wie ein abgeschnittener Balken statt wie
           eine Fotowand, die darunter durchläuft. */
        background: linear-gradient(to bottom,
            rgba(12, 12, 14, 0.66) 0%,
            rgba(12, 12, 14, 0.58) 52%,
            rgba(12, 12, 14, 0.32) 80%,
            rgba(12, 12, 14, 0) 100%);
    }
}

/* Der Verlauf ist der HINTERGRUND des Kopfes, kein eigenes Element.
   Das ist der Kern der ganzen Geschichte. Vier Anläufe mit einer
   eigenen Scheibe sind gescheitert – zuletzt mit gemessenen Zahlen:
   Der Titel kam nur auf 140 von 255 Helligkeit, der Text daneben auf
   volle 255. Die Scheibe wurde also ÜBER den Titel gemalt, obwohl ihr
   z-index niedriger war.
   Der Hintergrund eines Elements liegt immer unter dessen eigenem
   Inhalt – das steht in der Malreihenfolge und lässt sich nicht
   verdrehen. Kein z-index, kein Stapelzusammenhang, keine Ausnahme.
   Die Auflösung nach unten macht der Verlauf selbst, über seine
   Deckkraft. Damit entfällt auch die Maske, die das vorher erzwungen
   hat – und mit ihr die Filterschicht, die den Titel weichgezeichnet
   hat. */

/* Der Inhalt liegt über der Scheibe – ausdrücklich, nicht zufällig. */
.kopf-oben,
.kopf-glas .segmente {
    position: relative;
    z-index: 1;
}

.kopf-oben {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 16px 10px;
}

.kopf-oben h1 {
    margin: 0;
    /* Ausdrücklich, nicht geerbt – damit keine Klasse am Kopf ihn je
       wieder umfärben kann. */
    color: var(--text);
    font-size: 32px;
    line-height: 38px;
    font-weight: 700;
    letter-spacing: -0.5px;
    transition: font-size 0.22s ease, line-height 0.22s ease;
}

.kopf-oben .luecke { flex-grow: 1; }

/* Beim Scrollen schrumpft der Titel – der Wähler bleibt, er wird
   gebraucht.

   Die Klasse heißt "geschrumpft" und nicht "klein", und das ist keine
   Wortklauberei: ".klein" gibt es in dieser Datei schon als allgemeines
   Hilfsmittel für kleine graue Beschriftungen, mitsamt
   "color: var(--text2)". Hing sie am Kopf, erbte der Titel diese Farbe
   und wurde beim Scrollen zu halbdurchsichtigem Grau.
   Das sah aus wie Unschärfe – und hat uns einen halben Tag gekostet,
   weil wir beide nach einem Filter gesucht haben. */
.kopf-glas.geschrumpft { padding-bottom: 10px; }
.kopf-glas.geschrumpft .kopf-oben { padding-bottom: 6px; }
.kopf-glas.geschrumpft .kopf-oben h1 { font-size: 19px; line-height: 24px; }

/* Knöpfe im Glaskopf sind selbst kleine Glaspillen – flacher Text
   verschwindet über hellen Fotos. */
.glas-pille {
    border: 0;
    border-radius: 17px;
    padding: 7px 14px;
    min-height: 34px;
    font-size: 15px;
    font-weight: 500;
    color: var(--akzent);
    background: rgba(120, 120, 128, 0.16);
    /* Das Milchglas auf den Knöpfen bleibt. Es war nie die Ursache:
       Der Text darin war in jeder Messung gestochen scharf – gerade
       WEIL er eine eigene Schicht hat. */
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    box-shadow: inset 0 0 0 0.5px rgba(120, 120, 128, 0.18);
}

/* Der Segmentwähler liegt auf Fotos, nicht auf Weiß. Ein schwacher
   Grauton reicht dort nicht: Über einem bunten Motiv verschwindet die
   Schrift, und die drei Wörter schwimmen ohne Halt im Bild. Deshalb
   dasselbe Milchglas wie bei den Zeitraum-Schildchen. */
.kopf-glas .segmente {
    margin: 0 16px;
    background: rgba(244, 244, 247, 0.86);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    box-shadow: 0 1px 5px rgba(0, 0, 0, 0.13), inset 0 0 0 0.5px rgba(255, 255, 255, 0.5);
}

.kopf-glas .segmente button[aria-selected="true"] {
    background: rgba(255, 255, 255, 0.96);
}

@media (prefers-color-scheme: dark) {
    .kopf-glas .segmente {
        background: rgba(34, 34, 36, 0.86);
        box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5), inset 0 0 0 0.5px rgba(255, 255, 255, 0.14);
    }

    .kopf-glas .segmente button[aria-selected="true"] {
        background: rgba(99, 99, 102, 0.95);
    }
}

/* ------------------------------------------------------------ Reiter */

/* Die Leiste unten ist keine Leiste mehr, sondern eine schwebende
   Glaspille – so bleibt die Fotowand auch unten bis zur Kante sichtbar. */
.reiter {
    position: fixed;
    left: 50%;
    bottom: calc(14px + var(--unten));
    transform: translateX(-50%);
    z-index: 6;
    display: flex;
    gap: 2px;
    padding: 5px;
    border-radius: 27px;
    background: rgba(248, 248, 250, 0.74);
    backdrop-filter: saturate(180%) blur(24px);
    -webkit-backdrop-filter: saturate(180%) blur(24px);
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.16), inset 0 0 0 0.5px rgba(255, 255, 255, 0.6);
}

@media (prefers-color-scheme: dark) {
    .reiter {
        background: rgba(38, 38, 40, 0.76);
        box-shadow: 0 6px 22px rgba(0, 0, 0, 0.5), inset 0 0 0 0.5px rgba(255, 255, 255, 0.14);
    }
}

.reiter button {
    width: 68px;
    border: 0;
    border-radius: 22px;
    background: transparent;
    color: var(--text2);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 44px;
    padding: 0;
}

.reiter button[aria-current="page"] { background: rgba(120, 120, 128, 0.16); }

.reiter button[aria-current="page"] { color: var(--akzent); }
.reiter span { font-size: 10px; font-weight: 500; letter-spacing: -0.1px; }
/* Der ausgewählte Reiter bekommt ein gefülltes Symbol, kein zweites
   Farbsignal – so macht es iOS, und man erkennt es auch ohne Farbe. */
.reiter button[aria-current="page"] svg { stroke-width: 2; }

/* ------------------------------------------------------ Segmentwähler */

.segmente {
    display: flex;
    margin: 0 16px 12px;
    background: var(--fill);
    border-radius: 9px;
    padding: 2px;
    gap: 2px;
}

.segmente button {
    flex-grow: 1;
    border: 0;
    background: transparent;
    color: var(--text);
    border-radius: 7px;
    padding: 7px 8px;
    min-height: 34px;
    font-size: 13px;
    white-space: nowrap;
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
}

.segmente button[aria-selected="true"] {
    background: var(--bg);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 0 0 0.5px rgba(0, 0, 0, 0.04);
}

@media (prefers-color-scheme: dark) {
    .segmente button[aria-selected="true"] {
        background: #636366;
        box-shadow: none;
    }
}

.segmente .anzahl { color: var(--text2); font-weight: 400; font-size: 11px; }
.segmente button[aria-selected="true"] .anzahl { color: var(--text2); }

/* ----------------------------------------------------------- Zeitleiste */

/* Die Zeitraum-Schildchen liegen auf dem Raster, nicht darin. Nur so
   kann das Raster durchlaufen – und nur ein durchlaufendes Raster
   zeigt bei kleinen Monaten keine halbleeren Zeilen. */

#zeitleiste { position: relative; }

.marken {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    /* Die Schildchen liegen über den Kacheln – sie dürfen ihnen aber
       nicht die Berührung wegnehmen. */
    pointer-events: none;
    z-index: 3;
}

.marke {
    position: absolute;
    left: 8px;
    margin-top: 8px;
}

.marke b {
    display: inline-block;
    padding: 5px 12px 6px;
    border-radius: 16px;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.2px;
    color: var(--text);
    background: rgba(255, 255, 255, 0.78);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    box-shadow: 0 1px 5px rgba(0, 0, 0, 0.16), inset 0 0 0 0.5px rgba(255, 255, 255, 0.55);
}

@media (prefers-color-scheme: dark) {
    .marke b {
        color: #ffffff;
        background: rgba(40, 40, 42, 0.76);
        box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5), inset 0 0 0 0.5px rgba(255, 255, 255, 0.16);
    }
}

.marke .m-kurz, .marke .m-jahr { display: none; }

/* Je enger das Raster, desto kürzer die Beschriftung. */
#zeitleiste.dicht .raster { gap: 1px; }
#zeitleiste.dicht .marke .m-voll { display: none; }
#zeitleiste.dicht .marke .m-kurz { display: inline; }
#zeitleiste.dicht .marke b { font-size: 14px; padding: 4px 11px 5px; }

#zeitleiste.sehr-dicht .marke b { font-size: 13px; padding: 3px 10px 4px; }

#zeitleiste.jahresweise .marke .m-kurz { display: none; }
#zeitleiste.jahresweise .marke .m-jahr { display: inline; }


.raster {
    display: grid;
    grid-template-columns: repeat(var(--spalten, 3), minmax(0, 1fr));
    gap: 2px;
}

.kachel {
    position: relative;
    aspect-ratio: 1 / 1;
    background: var(--kachel);
    border: 0;
    padding: 0;
    overflow: hidden;
    display: block;
}

.kachel img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    transition: opacity 0.18s ease;
}

.kachel img.da { opacity: 1; }

.kachel .dauer {
    position: absolute;
    right: 5px;
    bottom: 5px;
    color: #fff;
    font-size: 11px;
    font-weight: 500;
    text-shadow: 0 0 3px rgba(0, 0, 0, 0.55);
    display: flex;
    align-items: center;
    gap: 3px;
}

.kachel .stern {
    position: absolute;
    right: 5px;
    top: 5px;
    filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.45));
}

.kachel[aria-selected="true"]::after {
    content: "";
    position: absolute;
    inset: 0;
    border: 3px solid var(--akzent);
    background: rgba(0, 122, 255, 0.18);
}

/* ------------------------------------------------------------ Vollbild */

/* ------------------------------------------------------------ Vollbild

   Entwurfsroute B: Das Bild bekommt die ganze Fläche. Kopf und Fuß
   nehmen ihm nichts weg, sondern schweben darüber und blenden sich
   weg, sobald man sie eine Weile nicht anfasst. Deshalb liegt hier
   alles absolut – nichts teilt sich die Höhe mit dem Motiv.           */

/* Solange das Vollbild offen ist, darf die Seite darunter nicht
   mitscrollen. Weil jetzt das Dokument der Scrollbereich ist, geht das
   nur, indem man den Körper festnagelt und den Scrollstand merkt –
   sonst springt die Wand beim Schließen an den Anfang zurück. */
body.gesperrt {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
    /* Das Vollbild ist eine festgenagelte Schicht. Reicht sie – je nach
       Stand der Safari-Leisten – nicht ganz bis zur Unterkante, scheint
       dort die Seitenfläche durch. Die ist hell. Also färben wir sie für
       die Dauer des Vollbilds schwarz: Dann fällt eine Lücke nicht auf,
       selbst wenn es sie gibt. */
    background: #000000;
}

/* Messanzeige – nur mit ?mess=1 in der Adresse. Sitzt bei "unten null":
   Wo der Balken steht, endet für den Browser der Bildschirm. */
.messanzeige {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 99;
    background: #ff3b30;
    color: #ffffff;
    font: 10px/1.5 ui-monospace, Menlo, monospace;
    padding: 3px 6px;
    pointer-events: none;
}

.vollbild {
    position: fixed;
    inset: 0;
    z-index: 30;
    background: #000000;
    overflow: hidden;
}

/* Die Bühne ist oben etwas eingerückt. Mathematisch mittig sitzt das
   Bild sonst zu hoch: Oben schwebt nur die Zurück-Pille, unten die
   breite Bedienpille – das Auge nimmt die untere als schwerer wahr und
   liest das Bild als nach oben gerutscht. */
.vollbild-buehne {
    position: absolute;
    inset: 0;
    padding-top: calc(60px + var(--oben));
    padding-bottom: 12px;
    overflow: hidden;
    /* Nichts dem Browser überlassen: Wischen, Kneifen und Schieben
       macht hier alles das Skript. Mit "pan-y" käme Safari beim
       Kneifen dazwischen und vergrößerte die ganze Seite. */
    touch-action: none;
}

/* Drei Plätze nebeneinander, dreimal so breit wie die Bühne. Steht der
   Wagen bei -33,3333 %, ist der mittlere Platz im Bild. */
.wagen {
    display: flex;
    width: 300%;
    height: 100%;
    will-change: transform;
}

.platz {
    flex: 0 0 33.3333%;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
}

/* Volle Fläche statt Eigengröße: Ein Bild, das kleiner als der
   Bildschirm ist, soll trotzdem die Fläche füllen – sonst schwimmt es
   in Schwarz. "contain" hält dabei das Seitenverhältnis. */
.platz img,
.platz video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    /* Der Kneifzoom rechnet mit der Mitte als festem Punkt. */
    transform-origin: 50% 50%;
}

/* Erst das Thumbnail, dann die Vorschau – der Weichzeichner macht den
   Wechsel unauffällig. */
.platz img { transition: filter 0.25s ease; }
.platz img.grob { filter: blur(7px); }

.vollbild-oben,
.vollbild-unten {
    position: absolute;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    transition: opacity 0.28s ease, transform 0.28s ease;
}

.vollbild-oben {
    top: calc(20px + var(--oben));
    padding: 0 12px;
}

.vollbild-unten {
    bottom: calc(18px + var(--unten));
    justify-content: center;
    padding: 0 12px;
}

/* Weg damit, sobald das Bild für sich sprechen darf. */
.vollbild.nackt .vollbild-oben { opacity: 0; transform: translateY(-10px); pointer-events: none; }
.vollbild.nackt .vollbild-unten { opacity: 0; transform: translateY(14px); pointer-events: none; }

.vollbild .luecke { flex-grow: 1; }

/* Glas, kein Kasten: Der Hintergrund bleibt sichtbar, die Schrift
   trotzdem lesbar. */
.pille,
.pillen-knopf.allein,
.datums-marke {
    /* Heller als das reine Schwarz ringsum. Mit 28/0,62 verschwanden
       die Pillen über dem schwarzen Rand neben dem Bild fast völlig –
       Glas braucht etwas, worauf es liegt, und hier liegt es oft auf
       nichts. Der Rahmen macht den Rest. */
    background: rgba(58, 58, 62, 0.72);
    -webkit-backdrop-filter: blur(22px) saturate(180%);
    backdrop-filter: blur(22px) saturate(180%);
    box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.22),
                0 2px 12px rgba(0, 0, 0, 0.45);
}

.pille {
    display: flex;
    gap: 2px;
    padding: 4px;
    border-radius: 24px;
}

.pillen-knopf {
    width: 52px;
    height: 44px;
    border: 0;
    border-radius: 20px;
    background: transparent;
    color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    flex-shrink: 0;
}

.pillen-knopf.allein {
    width: 44px;
    border-radius: 22px;
}

.pillen-knopf.gefahr { color: #ff6961; }
.pillen-knopf.laut { color: var(--akzent); }
.pillen-knopf[aria-pressed="true"] svg { fill: currentColor; }
/* Der Ton-Knopf fällt bei Fotos weg – sein Platz aber nicht.
   "display: none" nähme ihn aus dem Flex-Fluss, und die Datumsmarke
   wäre dann zwischen der Zurück-Pille und dem Nichts zentriert: gemessen
   26 Pixel zu weit rechts. Unsichtbar, aber anwesend, hält die Waage. */
.pillen-knopf[hidden] {
    display: flex;
    visibility: hidden;
    pointer-events: none;
}

.datums-marke {
    border-radius: 17px;
    padding: 6px 14px 7px;
    color: #ffffff;
    text-align: center;
    max-width: 58%;
    flex-shrink: 1;
    min-width: 0;
}

.datums-marke b {
    display: block;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: -0.1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.datums-marke span {
    display: block;
    font-size: 11px;
    opacity: 0.72;
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.datums-marke span:empty { display: none; }

/* Beim Video reicht ein Haarstrich – wer mehr will, tippt das Bild an. */
.video-fortschritt {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: rgba(255, 255, 255, 0.22);
}

.video-fortschritt[hidden] { display: none; }

.video-balken {
    height: 100%;
    width: 0;
    background: #ffffff;
    transition: width 0.25s linear;
}

.icon-knopf {
    width: 44px;
    height: 44px;
    border: 0;
    background: transparent;
    color: var(--akzent);
    display: flex;
    align-items: center;
    justify-content: center;
}

.icon-knopf.gefahr { color: var(--gefahr); }
.icon-knopf[aria-pressed="true"] svg { fill: currentColor; }

.angaben {
    padding: 8px 16px 0;
    font-size: 12px;
    color: var(--text2);
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
}

/* ------------------------------------------------------------ Personen */

.kopf.mit-zurueck {
    gap: 4px;
    align-items: center;
    padding-left: 6px;
}

.kopf.mit-zurueck .icon-knopf { flex-shrink: 0; margin-bottom: 2px; }

.person-titel {
    flex-grow: 1;
    margin: 0;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.3px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hinweis {
    margin: 6px 16px 16px;
    padding: 10px 14px;
    background: var(--fill);
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    gap: 12px;
}

.hinweis svg { width: 22px; height: 22px; color: var(--akzent); flex-shrink: 0; }
.hinweis p { margin: 0; flex-grow: 1; font-size: 14px; line-height: 19px; color: var(--text2); }
.hinweis .text-knopf { min-height: 44px; font-size: 15px; font-weight: 500; }

.gruppe-titel {
    padding: 8px 16px 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text2);
    letter-spacing: 0.3px;
}

.personen-raster {
    padding: 0 16px 8px;
    display: grid;
    grid-template-columns: repeat(var(--personen-spalten, 3), minmax(0, 1fr));
    gap: 18px 14px;
}

.personen-raster.eng { --personen-spalten: 4; padding: 0; gap: 14px 10px; }

.person { display: flex; flex-direction: column; align-items: center; gap: 6px; }

.person-bild {
    width: 100%;
    aspect-ratio: 1 / 1;
    border: 0;
    padding: 0;
    border-radius: 50%;
    background: var(--kachel);
    overflow: hidden;
}

.person-bild img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.18s ease;
}

.person-bild img.da, .personen-raster.eng .person-bild img { opacity: 1; }

.person-name {
    font-size: 14px;
    font-weight: 500;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.person-anzahl { font-size: 12px; color: var(--text2); margin-top: -4px; }
.klein-knopf { font-size: 14px; min-height: 22px; padding: 0; }

/* -------------------------------------------------------------- Alben */

.alben-raster {
    padding: 0 16px 16px;
    display: grid;
    grid-template-columns: repeat(var(--alben-spalten, 2), minmax(0, 1fr));
    gap: 18px 14px;
}

.album {
    border: 0;
    background: transparent;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
    text-align: left;
    color: inherit;
}

.album-bild {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--kachel);
}

.album-bild img { width: 100%; height: 100%; object-fit: cover; display: block; }

.album-name {
    font-size: 15px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.album-zahl { font-size: 12px; color: var(--text2); margin-top: -4px; }

/* -------------------------------------------------------------- Suche */

.suchfeld {
    margin: 0 16px 12px;
    padding: 0 12px;
    background: var(--fill);
    border-radius: 10px;
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
}

.suchfeld svg { width: 18px; height: 18px; color: var(--text2); flex-shrink: 0; }

.suchfeld input {
    flex-grow: 1;
    border: 0;
    background: transparent;
    min-height: 40px;
    font-size: 17px;
    outline: none;
    min-width: 0;
}

.suchfeld input::-webkit-search-cancel-button { display: none; }
.suchfeld .text-knopf { font-size: 15px; padding: 0; flex-shrink: 0; }

.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 0 16px 6px;
}

.chip {
    border: 0;
    background: var(--fill);
    color: var(--text);
    border-radius: 16px;
    padding: 7px 13px;
    min-height: 32px;
    font-size: 14px;
    white-space: nowrap;
}

.chip[aria-pressed="true"] { background: var(--akzent); color: #fff; }

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

#karte { position: relative; display: flex; flex-direction: column; }

.karte-buehne {
    position: relative;
    height: 62dvh;
    min-height: 320px;
    overflow: hidden;
    background: var(--fill);
    touch-action: none;
    cursor: grab;
    user-select: none;
}

.karte-buehne:active { cursor: grabbing; }
.karte-kacheln, .karte-marken { position: absolute; inset: 0; }
.karte-marken { pointer-events: none; }

.karte-kachel {
    position: absolute;
    width: 256px;
    height: 256px;
    display: block;
}

@media (prefers-color-scheme: dark) {
    .karte-kachel { filter: invert(1) hue-rotate(180deg) brightness(0.92) contrast(0.92); }
}

.karte-marke {
    position: absolute;
    width: 46px;
    height: 46px;
    margin: -23px 0 0 -23px;
    border: 0;
    padding: 0;
    background: transparent;
    pointer-events: auto;
}

/* Bild und Anzahl getrennt: Der Kreis schneidet ab, die Zahl darf
   überstehen. Beides in einem Element ginge nicht. */
.karte-marke-bild {
    display: block;
    width: 100%;
    height: 100%;
    border: 2px solid #fff;
    border-radius: 50%;
    overflow: hidden;
    background: var(--kachel);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}

.karte-marke img { width: 100%; height: 100%; object-fit: cover; display: block; }

.karte-anzahl {
    position: absolute;
    right: -3px;
    top: -3px;
    min-width: 19px;
    height: 19px;
    border-radius: 10px;
    background: var(--akzent);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    line-height: 19px;
    text-align: center;
    padding: 0 4px;
    border: 1.5px solid var(--bg);
}

.karte-zoom {
    position: absolute;
    right: 12px;
    top: 12px;
    display: flex;
    flex-direction: column;
    border-radius: 9px;
    overflow: hidden;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}

.karte-zoom button {
    width: 40px;
    height: 40px;
    border: 0;
    background: var(--flaeche);
    color: var(--text);
    font-size: 20px;
    line-height: 1;
}

.karte-zoom button + button { border-top: 0.5px solid var(--line); }

.karte-nachweis {
    padding: 6px 16px;
    font-size: 11px;
    color: var(--text2);
}

.karte-nachweis a { color: var(--text2); }

/* ---------------------------------------------------------- Bogen */

.bogen-schicht {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(0, 0, 0, 0.35);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.bogen-schicht.da { opacity: 1; }

.bogen {
    width: 100%;
    max-width: 460px;
    max-height: 86dvh;
    overflow-y: auto;
    background: var(--flaeche);
    box-shadow: 0 -1px 0 var(--line-fein);
    border-radius: 16px 16px 0 0;
    padding: 8px 20px calc(20px + var(--unten));
    transform: translateY(20px);
    transition: transform 0.22s ease;
}

.bogen-schicht.da .bogen { transform: none; }
.bogen h2 { margin: 6px 0 14px; font-size: 20px; font-weight: 600; text-align: center; letter-spacing: -0.2px; }

.bogen-griff {
    width: 36px;
    height: 5px;
    border-radius: 3px;
    background: var(--line);
    margin: 0 auto;
}

.bogen-koerper { display: flex; flex-direction: column; gap: 12px; }
.bogen-koerper .meldung { margin: 0; }

.bogen-gesicht {
    width: 132px;
    height: 132px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--kachel);
    align-self: center;
}

.bogen-fuss { display: flex; gap: 10px; margin-top: 18px; }
.bogen-fuss .knopf { flex-grow: 1; }

/* --------------------------------------------------------- Bausteine */

.karte {
    background: var(--fill);
    border-radius: var(--radius);
    padding: 16px;
    margin: 0 16px 14px;
}

.karte h2 { margin: 0 0 8px; font-size: 17px; font-weight: 600; }
.karte p { margin: 0 0 10px; font-size: 15px; color: var(--text2); }
.karte p:last-child { margin-bottom: 0; }

.knopf {
    display: inline-block;
    border: 0;
    background: var(--akzent);
    color: #fff;
    border-radius: 10px;
    padding: 13px 20px;
    min-height: 48px;
    font-size: 17px;
    font-weight: 500;
    text-align: center;
}

.knopf.leise { background: var(--fill2); color: var(--text); }
.knopf.gefahr { background: transparent; color: var(--gefahr); }
.knopf[disabled] { opacity: 0.4; }

.formular { display: flex; flex-direction: column; gap: 14px; }
.formular label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--text2); }

.formular input {
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 13px;
    min-height: 48px;
    background: var(--bg);
    font-size: 17px;
}

.liste { list-style: none; margin: 0; padding: 0; }

.liste li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 0;
    border-top: 0.5px solid var(--line-fein);
    font-size: 15px;
}

.liste li:first-child { border-top: 0; }
/* Die Textspalte darf schrumpfen, der Knopf daneben nicht. */
.liste li > span:first-child { min-width: 0; }
.liste li > .text-knopf { flex-shrink: 0; align-self: center; }
/* Zeile mit Kleinschrift darunter: Name und Knopf oben, Rest volle Breite. */
.liste li.stapel { flex-direction: column; align-items: stretch; gap: 2px; }
.liste li.stapel > .kopf { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.liste li.stapel > .kopf > .text-knopf { flex-shrink: 0; }
.liste .wert { color: var(--text2); text-align: right; }
.liste li.gut .wert { color: #1a7f4b; }
.liste li.schlecht .wert { color: var(--gefahr); }

.meldung { margin: 0 16px 14px; padding: 12px 14px; border-radius: 10px; font-size: 15px; }
.meldung.fehler { background: rgba(255, 59, 48, 0.12); color: var(--gefahr); }
.meldung.gut { background: rgba(26, 127, 75, 0.12); color: #1a7f4b; }

.klein { font-size: 12px; color: var(--text2); font-weight: 400; }

.code {
    background: var(--fill2);
    border-radius: 10px;
    padding: 12px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    overflow-x: auto;
    white-space: pre-wrap;
    word-break: break-all;
    margin: 0 0 12px;
}

.leer {
    padding: 80px 32px;
    text-align: center;
    color: var(--text2);
    font-size: 15px;
}

.laden {
    padding: 28px;
    text-align: center;
    color: var(--text3);
    font-size: 13px;
}

/* ------------------------------------------------------- Anmeldeseite */

.anmelden {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 24px;
    gap: 8px;
    max-width: 420px;
    margin: 0 auto;
}

.anmelden h1 { font-size: 28px; margin: 0 0 4px; letter-spacing: -0.3px; }
.anmelden p.klein { margin: 0 0 20px; }

/* ------------------------------------------------- Einrichtungsseite */

body.setup { background: var(--fill); }
.setup-wrap { max-width: 640px; margin: 0 auto; padding: 32px 0 60px; }
.setup-wrap h1 { font-size: 28px; margin: 0 16px 20px; letter-spacing: -0.3px; }
.setup-wrap .karte { background: var(--bg); border: 1px solid var(--line-fein); }
.setup-wrap ol { margin: 0; padding-left: 20px; font-size: 15px; color: var(--text2); }
.setup-wrap ol li { padding: 3px 0; }

code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.88em;
    background: var(--fill2);
    padding: 2px 5px;
    border-radius: 5px;
}

@media (min-width: 700px) {
    :root { --spalten: 5; --personen-spalten: 5; --alben-spalten: 4; }
    .blatt { max-width: 900px; margin: 0 auto; width: 100%; }
    .reiter { max-width: 900px; margin: 0 auto; width: 100%; }
}

/* Kästchen mit Erklärung daneben – im Bogen, wo eine Entscheidung
   getroffen wird, die man verstehen soll, bevor man sie trifft. */
.zeile-kasten {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    margin-top: 4px;
}

.zeile-kasten input { margin-top: 3px; flex-shrink: 0; }
