/* breitbild.css — ein Bauteil, das den Spieler die ganze Breite fuellen laesst.
 *
 * EINSETZEN   im <head> der Seite:  <link rel="stylesheet" href="/assets/breitbild.css">
 * KALTSTELLEN diese eine Zeile entfernen. Sonst nichts.
 *
 * Gebaut am 20.09.2026, auf Ansage des Nutzers: „ich moechte keine Schrauben
 * haben. Entweder baust du das als Bauteil, dass man das optional einsetzen
 * kann — wenn es einem nicht gefaellt, nehmen wir das Bauteil zurueck und
 * stellen es kalt. Sollte sich herausstellen, dass wir es brauchen, haben wir
 * es wieder da."
 *
 * Der Unterschied zu einer Schraube ist nicht kosmetisch. Eine Schraube
 * (`.spieler.fuellt`) bleibt fuer immer im Bauteil stehen, auch wenn niemand
 * sie je dreht: sie muss bei jedem Umbau mitgedacht, mitgeprueft und
 * mitgeschleppt werden. Ein eigenes Bauteil dagegen ist entweder eingesetzt
 * oder nicht da. Dieses hier hat **keine Klasse und keinen Schalter** — es
 * wirkt, sobald die Datei in der Seite haengt, und es ist vollstaendig weg,
 * sobald sie es nicht tut. Der Spieler selbst weiss nichts davon.
 *
 * WAS ES TUT
 *
 * Der Spieler ist im Ruhezustand 16:9 und damit im Querformat schmaler als die
 * Flaeche: gemessen am iPhone 734 breit bei 814 nutzbar, also 40 Pixel Rand je
 * Seite. Der Nutzer: „dass ein Rest uebrig bleibt, der ungenutzt ist, ist doch
 * einfach mal Fakt, ich seh doch, dass das eine andere Farbe hat."
 *
 * Richtig. 16:9 ist das Verhaeltnis des **Videos**, nicht des Geraets — das
 * iPhone ist quer rund 19,5:9. Ein 16:9-Bild kann diese Flaeche nie fuellen.
 * Dieses Bauteil macht, was Fernseher seit den Roehrenzeiten als Zoom kennen:
 * das Bild auf die Breite ziehen, oben und unten abschneiden.
 *
 *   ohne dieses Bauteil   ganzes Bild, Rand an den Seiten      734 × 413
 *   mit  diesem Bauteil   randlos in der Breite, oben/unten ab 814 × 410
 *
 * WIE ES RECHNET
 *
 * Ohne neue Masse. Die Sichtflaeche ist die nutzbare Flaeche des Geraets; das
 * Bild ist so hoch, wie 16:9 es bei dieser Breite verlangt; der Ueberstand geht
 * je zur Haelfte nach oben und unten und wird weggeschnitten.
 *
 * Geschnitten wird am **Rahmeninhalt**, nicht am Rahmen. Am Rahmen waeren die
 * beiden Funkelsterne halbiert, die auf seiner Kante laufen — dieselbe
 * Ueberlegung wie beim waagrechten Ausgleich, mit dem dieses Bauteil sich die
 * Kante teilt. Beide greifen an derselben Stelle an und stehen deshalb in
 * einer Rechnung.
 *
 * GRENZEN, damit sie nicht wieder gesucht werden muessen
 *
 *   - Nur im Querformat und nur bis 520 Pixel Fensterhoehe. Im Hochformat gibt
 *     es nichts zu fuellen, dort ist die Breite der Engpass.
 *   - In beiden Zustaenden. Der Bedienzustand zieht 36 Pixel Hoehe fuer die
 *     Leiste ab (`--leistenplatz`), der Ruhezustand nimmt sie sich dazu. Die
 *     Breite ist in beiden dieselbe — sie hat mit der Bedienung nichts zu tun.
 *   - `pruefe-spieler.js` meldet im kleinsten Fenster „Bild nutzt nur 83 % der
 *     Hoehe, gefordert sind 84 %". Die Forderung stammt vom 17.09.2026 und ist
 *     am 16:9-Modus eingemessen; mit diesem Bauteil gilt sie dort nicht mehr.
 *     Der Prüfstand weiss nichts von Bauteilen, und das soll so bleiben —
 *     deshalb steht der Hinweis hier und nicht als Ausnahme dort.
 *   - `--ausgleich` kommt aus dem Spieler und wird hier nur gelesen. Aendert er
 *     sich, aendert sich der Schnitt von selbst mit.
 */

/* **Die Sicherheitszonen werden ueber Variablen gelesen, nicht ueber env()
   direkt** — 20.09.2026. Der Grund ist nicht Schoenheit, sondern Messbarkeit:
   `env(safe-area-inset-*)` ist auf dem Rechner und in Playwright null und
   laesst sich von aussen nicht stellen. Jede oertliche Messung mass deshalb
   einen Fall, den das Geraet nie hat — `breitenbudget.js --zonen 59` meldete
   weiterhin `calc(9px + 0px)`. Steht der Wert in einer Variablen am
   Wurzelelement, kann ein Pruefwerkzeug ihn per `style.setProperty` setzen und
   damit den Fall des Geraets nachstellen. Der Fallback ist das echte `env()`,
   am Geraet aendert sich also nichts. */
/* ┌ @bauteil breitbild
   │ @art       erweiterung
   │ @erweitert spieler
   │ @zweck     Zieht den Spieler im Querformat auf die volle Breite und
   │            beschneidet das Bild oben und unten
   │ @liest     --ausgleich, --rund-kasten
   │ @setzt     —
   └ @intern    --sicht-breite, --sicht-hoehe, --luft-oben, --luft-unten,
                --luft-links, --luft-rechts, --leistenplatz, --rahmenluft,
                --knopf-ueber, --luft-senkrecht, --boden, --zone-links,
                --zone-rechts, --zone-oben, --zone-unten, --linie,
                --inhalt-hoehe, --bild-hoehe, --ueberstand, --ruhe-verzug
 *
 * **Sie ist eine Erweiterung und kein Teil des Spielers.** Der Spieler weiss
 * nichts von ihr; sie wird mit einer `<link>`-Zeile eingesetzt und mit
 * derselben Zeile kalt gestellt. Genau das hat am 20.09.2026 zwoelf Stunden
 * lang getragen — bei jedem Zwischenstand liess sich der Stand davor in einer
 * Sekunde wiederherstellen.
 *
 * Was unter `@setzt` steht, stellt sie **am Wirt**. `vertrag.js` prueft, dass
 * jede dieser Schrauben beim Spieler unter `@liest` steht: eine Erweiterung
 * darf an erklaerten Eingaengen drehen, nicht ins Innere greifen. Der Fall, an
 * dem diese Regel gelernt wurde, ist `--gross: 18px` — es stand hier, der
 * Spieler fuehrt es nicht als Eingang, und es blieb wirkungslos.
 *
 * **`@setzt` ist seit dem 21.09.2026 leer, und das ist der ehrliche Befund.**
 * Die Masse `--sicht-*` und `--luft-*` sahen aus wie Uebergaben an den Spieler
 * — sie sind keine. Diese Datei setzt sie am `body.keinscroll` und **verrechnet
 * sie in ihren eigenen Regeln**, bis hin zu denen fuer die Spulleiste. Kein
 * anderer Abschnitt liest sie; gemessen, nicht angenommen. Sie sind damit das
 * Innere dieses Bauteils, und der Waechter meldete zu Recht zweimal „Griff ins
 * Innere", solange sie als Uebergabe gefuehrt waren.
 *
 * Woran man den Unterschied erkennt: eine Uebergabe steht beim Empfaenger unter
 * `@liest` und wird von ihm gelesen. Steht sie nirgends, ist sie keine
 * Schnittstelle, sondern eine Zwischenrechnung mit weitem Geltungsbereich. */
:root {
  --zone-links: env(safe-area-inset-left, 0px);
  --zone-rechts: env(safe-area-inset-right, 0px);
  --zone-oben: env(safe-area-inset-top, 0px);
  --zone-unten: env(safe-area-inset-bottom, 0px);
  /* **Die Bodenluft steht an der Wurzel, nicht am Rahmen** — 21.09.2026, beim
     ersten Anlauf falsch gemacht und sofort gemessen. Am Rahmen definiert,
     sieht die Spulleiste sie nicht: sie ist sein Geschwister, und Custom
     Properties vererben nur nach unten. `bottom: var(--boden)` war dort
     ungueltig, und die Leiste sprang 130 Pixel nach oben.

     Fuenf Pixel ueber der Sicherheitszone des Homebalkens. Weniger waere
     fahrlaessig: der Balken nimmt Wischgesten an, und die Spulkugel liegt
     genau dort, wo man wischt.

     **Ueber `var(--zone-unten)`, nicht ueber `env()` direkt** — das steht seit
     dem 20.09.2026 im Kopf dieser Datei, und ich habe es hier im ersten Anlauf
     trotzdem gebrochen. Die Folge war sofort messbar: am Rechner ist `env()`
     null, die Bodenluft wurde 5 statt 25, und der Rahmen wuchs um zwanzig
     Pixel zu weit. Ueber die Variable kann ein Pruefwerkzeug den Fall des
     Geraets nachstellen (`--zonen 59`), ueber `env()` nicht. */
  --boden: calc(var(--zone-unten) + 5px);
}

@media (orientation: landscape) and (max-height: 520px) {
  /* **Beide Zustaende auf Maximum** — 20.09.2026, nach mehreren Anlaeufen.
   *
   * Der Nutzer: „man kann ja hier ans Maximum gehen, damit die Spurleiste mit
   * Zeitangabe an die Maximumbreite geht. Vielleicht nicht so, dass es schlecht
   * aussieht, aber die Hoehe war ja auch — und der Magentastern wollte
   * eigentlich auf dem Magentarahmen laufen."
   *
   * Drei Festlegungen daraus, und sie haengen zusammen:
   *
   * 1. Breite und Hoehe gehen in **beiden** Zustaenden ans Maximum. Der
   *    Bedienzustand zieht nur den Platz fuer die Leiste von der Hoehe ab —
   *    die Breite teilt er mit dem Vollbild, damit die Zeitangabe bis aussen
   *    reicht.
   * 2. Der Stern laeuft wieder **auf** der Linie, wie ueberall sonst am
   *    Spieler. Eine eigene Bahn nur fuer diesen Ort waere genau die
   *    Individualloesung, die das Baukastenprinzip zerstoert.
   * 3. **Der Stern darf ueber die Kante hinausragen.** Hier stand bis zum
   *    20.09.2026 die Rechnung „Luft mindestens halber Sterndurchmesser", und
   *    dazu ein `--gross: 18px`, das den Stern kleinrechnen sollte. Beides ist
   *    entfallen. Das `--gross` war wirkungslos: der Spieler setzt die Groesse
   *    am Stern selbst (`.spieler .stern-spitze { --gross: 54px }`), und eine
   *    Deklaration am Element schlaegt jeden geerbten Wert — dieselbe Falle wie
   *    im Bauteil Funkelstern beschrieben. Die Abnahme hat die 54 gemeldet und
   *    wurde faelschlich fuer falsch geeicht gehalten.
   *
   *    Und die Rechnung war gar nicht noetig. Der Nutzer am 20.09.2026: „der
   *    kann auch manchmal rueberfunkeln." Ein Stern, der am Geraeterand kurz
   *    angeschnitten wird, stoert nicht; 27 Pixel Luft auf jeder Seite kosten
   *    dagegen 36 Pixel Bildhoehe. Was ihm zu gross war, ist der Punkt in der
   *    Mitte — der haengt jetzt an der Schraube `--kern` im Spieler, nicht an
   *    der Groesse des ganzen Sterns und erst recht nicht an diesem Bauteil. */
  .spieler.gross {
    --rahmenluft: 9px;
    /* **30 statt 36, ab dem 21.09.2026.** Der Nutzer: „ob die Zeitleiste noch
       ein bisschen weiter mit dem Bild nach unten wachsen kann und es trotzdem
       nicht zu nah an das Bildschirmmaximum rennt."

       Nach unten ist praktisch nichts frei: von den 29 Pixeln Luft gehoeren 20
       dem Homebalken, bleiben 9 Puffer. Der Platz liegt zwischen Rahmen und
       Leiste. `--leistenplatz` ist die Summe aus Leistenhoehe (18) und diesem
       Abstand; 36 hiess 18 Abstand, 30 heisst 12. Das Bild gewinnt die
       Differenz, und die Leiste bleibt genau dort, wo sie war — sie haengt an
       der unteren Luftgrenze, nicht am Rahmen.

       **Die Untergrenze ist bekannt und liegt bei 8:** so sass die Leiste am
       20.09.2026, und der Nutzer nannte es „dazu gedraengt". 12 ist der
       Mittelweg, und er ist eine Zahl zum Ansehen, keine gerechnete Wahrheit. */
    /* **Null, ab dem 21.09.2026 — und das ist der Abriss eines Turms.**
       Dieser Wert war der Anfang einer Kette: er machte den Rahmen im
       Bedienzustand niedriger als im Vollbild, also aenderte sich die Hoehe
       beim Umschalten. Eine wechselnde Hoehe heisst ein wechselnd grosser
       Laeufer, und weil die Bahn in Prozent seiner eigenen Groesse laeuft,
       musste sie bei jeder Aenderung neu aufgeloest werden (`sternbahn.js`).
       Dabei drifteten die beiden Schichten des Sterns auseinander, also
       musste ein zweites Modul sie zusammenhalten (`sternpaar.js`), und weil
       das driftete, kam ein Gleichtakt dazu. Drei Module, zwei Zusagen, ein
       Stueck Sonde — alle nur, weil sich eine Zahl aenderte.

       Der Nutzer, nach zwei Tagen: „es kommt immer noch nichts dabei raus."
       Er hat recht, und die Antwort ist nicht der naechste Waechter, sondern
       die Zahl, die sich nicht mehr aendert. Auf `thaimorrow.ch` gibt es
       nichts von alldem, weil dort die Hoehe nie wechselt.

       Die Leiste bekommt ihren Platz jetzt **im** Bild, unten am Rand, wie bei
       jedem Videospieler. Damit ist der Rahmen in beiden Zustaenden gleich
       hoch, die Luft oben und unten bleibt gleich, und das Bild ist im
       Bedienzustand so gross wie im Vollbild. */
    /* **Zurueck auf 30, am 21.09.2026 spaetabends.** Der Versuch, die Hoehe
       konstant zu halten, indem die Leiste ins Bild rutscht, ist am Augenschein
       gescheitert: „sie war nie im Player, sie war immer unter dem Player."
       Damit kommt der Hoehenwechsel zurueck — und das ist jetzt tragbar, weil
       `sternbahn.js` die beiden Schichten des Sterns auch dabei zusammenhaelt.
       Gemessen am selben Abend: 0 px Abstand ueber vier Zustandswechsel und
       ueber eine Drehung.

       Was die Episode gekostet hat, steht als Warnung in `memory/`: eine
       Bauweise zu aendern, um eine Fehlerklasse loszuwerden, ist erst dann
       eine Verbesserung, wenn die neue Bauweise auch gefaellt. */
    --leistenplatz: 30px;

    /* **Oben bestimmt der Schliessknopf die Luft, nicht die Rahmenlinie** —
       20.09.2026. Der Knopf `.zu` haengt mit `top: -14px` ueber der Oberkante
       des Rahmens; bei neun Pixeln Luft steht sein Kreis damit fuenf Pixel
       ueber dem Fensterrand. Der Nutzer: „der Kreis von dem X-Punkt ist so
       gross, dass er einfach rueberhinausragt — zur Navigation ist der
       eigentlich nicht verkehrt."

       Also nicht den Knopf kleiner machen, sondern die Luft nach seinem
       Ueberstand bemessen. `--knopf-ueber` ist eine Schraube und keine Zahl im
       Text: aendert jemand `.zu`, wird sie hier nachgezogen, und die Abnahme
       misst ohnehin nach. */
    --knopf-ueber: 14px;
    /* **Oben und unten dieselbe Zahl, und zwar die groessere der beiden
       Forderungen** — 20.09.2026. Oben verlangt der Schliessknopf 9 + 14, unten
       der Homebalken 9 + 20. Wer jede Seite fuer sich rechnet, bekommt 23 gegen
       29 und damit einen Rahmen, der sichtbar zu hoch sitzt. Der Nutzer:
       „sollten wir vielleicht auch den Abstand nehmen, der maximal ueberhaupt
       geht … im Vollbild sollte das zumindest auch den gleichen Abstand
       haben." Eine Zahl fuer beide Seiten, das Maximum entscheidet. */
    --luft-senkrecht: max(
      calc(var(--rahmenluft) + var(--knopf-ueber) + var(--zone-oben)),
      calc(var(--rahmenluft) + var(--zone-unten)));
    --luft-oben: var(--luft-senkrecht);
    /* **Unten so viel wie oben** — 20.09.2026, Vorgabe des Nutzers: „im Vollbild
       sollte das zumindest vielleicht auch den gleichen Abstand haben." Oben
       gibt der Schliessknopf das Mass vor, unten gibt es nichts, was mehr
       verlangt — ausser dem Homebalken, und der ist kleiner. `max` deshalb
       nicht aus Vorsicht, sondern weil auf einem Geraet ohne Knopfueberstand
       sonst die Rahmenlinie im Balken verschwaende.

       Zwei verworfene Fassungen dieses Tages stehen hier absichtlich als
       Warnung. Erst `var(--luft-links)`, also 68 Pixel: das uebernahm die
       Kamerazone auf eine Seite, an der keine Kamera sitzt. Dann
       `calc(var(--rahmenluft) + var(--zone-unten))`, also 29: rechnerisch
       richtig, aber es aenderte die Hoehe, ohne dass jemand danach gefragt
       hatte — „die Hoehe war nie Teil des Themas." Massgebend ist keine der
       beiden Rechnungen, sondern die Symmetrie zu oben.

       **Und die Ausnahme davon, ab dem 21.09.2026: im Leistenmodus nicht.**
       Der Nutzer hat nach Platz nach unten gefragt und ihn bekommen, wo er
       ohne Schaden zu holen ist. Die Symmetrie oben/unten ist eine Zusage
       fuers **Vollbild** — dort steht der Rahmen allein und ein ungleicher
       Rand faellt auf. Steht die Leiste darunter, sieht ohnehin niemand eine
       Symmetrie: unten schliesst das Bauteil mit der Leiste ab, nicht mit der
       Rahmenlinie.

       Unten bleiben damit `--boden`: die Sicherheitszone des Homebalkens plus
       fuenf Pixel. Weniger waere fahrlaessig — der Balken nimmt Wischgesten
       an, und die Spulkugel liegt genau dort, wo man wischt. */
    --luft-unten: var(--luft-senkrecht);

    /* **Links kommt der Kameraausschnitt dazu** — 20.09.2026, auf einen Befund
       des Nutzers, der auf keinem Bildschirmfoto zu sehen ist: „der eigentliche
       Kameraausschnitt faellt bei einem wirklichen Vollbild kaum auf, aber er
       ist da, und der sieht nicht sauber aus. Eigentlich muesste man
       linksseitig den Player einkuerzen auf mindestens 1 cm."
       
       Die Zahl stimmt auf den Punkt: die Sicherheitszone misst quer 59 Pixel,
       bei rund 6 Pixeln je Millimeter also genau einen Zentimeter. Links wird
       sie deshalb addiert, rechts nicht — dort ist nichts im Weg.
       
       **Grenze, die zu kennen ist:** iOS meldet die Zone im Querformat auf
       beiden Seiten mit 59 Pixeln, unabhaengig davon, wo die Kamera wirklich
       sitzt. Dreht das Geraet in die andere Richtung, bleibt der Einzug
       trotzdem links. Aus dem Stylesheet ist das nicht zu unterscheiden. */
    --luft-links: calc(var(--rahmenluft) + var(--zone-links));
    /* **Rechts gleich viel wie links** — 20.09.2026. Links steht die
       Kamerazone, also 9 + 59 = 68 Pixel. Der Nutzer, nachdem links passte:
       „jetzt koennen wir aber um die gleiche Breite bitte auch rechts
       einloesen." Das ist hier nicht nur Symmetrie: iOS meldet die Zone im
       Querformat auf beiden Seiten, und welche der beiden die Kamera traegt,
       haengt an der Drehrichtung des Geraets. Wer nur eine Seite einzieht,
       trifft in der Haelfte der Faelle die falsche. */
    --luft-rechts: calc(var(--rahmenluft) + var(--zone-rechts));

    --sicht-breite: calc(100vw - var(--luft-links) - var(--luft-rechts));
    --sicht-hoehe: calc(100dvh - var(--luft-oben) - var(--luft-unten) - var(--leistenplatz));
    width: var(--sicht-breite);
    height: var(--sicht-hoehe);
    aspect-ratio: auto;
    /* Weder waagrecht noch senkrecht liegt die Mitte bei 50 Prozent, sobald
       die Luft auf gegenueberliegenden Seiten verschieden ist — sonst waere
       die Ungleichheit doppelt drin. */
    top: calc(var(--luft-oben) + var(--sicht-hoehe) / 2);
    left: calc(var(--luft-links) + var(--sicht-breite) / 2);

    /* **Die Hoehe gleitet mit, ab dem 21.09.2026.** Der Nutzer am Geraet:
       „wenn es von dem Spulleistenplayer in den anderen Player rutscht, dann
       muss irgendwie ein riesen Ruck entstehen … als ob du die Seite neu
       laedst." Er hat genau das gesehen, was hier stand:

       `stil.css` gibt dem grossen Spieler im Querformat
       `transition: width .45s, top .45s` — **ohne `height`**. Solange der
       Rahmen seine Hoehe aus dem Seitenverhaeltnis bezog, gab es keine zu
       animieren. Seit dieses Bauteil `height: var(--sicht-hoehe)` setzt, gibt
       es sie: beim Wechsel zwischen Leiste und Vollbild springt sie in **einem
       Bild** um 36 Pixel, waehrend die senkrechte Lage 0,45 Sekunden lang
       nachkriecht. Die Kante springt, die Mitte wandert — und der Funkelstern
       laeuft auf dieser Kante, also rutscht er sichtbar mit weg.

       Die Transition gehoert deshalb hierher und nicht nach `stil.css`: wer
       die Hoehe stellt, stellt auch ihren Uebergang. Sie nennt `width` und
       `top` mit, weil die Kurzform die Regel aus `stil.css` ohnehin
       vollstaendig ersetzt — sonst faellt deren Uebergang still aus.
       Gemessen wird das seit demselben Tag als Zusage 10 in
       `pruefe-breitbild.js`: die Rahmenhoehe darf sich je Bild um hoechstens
       acht Pixel aendern. */
    transition: width .45s ease, height .45s ease, top .45s ease;
  }

  /* **Und die Bewegungsruhe behaelt das letzte Wort.** Der Block in
     `stil.css` steht vor dieser Datei; eine neue `transition` danach hebelt
     ihn aus, wenn sie nicht wiederholt wird. Dieselbe Falle wie bei
     `animation` — sie hat am 19.09.2026 schon einmal zugeschlagen. */
  @media (prefers-reduced-motion: reduce) {
    .spieler.gross,
    .spieler.gross.still,
    .spieler.gross iframe { transition: none; }
  }

  /* **Nur mit Leiste: unten bis an den Boden** — 21.09.2026. Vier Pixel, die
     dem Bild zugutekommen, weil unter der Leiste kein Rahmen steht, dessen
     Symmetrie jemand sieht. Im Vollbild gilt die Regel nicht; die Klasse
     `:not(.still)` ist der ganze Unterschied. */
  /* Die Sonderregel „im Leistenmodus unten bis an den Boden" ist am
     21.09.2026 entfallen. Sie holte vier Pixel, indem sie den Rahmen im
     Bedienzustand tiefer zog — und genau solche Unterschiede zwischen den
     Zustaenden sind es, die den Turm gebaut haben. Beide Zustaende sind jetzt
     gleich, `--boden` bleibt fuer die Leiste. */

  /* **Die Leiste geht mit nach unten.** Ohne diese Zeile waechst nur der
     Rahmen, und der Abstand zwischen beiden schrumpft von zwoelf auf acht —
     also genau auf den Wert, den der Nutzer am 20.09.2026 „dazu gedraengt"
     genannt hat. Gemessen am 21.09.2026 beim ersten Anlauf dieser Aenderung.

     Die Leiste braucht ihre eigene Regel, weil sie ein **Geschwister** des
     Rahmens ist: `--luft-unten` am Rahmen erreicht sie nicht, Custom
     Properties vererben nur nach unten. Dieselbe Ueberlegung wie bei allem
     anderen, was dieses Bauteil fuer die Leiste stellt. */


  /* Ruht die Bedienung, faellt der Platz fuer die Leiste weg und das Bild
     nimmt ihn mit. Sonst aendert sich nichts — gleiche Breite, gleiche Luft,
     gleicher Stern. */
  /* **Breite und Hoehe stehen hier noch einmal — zum zweiten Mal an diesem
     Tag, aus demselben Grund.** Der Spieler bringt fuer den Ruhezustand eine
     eigene Regel mit drei Klassen mit (`.spieler.gross.still { width: … }`).
     Sie ist spezifischer als `.spieler.gross`, und Spezifitaet schlaegt
     Ladereihenfolge — das Bauteil kommt an und wird trotzdem ueberstimmt.
     
     Beim ersten Mal hat `breitenbudget.js` es gefunden, beim zweiten Mal
     `pruefe-breitbild.js`. Ohne Abnahme waere es beide Male unbemerkt
     geblieben: der Rahmen sah plausibel aus, nur eben 174 Pixel zu schmal. */
  .spieler.gross.still {
    --leistenplatz: 0px;
    width: var(--sicht-breite);
    height: var(--sicht-hoehe);
    top: calc(var(--luft-oben) + var(--sicht-hoehe) / 2);
    left: calc(var(--luft-links) + var(--sicht-breite) / 2);
    /* **Das Bild waechst erst, wenn die Leiste weg ist** — 22.09.2026. Der
       Nutzer: „nur manchmal, dass es ein bisschen kurz rumspringt … ein paar
       unsaubere Dinge." Aufgezeichnet wurde die Geometrie Bild fuer Bild ueber
       45 Sekunden: bei Sekunde 14,3 wuchs der Rahmen in zehn Schritten von
       355 auf 383 Pixel Hoehe, und bei Sekunde 7,0 sprang die Kugel um
       5,5 Pixel zur Seite.

       Beides ist dasselbe Ereignis. Das Wachsen ist gewollt — ruht die
       Bedienung, nimmt das Bild ihren Platz. Nur lief es in 0,45 Sekunden ab,
       waehrend die Leiste 1,1 Sekunden fadet: man sieht sie also noch, und
       unter ihr rueckt schon alles. Die Verzoegerung schiebt die Bewegung
       hinter das Faden.

       Nur auf dem Hinweg: beim Aufwachen gilt `.spieler.gross` ohne
       Verzoegerung, das Bild macht der Leiste sofort Platz.

       **Und das Videobild wartet mit** — 26.09.2026. Die Verzoegerung stand
       nur am Rahmen; der iframe darin hat eigene Uebergaenge und wuchs sofort.
       Gut eine Sekunde lang ragte er unten ueber den noch kleinen Rahmen und
       deckte die untere Magentalinie zu. Der Nutzer: „dann fehlt unten der
       Magenta Rahmen kurzweilig … der Rahmen reisst aus". Deshalb eine
       Schraube, die beide lesen. */
    --ruhe-verzug: 1.15s;
    transition-delay: var(--ruhe-verzug);
  }

  /* **Die Leiste gehoert zum Bauteil** — 20.09.2026. Sie hing weiter an
     `--fenster`, dem alten Mass, und war damit 643 Pixel breit, waehrend der
     Rahmen darueber 850 mass. Am Geraet sieht das aus, als schwebe sie
     darunter statt dazuzugehoeren. Der Nutzer: „man kann ja ans Maximum gehen,
     damit die Spurleiste mit Zeitangabe an die Maximumbreite geht."
     
     Sie bekommt deshalb dieselbe Breite und dieselbe Mitte wie der Rahmen und
     setzt sich unmittelbar darunter. Dass sie ein Geschwister des Rahmens ist
     und nicht sein Kind, aendert daran nichts — sie liest dieselben Masse. */
  /* **Die Leiste haengt unten, nicht oben** — 20.09.2026. Bis dahin sass sie
     acht Pixel unter dem Rahmen (`top: … + 8px`) und liess darunter 39 Pixel
     ungenutzt. Der Nutzer: „im Spulenleistenformat koennte die Spulenleiste
     noch ein bisschen mehr Abstand zum eigentlichen Player haben und ein
     bisschen nach unten versetzt sein … irgendwie wirkt die mir dazu
     gedraengt, und ich finde, da ist auch noch Platz."

     Statt den Abstand zu raten, wird die Leiste an der **unteren Luftgrenze**
     verankert. Damit ist der Abstand zum Rahmen automatisch der groesste, den
     der Platz hergibt, und er bleibt richtig, wenn die Leiste einmal hoeher
     wird — sie waechst dann nach oben, statt in den Homebalken zu rutschen.
     Eine Zahl weniger im Stylesheet, und eine, die sonst bei jeder Aenderung
     an der Leistenhoehe nachgezogen werden muesste.

     `top: auto` ist noetig, weil der Spieler die Leiste mit `top` setzt und
     eine Angabe fuer beide Kanten sonst gegeneinander steht. */
  /* **Sie liegt im Bild, ab dem 21.09.2026.** Vorher hing sie unter dem
     Rahmen und kostete ihn 30 Pixel Hoehe — siehe die Begruendung bei
     `--leistenplatz`. Jetzt sitzt sie am unteren Bildrand, acht Pixel ueber
     der Rahmenlinie, und der Rahmen behaelt in beiden Zustaenden dieselbe
     Hoehe.

     Der Funkelstern laeuft auf derselben Linie und bleibt sichtbar: seine
     Ebene (`--ebene: 62`) liegt ueber der Leiste. */
  .spieler.gross + .spulleiste {
    width: var(--sicht-breite);
    left: calc(var(--luft-links) + var(--sicht-breite) / 2);
    top: auto;
    bottom: var(--boden);
  }

  /* Die Masse des Rahmens muessen dafuer auch neben ihm lesbar sein. Custom
     Properties vererben nur nach unten, und die Leiste steht daneben — deshalb
     stehen sie zusaetzlich am Koerper. */
  body.keinscroll {
    --rahmenluft: 9px;
    --knopf-ueber: 14px;
    /* **Oben und unten dieselbe Zahl, und zwar die groessere der beiden
       Forderungen** — 20.09.2026. Oben verlangt der Schliessknopf 9 + 14, unten
       der Homebalken 9 + 20. Wer jede Seite fuer sich rechnet, bekommt 23 gegen
       29 und damit einen Rahmen, der sichtbar zu hoch sitzt. Der Nutzer:
       „sollten wir vielleicht auch den Abstand nehmen, der maximal ueberhaupt
       geht … im Vollbild sollte das zumindest auch den gleichen Abstand
       haben." Eine Zahl fuer beide Seiten, das Maximum entscheidet. */
    --luft-senkrecht: max(
      calc(var(--rahmenluft) + var(--knopf-ueber) + var(--zone-oben)),
      calc(var(--rahmenluft) + var(--zone-unten)));
    --luft-oben: var(--luft-senkrecht);
    --luft-unten: var(--luft-senkrecht);
    --luft-links: calc(var(--rahmenluft) + var(--zone-links));
    --luft-rechts: calc(var(--rahmenluft) + var(--zone-rechts));
    /* **Auch hier null** — 21.09.2026. Dieselbe Zahl steht zweimal, weil die
       Leiste ein Geschwister des Rahmens ist und seine Masse nicht erbt. Beim
       Abriss des Turms war sie deshalb an zwei Stellen nachzuziehen, und beim
       ersten Anlauf habe ich genau diese hier vergessen: der Rahmen war dann
       372 hoch und die Leiste rechnete weiter mit 36 Pixeln Platz darunter.
       Eine Zahl an zwei Orten ist eine Zahl zu viel — sie bleibt vorerst, weil
       Custom Properties nicht seitwaerts vererben. */
    --leistenplatz: 30px;
    --sicht-breite: calc(100vw - var(--luft-links) - var(--luft-rechts));
    --sicht-hoehe: calc(100dvh - var(--luft-oben) - var(--luft-unten) - var(--leistenplatz));
  }

  /* Das Bild deckt die Sichtflaeche: so breit wie sie plus Ausgleich, und so
     hoch, wie 16:9 das verlangt. Der Ueberstand geht je zur Haelfte nach oben
     und unten und wird weggeschnitten — am Rahmeninhalt, nicht am Rahmen,
     sonst waeren die Funkelsterne auf seiner Kante halbiert. */
  .spieler.gross iframe {
    /* **Der Ueberstand rechnet gegen den Inhalt, nicht gegen die Aussenkante**
       — berichtigt am 20.09.2026, zweiter Anlauf.

       `--sicht-hoehe` ist die Hoehe des Rahmens **mit** seiner Linie; der
       iframe sitzt aber im Inhalt und der ist zwei Linien kleiner. Wer den
       Ueberstand gegen die Aussenkante rechnet, laesst das Videobild unten
       genau ueber der Rahmenlinie enden und deckt sie zu. Am Geraet sieht das
       aus, als fehle die Linie — der Nutzer zweimal an diesem Tag: „warum ist
       der Magenta-Rahmen kaputt bei der Spule, der ist ja nicht sichtbar?" und
       „der untere Magenta-Rahmen ist beim Spulen wieder nicht da."

       Der erste Anlauf schnitt unten pauschal einen Pixel mehr ab. Das war die
       halbe Korrektur eines Fehlers von zwei Pixeln und deshalb genau so weit
       daneben wie vorher — gemessen: Bild bis 365, Inhalt endet bei 364. Mit
       der richtigen Bezugsgroesse geht die Rechnung ohne Zuschlag auf, oben wie
       unten, und der Zuschlag ist entfallen. */
    --linie: 1px;
    --inhalt-hoehe: calc(var(--sicht-hoehe) - 2 * var(--linie));
    --bild-hoehe: calc((var(--sicht-breite) + var(--ausgleich, 0px)) * 9 / 16);
    --ueberstand: calc((var(--bild-hoehe) - var(--inhalt-hoehe)) / 2);
    top: calc(-1 * var(--ueberstand));
    height: var(--bild-hoehe);
    clip-path: inset(var(--ueberstand) 0 var(--ueberstand) var(--ausgleich, 0px)
      round var(--rund-kasten));

    /* **Das Bild gleitet mit dem Rahmen** — 21.09.2026, auf eine Beobachtung
       des Nutzers am Geraet: „der Frame rutscht manchmal aus so einem
       schwarzen Rahmen raus."

       Genau so ist es: seit die Rahmenhoehe ueber 0,45 Sekunden wandert,
       sprangen `height`, `top` und der Schnitt des Videobildes weiterhin in
       einem Bild. Fuer die Dauer des Uebergangs passte der Ausschnitt dann
       nicht zum Rahmen — und was nicht vom Bild gedeckt ist, ist die schwarze
       Flaeche des fremden Dokuments.

       Derselbe Takt und dieselbe Kurve wie beim Rahmen, sonst laeuft das Bild
       der Kante hinterher statt mit ihr. Die Bewegungsruhe wird unten
       wiederholt, weil eine Transition nach dem `prefers-reduced-motion`-Block
       ihn sonst aushebelt. */
    transition: height .45s ease, top .45s ease, clip-path .45s ease;
    /* Dieselbe Verzoegerung wie der Rahmen, geerbt aus `.still`: ohne sie
       wuchs das Bild vor dem Rahmen und deckte die untere Linie zu. */
    transition-delay: var(--ruhe-verzug, 0s);
  }
}

/* @ende breitbild — ab hier gehoert nichts mehr zu diesem Bauteil. */
