/* =====================================================================
   FOLDING TO YOU · styles.css

   Erster Teil: die Grammatik, woertlich aus design.html uebernommen
   (die Entscheidungen vom 23.08.2026). Wer dort etwas aendert, zieht
   es hier nach, nie umgekehrt.
   Zweiter Teil: die Szenen. Nichts darin erfindet neue Grammatik,
   alles setzt die fuenf Bausteine und die zwei Bildschirme ein.
   ===================================================================== */

:root{
  --grund:#0e0e10;
  /* Verdeckungsfarbe der uebernommenen Zeichnungen: die Monstera malt
     ihre Ueberlappungen mit var(--buehne) zu, hier ist das der Grund */
  --buehne:var(--grund);
  --moewe:#a9b5bd; --moewe-rgb:169 181 189;
  --tinte:#ece9e2;
  --tinte-dunkel:#12161a;
  --regie:var(--moewe);
  /* WO DER DAUMEN JETZT HIN SOLL, IST MOEWENBLAU (design.html,
     30.08.26). Bis dahin war es Butter, an fuenf festen Orten: die drei
     Kleckse (Weiter 48, Tippen 31, Wischen 29), der Sendenknopf und der
     Punkt fuer ungelesene Nachrichten. Alle fuenf sind an dem Tag
     umgezogen, und die Groessenstaffelung ist mitgegangen: alle drei
     Kleckse stehen jetzt auf 48. Was Knopf ist und was Geste, sagt seit
     dem die FORM und nicht die Groesse.
     Lauras Grund: jede bunte Farbe gehoert im Spiel schon jemandem
     (orange Fine, walblau Fabi, violett das Traumglas), und eine neue
     sieht komisch aus. Der Preis: moewenblau ist zugleich die Farbe der
     WELT, also trennt die Farbe die zwei nicht mehr — das tut die Form.
     BUTTER IST DAMIT AUS DER BEDIENUNG RAUS. Sie steht nur noch dort,
     wo sie LICHT ist und keine Aufforderung: die Nachttischlampe
     (.ntl-birne, .ntl-mundflaeche) und der Schein des Handys
     (ikonen.js). Das ist keine Ausnahme von der Regel, sondern eine
     andere Rolle derselben Farbe. */
  --akz:#e5c26a; --akz-rgb:229 194 106;
  --klecks-rgb:var(--moewe-rgb);

  /* DER SENDENKNOPF DREHT SICH UM (design.html, 30.08.26): in Ruhe
     dunkel mit gestricheltem Rand, MOEWENBLAU sobald man ihn druecken
     kann. Bis dahin war es andersherum. Zwei Angaben je Zustand, weil
     die Scheibe ein Zeichen traegt: wird sie dunkel, muss der Flieger
     darin hell werden.
     DIE ALTE SONDERREGEL IST WEG. Bis zum 25.08.26 war der Flieger im
     Spiel IMMER Butter und wich damit bewusst von design.html ab; seit
     jener Nacht folgt das Spiel der Bibel, und seit dem 30.08. folgt es
     ihr auch in der Farbe. */
  --senden-ruhe:rgb(var(--moewe-rgb) / .14);
  --senden-ruhe-zeichen:rgb(var(--moewe-rgb) / .55);

  /* GESTRICHELT HEISST OFFEN/ERWARTEND, wie am Wahlkasten: Strich 4,5,
     Luecke 5,5, Breite 1,5. Zwei SVG, weil es den Knopf in zwei
     Groessen gibt; die Radien sind so gewaehlt, dass der Umfang ein
     Vielfaches von 10 ist (r 19,10 -> 120, r 15,92 -> 100), sonst
     stoesst am Kreisschluss ein zu kurzer Strich auf einen ganzen. */
  --senden-rand:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'><circle cx='20' cy='20' r='19.1' fill='none' stroke='rgb(255,255,255)' stroke-opacity='.32' stroke-width='1.5' stroke-dasharray='4.5 5.5'/></svg>");
  --flieger-rand:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 34'><circle cx='17' cy='17' r='15.92' fill='none' stroke='rgb(255,255,255)' stroke-opacity='.32' stroke-width='1.5' stroke-dasharray='4.5 5.5'/></svg>");

  /* DER KRINGEL UND DER BOBBEL, WOERTLICH AUS DEM FAVICON (30.08.26,
     design.html). Das Zeichen stand schon da: favicon.svg zeigt seit
     jeher einen von Hand gezogenen offenen Ring mit einem Bobbel darin.
     Der Pfad ist Zeichen fuer Zeichen derselbe, nur die zwei Farben des
     Favicons sind raus — im Spiel traegt beides EINE Farbe.
     Beide Masken teilen denselben quadratischen viewBox und liegen auf
     inset:0, damit der Bobbel gegenueber dem Ring genau so schief sitzt
     wie im Favicon, ohne dass hier ein Versatz gerechnet wird.
     Der AUSGEFUELLTE traegt fill UND stroke: der sichtbare Umriss ist
     die Aussenkante des Strichs, sonst waere er um die halbe
     Strichbreite kleiner als der offene und damit ein anderer Kreis.
     --gemalt und --gemalt-2 bleiben stehen: die Landingpage und der
     Textmarker brauchen sie weiter. */
  --kringel:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-5.75 -5.75 11.5 11.5'><path d='M-4.5,-2.7 C-2.7,-6.1 3.5,-5.5 4.9,-1.3 C6.1,2.5 1.3,5.7 -2.5,3.9 C-5.3,2.5 -5.7,-0.3 -4.3,-2.3' fill='none' stroke='black' stroke-width='1.2' stroke-linecap='round'/></svg>");
  --bobbel:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-5.75 -5.75 11.5 11.5'><circle cx='0' cy='0' r='1.9' fill='black'/></svg>");
  --kringel-voll:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-5.75 -5.75 11.5 11.5'><path d='M-4.5,-2.7 C-2.7,-6.1 3.5,-5.5 4.9,-1.3 C6.1,2.5 1.3,5.7 -2.5,3.9 C-5.3,2.5 -5.7,-0.3 -4.3,-2.3' fill='black' stroke='black' stroke-width='1.2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  /* die vier Grundfarben, kein Akzent, sie kommen immer mal wieder vor */
  --orange:#e07b2f; --pink:#ef6aa8; --walblau:#04adbf; --violett:#a06ce0;
  --s-lesen:'Hanken Grotesk',system-ui,sans-serif;
  --s-regie:'Barlow Condensed',var(--s-lesen);
  --s-hand:'Caveat',cursive;
  /* Fines Handschrift (design.html: PERSONEN-HANDSCHRIFTEN). Bisher
     stand sie im Spiel nur woertlich (To-Do-Liste); mit dem Wortzettel
     (28.08.26) braucht sie einen Namen, denselben wie in der Bibel. */
  --s-fine:'Patrick Hand',cursive;
  --ts:1;
  --hanken:calc(19px * var(--ts));
  --barlow:calc(17px * var(--ts));   /* seit 28.08.26: 17 statt 16 (Regie eine Groesse groesser, ganzes Spiel);
                                        davor 24.08.26 abends 16 statt 15 (Laura). Nachgezogen aus design.html.
                                        Die kleinen Regie-Etiketten haengen seit dem 28.08.26 als Bruchteile
                                        an dieser Zahl und gehen jeden Schritt mit. */
  --caveat-titel:calc(42px * var(--ts));
  --caveat-hand:calc(27.5px * var(--ts));
  /* Fines Kartenzettel-Lauf (design.html: 15,5 auf 1,45; der Titel
     20/1,25 steht an seiner Stelle). Bis 30.08.26 stand die Variable
     nur in der Bibel — wer sie hier brauchte, fiel still auf die
     geerbte Groesse zurueck. */
  --patrick:calc(15.5px * var(--ts));
  --zeile:calc(26px * var(--ts));
  --zeile-barlow:calc(21px * var(--ts));
  --zeile-werkzeug:1.45;
  /* DER MASSSTAB EINZELNER SZENEN. Buehnenbreite geteilt durch 390,
     geklemmt auf 0,85 bis 1,15; gesetzt in game.js (massstabSetzen),
     die 1 hier ist der Rueckfall. Er gilt NICHT allgemein: die
     Grammatik (Text, Spalte, Knopfhoehe, die Kisten im Stapel) rechnet
     weiter in festen px. Nur einzelne Szenen nehmen ihn, wo sie
     ausdruecklich damit gebaut wurden. */
  --e:1;

  /* DER SPALTEN-DECKEL (design.html, 24.08.26): ein Bildschirm liegt
     ueber allem und erbt die 430 der Buehne nicht, deshalb hat jede
     Textzeile ihren eigenen Deckel */
  --spalte:362px;
  /* DIE WAHL-GRUNDLINIE (Laura, 24.08.26: "nicht hardcoden, sondern
     generell festlegen"): wo immer gewaehlt oder geantwortet wird,
     steht die UNTERSTE Kante der Kaesten auf dieser Hoehe ueber dem
     unteren Rand, egal wie viele Kaesten es sind und wie ihr Text
     umbricht. Wer die Hoehe aendert, aendert nur diese zwei Werte.
     SIE HAENGT AM KNOPF (27.08.26). Die Unterkante der Tastflaeche
     liegt bei --knopf-mitte minus 38 (halbe Knopfhoehe), die Wahl
     steht einen Pixel darunter. Beide Grundlinien sind damit dieselbe,
     und eine Entscheidung sieht ueberall gleich aus, egal ob sie aus
     einem Klecks oder aus Kaesten besteht. Als der Knopf am 27.08.26
     von 85 auf 70 fiel, ging die Wahl von 46 auf 31 mit. Wer den Knopf
     wieder bewegt, bewegt diese Zahl im selben Schritt. */
  --wahl-boden:31px;
  /* DIE HOEHE DES WEITER-KNOPFES (design.html, 24.08.26; hier
     nachgezogen am 25.08.26 auf Lauras Ansage beim Regel-Audit):
     die MITTE des Kleckses sitzt IMMER gleich hoch ueber der
     Unterkante, in jeder Szene und auf jedem Bildschirm; damals
     waren das 85 px. Vorher hielten hier
     noch die zwei Alt-Werte (Szene 111, Schirme 58), deren
     Mittelwert Laura zur einen Hoehe gemacht hat. Der Fuss ist genau
     doppelt so hoch und haelt den Knopf mittig; die Sicherheitszone
     kommt oben drauf und nicht in die Rechnung (in der Szene traegt
     .spiel sie schon als padding). Wer die Hoehe aendert, aendert
     sie in design.html und zieht sie hier nach, nie umgekehrt.

     SEIT DEM 27.08.26 SIND ES 70 (Laura: "ich will dass der gesamte
     raum unten, also fuss von 170 auf 140 px faellt. das ist auch
     schon ein gewinn und ein gutes mittel, dann kann der gelbe knopf
     ein kleines stueck runter"). Der Fuss ist das Doppelte, also
     bestimmt diese eine Zahl beides: 70 macht 140. Der Knopf faellt
     dabei 15 px, seine Unterkante von 47 auf 32. Tiefer geht nicht
     folgenlos: bei 60 stuende die Tastflaeche nur noch 22 px ueber der
     Bildschirmkante und damit auf Android in der Gestenleiste.
     Die 30 px, die der Fuss abgibt, nimmt sich die Buehne (flex:1);
     Zeile, Kisten und alles, was unten in der Szene haengt, wandert
     mit ihr 30 px tiefer. */
  --knopf-mitte:70px;
  --fusshoehe:calc(var(--knopf-mitte) * 2);
  /* DER FUSS AM STAPEL (Laura, 26.08.26, nach dem Handy-Bild: "der
     text klebt so krass an den kartons, dabei ist drunter noch
     platz"). Der Platz drunter WAR der Fuss: 170 px fest, und am
     Sortier-Stapel meistens leer, weil dort gezogen und nicht getippt
     wird. Er faellt darum auf 130, und der Fluss nimmt sich die 40 px
     dazu (Regel .spiel.amstapel weiter unten). Es wandert nur der
     Text: die Buehne behaelt ihre Hoehe, die zwei Kisten stehen, wo
     sie standen.
     130 UND NICHT 48 WIE BEIM RAETSEL (Lauras Auflage: "es kann nach
     unten, aber nicht ganz nach unten"). Zwischen den sechs Dingen
     stehen Weiter-Klicks; der Klecks braucht seine Mitte weiter auf
     --knopf-mitte und seine Tastflaeche (92 x 76) darum herum. Sie
     reichte bei --knopf-mitte 85 bis 123 px hinauf, also war 130 die
     naechste runde Zahl, die sie noch trug. Seit der Knopf am 27.08.26
     auf 70 steht, reicht sie nur noch bis 108, die 130 haben also 22 px
     Reserve statt 7. Die Zahl bleibt trotzdem stehen: sie haelt
     zusammen mit --fluss-stapel diese eine Szene genau so, wie sie war.
     Wer hier tiefer geht, schiebt den Knopf in den Text. */
  --fuss-stapel:130px;
  /* die Grundhoehe des Flusses, bisher als 96 in seiner eigenen Regel.
     Sie steht hier, weil der Fuss und sie zusammen die Buehne bestimmen. */
  --flussmin:96px;
  /* DER FLUSS AM STAPEL, EINE EIGENE ZAHL (27.08.26). Bis dahin rechnete
     er sich aus --flussmin plus dem, was der Fuss abgab
     (96 + 170 - 130 = 136). Als der Fuss am 27.08.26 auf 140 fiel, waere
     daraus 106 geworden: die Sortier-Szene haette drei Viertel ihres
     Luftgewinns wieder verloren, obwohl an ihr nichts geaendert werden
     sollte. Laura: "dann kann man doch die sortier-stapel szene
     auslassen oder? tu das." Also steht das Ergebnis von damals jetzt
     als feste Zahl da, und die Szene sieht aus wie am 26.08.26.
     Sie ist damit die einzige, die den Bewegungen des Knopfes NICHT
     folgt. Wer sie wieder anhaengen will, schreibt hier
     calc(var(--flussmin) + var(--fusshoehe) - var(--fuss-stapel)). */
  --fluss-stapel:136px;
  /* DER KOPFSTREIFEN (Lauras Befund 25.08.26: Karton und Grabung lagen
     unter Neustart und Fragezeichen). Der Streifen oben gehoert den
     zwei festen Knoepfen samt dem Wort NEUSTART darunter (Knopf: 10px
     Abstand + 44px Box, das Wort haengt mit line-height 1 bis ~61px).
     Die Buehne BEGINNT erst darunter und schneidet ab (overflow:hidden
     an .buehne): keine Szene kann je wieder in die Knoepfe ragen, ohne
     dass es hier jemand von Hand falsch verschiebt. Werkbank und
     Demo-Bau rechnen gleich, damit Lauras Handy zeigt, was der Test
     sah, auch wenn die Knoepfe am Arbeitsstand meist unsichtbar sind.

     SEIT DEM 26.08.26 GILT DER STREIFEN AUCH FUERS GERAET (Laura:
     "1 immer"). Das Handy lag als Vollbild darunter, und die zwei
     Knoepfe standen mitten im Chatkopf. Handy, Kamera und Fotorolle
     beginnen jetzt erst unter dem Streifen; die Rechnung dazu steht in
     geraet.css bei #ov-handy und #fotogeraet und teilt durch --scale,
     weil das Panel zoom traegt. Einzige Ausnahme ist die LIEGENDE
     KARTE, die jeden Pixel Hoehe braucht: dort ist stattdessen das
     ZUMACHEN nach unten rechts gewandert. */
  --kopf:66px;
  --werkzeug:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --werkzeug-gross:11.5px;

  /* DER GEZOGENE MARKER-STRICH (25.08.26), IN FUENF FARBEN (26.08.26).
     Dieselbe Handschrift wie die gemalten Kreise, nur laenglich.
     preserveAspectRatio="none" zieht ihn auf jede Wortbreite; die Kanten
     bleiben unruhig, weil die Kurven es sind.
     Woertlich aus design.html, Stueck 12: die Form ist in allen zehn
     Zeilen dieselbe, es unterscheiden sie die Farbe und die Deckkraft.
     Wach .45, still .17. Er kam fuer Fabis Brief und traegt seit dem
     26.08.26 ALLES, was im Text angetippt werden kann; die zwei
     Wortknoepfe im Gruppenchat hatten bis dahin einen gepunkteten
     Unterstrich in Moewenblau. */
  --strich-orange:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(224,123,47)' fill-opacity='.45'/></svg>");
  --strich-pink:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(239,106,168)' fill-opacity='.45'/></svg>");
  --strich-walblau:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(4,173,191)' fill-opacity='.45'/></svg>");
  --strich-violett:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(160,108,224)' fill-opacity='.45'/></svg>");
  --strich-butter:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(229,194,106)' fill-opacity='.45'/></svg>");
  --strich-orange-still:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(224,123,47)' fill-opacity='.17'/></svg>");
  --strich-pink-still:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(239,106,168)' fill-opacity='.17'/></svg>");
  --strich-walblau-still:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(4,173,191)' fill-opacity='.17'/></svg>");
  --strich-violett-still:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(160,108,224)' fill-opacity='.17'/></svg>");
  --strich-butter-still:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 24' preserveAspectRatio='none'><path d='M1.8,6.9 C16,4.2 33,5.7 49,5.0 C65,4.3 82,5.4 98.2,5.9 C99.2,10.1 98.9,14.7 97.5,18.5 C81,20.0 64,18.6 48,19.4 C32,20.1 16,19.0 2.4,18.1 C1.0,14.5 0.9,10.4 1.8,6.9 Z' fill='rgb(229,194,106)' fill-opacity='.17'/></svg>");

  /* die zwei von Hand gezogenen Kreise und der breite Fleck */
  --gemalt:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><path d='M50.5,4.2 C64.2,3.3 78.6,9.9 87.3,21.5 C94.7,31.3 96.9,44.7 95.1,56.9 C93.2,70.3 85.3,82.7 73.1,89.5 C61.7,95.9 47.1,97.3 35.1,92.4 C22.3,87.2 11.5,76.3 6.8,63.1 C2.3,50.5 3.5,35.7 10.7,24.5 C18.3,12.7 33.0,5.1 50.5,4.2 Z' fill='black'/></svg>");
  --gemalt-2:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><path d='M52.4,7.1 C66.8,7.9 79.4,16.2 86.6,28.4 C92.9,39.1 93.4,53.2 88.6,64.7 C83.4,77.1 71.6,86.9 58.3,89.3 C45.1,91.6 30.6,86.7 21.2,77.0 C11.6,67.1 7.4,52.2 10.6,38.9 C13.9,25.2 25.4,13.2 39.2,9.1 C43.4,7.8 47.9,6.8 52.4,7.1 Z' fill='black'/></svg>");
  --gemalt-3:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 96'><path d='M13,50 C9,34 26,20 52,12 C72,6 96,9 120,6 C150,3 190,14 191,34 C192,51 186,71 160,81 C134,92 88,92 56,85 C32,80 16,68 13,50 Z' fill='black'/></svg>");
}

/* =====================================================================
   ANGESTRICHEN: EINE REGEL FUER ALLES ANTIPPBARE IM TEXT (26.08.26)
   Die Regel steht in design.html, Stueck 12, und hier steht sie noch
   einmal so, wie das Spiel sie benutzt: was angetippt werden kann, ist
   mit dem Textmarker unterlegt. Nicht unterstrichen, nicht gepunktet,
   nicht in einer anderen Schrift oder Farbe gesetzt. Die Farbe sagt
   nur, wem die Stelle gehoert: walblau Fabi, orange Fine.
   Sie sitzt auf beiden Bauarten, ohne dass man es sieht: im Chat baut
   game.js Knoepfe (.p-wort), im Brief stehen Marken im Text.
   ===================================================================== */
.angestrichen,
.f2y-brief .absatz mark{
  display:inline;-webkit-appearance:none;appearance:none;
  background-color:transparent;color:inherit;
  background-image:var(--strich);
  background-repeat:no-repeat;background-size:100% 100%;
  /* das Polster darf die Zeile nicht hoeher machen. Waagerecht wird es
     wieder herausgezogen, damit der Strich ueber das Wort hinausragt
     und der Satz trotzdem gleich lang bleibt; senkrecht ebenso, und das
     gilt dem KNOPF: eine Marke ist inline und traegt ihr Polster ohne
     Wirkung auf die Zeilenhoehe, ein Knopf ist eine Kiste und schiebt
     die Zeile auf. Nachgemessen an der Chatzeile: 78 px mit Marke,
     86 px mit Knopf, 78 px mit diesem Ausgleich. */
  padding:.1em .22em;margin:-.1em -.22em;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
  text-decoration:none;border:0;font:inherit;cursor:pointer}
/* gelesen ist gelesen: der Strich wird still und bleibt es */
.angestrichen.gelesen,
.f2y-brief .absatz mark.gelesen{background-image:var(--strich-still)}
/* je Farbe eine Zeile, und die traegt beide Zustaende */
.angestrichen.orange {--strich:var(--strich-orange); --strich-still:var(--strich-orange-still)}
.angestrichen.pink   {--strich:var(--strich-pink);   --strich-still:var(--strich-pink-still)}
.angestrichen.walblau{--strich:var(--strich-walblau);--strich-still:var(--strich-walblau-still)}
.angestrichen.violett{--strich:var(--strich-violett);--strich-still:var(--strich-violett-still)}
.angestrichen.butter {--strich:var(--strich-butter); --strich-still:var(--strich-butter-still)}
/* FABIS BRIEF IST GANZ WALBLAU, und die Farbe haengt am Blatt und nicht
   an der einzelnen Marke: seine Stellen stehen in texte.js und sollen
   dort nichts sein als Text, den man lektorieren kann. */
.f2y-brief{--strich:var(--strich-walblau);--strich-still:var(--strich-walblau-still)}

/* =====================================================================
   WIE STARK DAS LICHT AM HANDY IST (Laura, 26.08.26: "alle lichtkegel,
   beide fenster szenen und nachtischlampe sind am handy auf voller
   helligkeit kaum sichtbar. warum? am pc schon").

   Es war kein Fehler im Bau: am Handy und am Rechner liefen dieselben
   Zahlen, keine Media Query drehte irgendwo an der Deckkraft. Sie
   liegen nur alle im untersten Zwanzigstel der Skala, und genau dort
   gehen die zwei Geraete auseinander. Der Grund (#0e0e10) ist auf
   einem vollen Handy rund 4,5 nits hell; der Nachmittagskegel legt an
   seinem Ende 2,3 nits drauf, der Morgenkegel 1,6, der Keil der
   Nachttischlampe 2,6. Drei Dinge fressen das am Handy auf, die es am
   Rechner nicht gibt:

   · OLED faehrt bei VOLLER Helligkeit die dunklen Toene herunter (bei
     niedriger hebt es sie an). Der Bereich, in dem hier alles lebt,
     laeuft dann zusammen. Ein Monitor hat dort unten eine flache
     Kurve und Grundleuchten, also bleibt alles getrennt.
   · Das Glas spiegelt. In einem hellen Zimmer wirft ein glaenzendes
     Handy rund 14 nits auf die ganze Flaeche zurueck, also mehr, als
     der Kegel ueberhaupt liefert. Ein Monitor ist matt, steht
     senkrecht und nicht im Gegenlicht.
   · Man dreht die Helligkeit ja gerade dann auf, wenn es hell ist.
     Beides trifft also immer zusammen.

   Darum dieser eine Faktor. Er gilt NUR am Finger (Handy-Fixes
   bleiben am Handy) und haengt an drei Stellen: .tf-keil (der
   Nachmittag), .mf-keil (der Morgen) und die drei Verlaeufe der
   Nachttischlampe in ikonen.js. Wer das Licht am Handy nachstellt,
   dreht HIER und nirgends sonst.

   2,1 IST LAURAS ZAHL (26.08.26): doppelt, damit am Handy ankommt,
   was am Rechner gemeint war, und dann noch fuenf Prozent obendrauf.

   DIE FENSTERSCHEIBEN HAENGEN NICHT DRAN. Sie stehen bei 81 nits, das
   Achtzehnfache des Grundes, und sind am Handy nie das Problem
   gewesen. Wer sie mitzoege, machte aus dem Fenster einen
   Scheinwerfer und kippte das Verhaeltnis zum Kegel.

   DIE TASCHENLAMPE HAENGT AUSDRUECKLICH NICHT DRAN (Laura im selben
   Atemzug: "ausser die taschenlampe erst mal"). Sie leuchtet nicht,
   sie verdunkelt, und unter ihrem rgba(8,8,8,.89) ist kein Platz
   mehr: auf leerem Grund macht sie sieben von 255 Stufen aus, und
   mehr Deckkraft macht daraus keine einzige mehr. Die braucht einen
   zweiten Verlauf, der im Kern AUFhellt, statt aussen abzudunkeln.
   ===================================================================== */
:root{ --handylicht:1 }
@media (pointer:coarse){ :root{ --handylicht:2.1 } }

*{box-sizing:border-box}
/* Doppeltipp darf nie zoomen (Laura, 25.08.26: "Menschen werden
   staendig doppelt klicken"). manipulation laesst Scrollen und das
   Zwei-Finger-Zoomen in Ruhe und nimmt nur den Doppeltipp-Zoom weg;
   die strengeren touch-action:none an den Ziehdingen gewinnen per
   Spezifitaet weiterhin. */
*{touch-action:manipulation}
html,body{margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--grund); color:var(--tinte);
  font-family:var(--s-lesen); font-size:var(--hanken);
  line-height:var(--zeile); min-height:100dvh; overscroll-behavior:none;
  -webkit-font-smoothing:antialiased; overflow:hidden;
}
@media(pointer:coarse){
  body{user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}
}

/* =====================================================================
   DIE ZWEI GRAUEN BALKEN AUF DEN SCHWARZEN BILDSCHIRMEN (Lauras Befund
   26.08.26 am eigenen iPhone: "die grauen balken unten und oben").

   Das Spiel hat zwei Schwarz, und beide sind so gewollt: der Grund ist
   --grund (#0e0e10, Lauras Mittelwert), ein schwarzer Bildschirm ist
   reines #000. Solange beide nur nacheinander zu sehen sind, faellt das
   nicht auf.

   Am Handy sind sie aber GLEICHZEITIG zu sehen. Ein .schirm liegt
   position:fixed;inset:0 und deckt damit den Layout-Bereich ab, nicht
   den ganzen Bildschirm: was darueber und darunter noch dazugehoert
   (Safaris eingeklappte Leisten, in der Homescreen-App die
   Sicherheitszonen), faerbt der Koerper. Also reines Schwarz in der
   Mitte und #0e0e10 als Streifen oben und unten. Vierzehn von 255
   Stufen Unterschied, auf OLED im Dunkeln deutlich sichtbar.

   Die Loesung nimmt weder dem Grund noch dem Schwarz etwas weg: der
   KOERPER wird schwarz, solange oben ein schwarzer Bildschirm liegt.
   Danach ist er wieder --grund. WICHTIG: geaendert wird die
   background-Eigenschaft, NICHT die Variable --grund. Alles, was aus
   --grund rechnet (die Fenstersprossen, die Verdeckungen der
   uebernommenen Zeichnungen, das Eingabefeld im Chat), bleibt damit
   unberuehrt.

   DREI FLAECHEN sind reines Schwarz und meinen dasselbe: der schwarze
   Bildschirm, der Funkenwirbel und der Nachtkreisel. Alle drei stehen
   hier, sonst waeren die Balken in der Nacht wieder da.
   Der Demo-Schirm (.f2y-demo) steht bewusst NICHT dabei: er ist schon
   --grund und braucht nichts.

   :has() statt einer Klasse aus game.js, weil die drei Flaechen an
   sechs verschiedenen Stellen kommen und gehen; eine Klasse waere
   irgendwann haengengeblieben. Wo :has() fehlt (sehr alte Geraete),
   bleibt es beim heutigen Bild, es geht also nichts kaputt.
   ===================================================================== */
body:has(.schirm:not([hidden])),
body:has(#wirbelschirm),
body:has(.f2y-kreisel){background:#000}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}

/* ---------- der Klecks: still (Knopf), ziehend, atmend ---------- */
.klecks{position:relative;display:block;width:var(--kl,48px);height:var(--kl,48px);pointer-events:none}
.klecks::before,.klecks::after{
  content:"";position:absolute;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%;mask-size:100% 100%;
  transition:background-color .2s ease, transform .2s cubic-bezier(.3,.9,.3,1);
}
/* JEDER Klecks traegt dieselbe eine Farbe, ohne Ausnahme (design.html,
   30.08.26): moewenblau, an --klecks-rgb und sonst nirgends. Die zwei
   Lagen sind Ring und Bobbel; der Bobbel steht eine Spur darunter bei
   .9, ganz gleich waeren die zwei eine Flaeche mit Loch statt zweier
   Zuege. Keine Drehung mehr: der Ring ist von Hand gezogen und schon
   schief, eine Drehung obendrauf waere eine erfundene Unregelmaessigkeit
   auf einer echten. */
.klecks::before{inset:0;
  -webkit-mask-image:var(--kringel);mask-image:var(--kringel);
  background-color:rgb(var(--klecks-rgb))}
.klecks::after{inset:0;
  -webkit-mask-image:var(--bobbel);mask-image:var(--bobbel);
  background-color:rgb(var(--klecks-rgb) / .9)}

/* ---------- DER AUSGEFUELLTE KRINGEL: TIPPEN UND WISCHEN ----------
   design.html sagt es mit einer Klasse (.klecks.voll), das Spiel sagt
   es mit dem BEHAELTER — und beides steht hier in EINER Regel, damit
   die zwei Schreibweisen nie auseinanderlaufen koennen.
   Warum der Behaelter: game.js schreibt den Klecks an 30 Stellen
   woertlich als <span class="klecks">, immer in genau einem von zwei
   Nestern. Steckt er in einem .knopf-weiter, ist er ein KNOPF; steckt
   er in einer der Gesten-Einladungen, ist er eine GESTE. Das Nest weiss
   es also schon, und keine der 30 Stellen muss angefasst werden. Wer
   eine neue Gesten-Einladung baut, traegt ihren Namen hier ein — oder
   haengt .voll an den Klecks, das tut dasselbe.
   Der Bobbel faellt ganz weg (content:none) und nicht nur seine
   Sichtbarkeit, sonst laege eine unsichtbare zweite Maske ueber jedem
   gefuellten Kreis. */
.klecks.voll::after,
.tipp-hier .klecks::after,
.zieh-zug .klecks::after,
.rolle-wisch .klecks::after,
.wisch-zug .klecks::after,
.d-zug .klecks::after,
.wal-zug .klecks::after,
.bd-zug .klecks::after{content:none}
.klecks.voll::before,
.tipp-hier .klecks::before,
.zieh-zug .klecks::before,
.rolle-wisch .klecks::before,
.wisch-zug .klecks::before,
.d-zug .klecks::before,
.wal-zug .klecks::before,
.bd-zug .klecks::before{
  -webkit-mask-image:var(--kringel-voll);mask-image:var(--kringel-voll)}

/* 1 · der Knopf (die Butter kommt seit dem 24.08.26 spaetabends aus
   der Klecks-Grundregel: eine Regel statt drei Ausnahmen) */
.knopf-weiter{position:relative;display:flex;align-items:center;justify-content:center;
  width:92px;height:76px;margin:0 auto}
/* Gedrueckt geht der RING zusammen und der BOBBEL waechst, nicht beide
   in dieselbe Richtung: es sieht aus, als druecke der Daumen den Punkt
   breit. Die Farbe bleibt stehen, sie hat hier nichts mehr zu sagen. */
.knopf-weiter.gedrueckt .klecks::before{transform:scale(.93)}
.knopf-weiter.gedrueckt .klecks::after{transform:scale(1.24)}
/* DER ZAEHE PUNKT (Nachtgedanken, 26.08.26). Keine eigene Gestalt: es
   ist derselbe gedrueckt-Zustand, er braucht nur so lange, wie man
   halten muss (--dr kommt aus game.js). Losgelassen faellt die Klasse
   weg, und er federt in seiner normalen Zeit zurueck. */
.knopf-weiter.zaeh .klecks::before,
.knopf-weiter.zaeh .klecks::after{transition-duration:var(--dr,.2s);transition-timing-function:linear}

/* 2 · die Wahl */
.wahlfeld{display:flex;flex-direction:column;align-items:flex-start;gap:11px}
.wahl{
  position:relative;display:inline-block;width:auto;max-width:100%;
  padding:.36em .9em;line-height:var(--zeile);text-align:left;background:none;
  border:1.5px solid transparent;border-radius:11px;
  transition:background-color .22s ease, color .22s ease, opacity .22s ease;
}
.w-rand{position:absolute;left:.75px;top:.75px;
  width:calc(100% - 1.5px);height:calc(100% - 1.5px);
  overflow:visible;pointer-events:none;transition:opacity .22s ease}
.w-rand rect{fill:none;stroke:rgb(255 255 255 / .32);stroke-width:1.5;
  stroke-dasharray:4.5 5.5;stroke-linecap:butt}
.wahl.gewaehlt{background:var(--moewe);color:var(--tinte-dunkel)}
.wahl.gewaehlt .w-rand{opacity:0}
.wahl.nicht{opacity:.38}
@keyframes ruf-atem{0%,100%{transform:scale(.985)}50%{transform:scale(1.045)}}
@keyframes ruf-stups{
  0%,84%,100%{transform:rotate(0)}
  88%{transform:rotate(-2.6deg)}
  92%{transform:rotate(1.7deg)}
  96%{transform:rotate(-.5deg)}}

/* 6 · Bildschirm 1, schwarz mit einer Zeile. KEIN BILDSCHIRM OHNE
   SICHTBAREN WEG WEITER (Laura, 24.08.26, design.html): unten liegt
   der Klecks als Knopf, die Zeile bleibt absolut mittig, der Fuss
   haengt absolut am unteren Rand und schiebt nichts.
   [hidden] braucht seine eigene Regel, sonst liegt der Schirm
   unsichtbar ueber allem und faengt jeden Klick ab (Hausregel). */
.schirm{position:fixed;inset:0;z-index:90;background:#000;
  display:flex;align-items:center;justify-content:center;padding:0 34px}
.schirm[hidden]{display:none}
.schirm-zeile{margin:0;text-align:center;
  font-family:'Hanken Grotesk',system-ui,sans-serif;
  font-size:var(--hanken);line-height:var(--zeile);color:var(--tinte)}
/* Der Fuss ist genau doppelt so hoch wie --knopf-mitte, der Knopf
   steht mittig darin: dann liegt seine Mitte exakt --knopf-mitte
   ueber der Unterkante (Bauart woertlich aus design.html; vorher
   standen hier 116 px, also die alten 58). */
.schirm .st-fuss{position:absolute;left:0;right:0;bottom:0;
  height:calc(var(--knopf-mitte) * 2 + env(safe-area-inset-bottom,0px));
  display:flex;align-items:center;justify-content:center;
  padding-bottom:env(safe-area-inset-bottom,0px)}
/* EINE WAHL AUF DEM SCHWARZ (26.08.26, bisher nur der
   Wiedereinstieg: "Spiel fortsetzen" / "Von Vorne anfangen"). Vorher
   stand hier ein leiser zweiter Weg ueber dem Klecks; Laura wollte
   stattdessen die Kaesten, mit denen im Spiel jede Entscheidung
   getroffen wird. Also gilt hier woertlich die Geometrie aus dem
   Fuss: dieselbe Spalte, dieselbe Hoehe ueber dem Rand, dieselbe
   Bewegung. Eine Entscheidung sieht ueberall gleich aus, egal ob eine
   Szene darunter liegt oder Schwarz. Ein Fuss steht dann nicht mehr
   da: die Kaesten SIND der Weg weiter. */
.schirm .wahlfeld{position:absolute;left:26px;right:26px;
  max-width:var(--spalte);margin-inline:auto;
  bottom:calc(var(--wahl-boden) + env(safe-area-inset-bottom, 0px));
  align-items:center;justify-content:flex-end}
/* backwards wie bei .fuss .wahl: der vorwaerts gefuellte Endwert
   schluege .nicht (Begruendung dort) */
.schirm .wahl{animation:wahl-rein .35s cubic-bezier(.25,.8,.3,1) backwards}
.schirm .wahlfeld.geht .wahl{transition:opacity .3s ease;opacity:0}

/* =====================================================================
   DIE SZENE. Eine Spalte, 430 breit, am Rechner dieselbe mittig.
   Von oben nach unten: Buehne, Fluss, Fuss. Der Fuss ist fest hoch,
   damit beim Wechsel zwischen Knopf und Wahl nichts springt und der
   Daumen immer an derselben Stelle liegt.
   ===================================================================== */
.spiel{position:relative;height:100vh;height:100svh;max-width:430px;margin:0 auto;
  display:flex;flex-direction:column;
  /* nicht 6px: der Kopfstreifen (--kopf, oben erklaert) haelt die
     Buehne unter Neustart und Fragezeichen */
  padding-top:calc(var(--kopf) + env(safe-area-inset-top,0px));
  padding-bottom:env(safe-area-inset-bottom,0px)}

.buehne{position:relative;flex:1 1 auto;min-height:230px;overflow:hidden}

/* ---------- die Zeile in der Szene ----------
   In der Szene steht EINE Zeile, unten ueber dem Daumen. Die alte
   loest sich auf, wenn die neue kommt; die Buehne traegt den Rest.
   (Der Fluss mit den letzten drei bleibt Bildschirm 2 vorbehalten.)
   Grundhoehe drei Zeilen, damit beim Sortieren nichts springt; eine
   lange Rede (der Nachbar) darf den Kasten wachsen lassen, sonst wird
   ihr Anfang oben abgeschnitten (Lauras Befund 24.08.26). */
/* DER FLUSS HAT SEINE EIGENE EBENE (26.08.26, mit dem Herbstregen).
   Ohne sie haengt es davon ab, ob flussAusweichen gerade ein transform
   gesetzt hat, ob der Text ueber oder unter einer Buehnen-Ebene liegt.
   Begruendung ausfuehrlich oben bei .f2y-herbst. */
.fluss{position:relative;z-index:1;
  flex:0 0 auto;min-height:var(--flussmin);display:flex;flex-direction:column;
  justify-content:flex-end;padding:0 26px 2px;overflow:hidden;
  /* flussAusweichen() (game.js) hebt den Fluss an, wenn die Wahl
     ueber den Fuss hinauswaechst; transform, damit die Buehne steht */
  transition:transform .35s ease, min-height .5s cubic-bezier(.3,.8,.3,1)}

/* DER STAPEL SCHIEBT DIE ZEILE TIEFER (Laura, 26.08.26). Ihr Befund am
   Handy: "der text klebt so krass an den kartons, dabei ist drunter
   noch platz". Gemessen war der Platz drunter der Fuss, 170 px, in
   dieser Szene meistens leer, weil ein Ding gezogen und nicht
   angetippt wird. Der Text sass an der Buehnen-Unterkante fest, weil
   die Buehne als einzige nachgibt (flex:1) und die zwei Kisten an
   ihrem Boden stehen.

   ZWEI ZAHLEN, EINE VERSCHIEBUNG. Der Fuss faellt auf --fuss-stapel
   (130), und der Fluss steht auf --fluss-stapel (136) statt auf seinen
   96. Damit wandert NUR die Zeile: die Buehne behaelt ihre Hoehe, die
   Kisten und die Etiketten bleiben stehen, und der Abstand vom Wort
   KOMMT MIT zur Zeile waechst von rund 40 auf rund 80 px. Wer eine der
   Zahlen aendert, aendert sie an der Wurzel, nicht hier.

   DIESE SZENE IST AUSGENOMMEN (27.08.26). Die 136 waren bis dahin
   gerechnet: 96 plus das, was der Fuss abgab. Mit dem kuerzeren Fuss
   (140) waeren daraus 106 geworden, der Luftgewinn also von 40 auf 10
   geschrumpft. Auf Lauras Ansage steht die Zahl jetzt fest in
   --fluss-stapel, und die Szene sieht aus wie vor der Verkuerzung: die
   Buehne bleibt hier 30 px kuerzer als in allen anderen Szenen, die
   Kisten stehen, wo sie standen.

   DER KLECKS FOLGT TROTZDEM (27.08.26). Im Fuss steht er sonst mittig,
   seine Mitte haengt also an der Fusshoehe und waere hier auf 65 px
   gerutscht. Das Gesetz aus design.html sagt aber: die Mitte sitzt
   IMMER --knopf-mitte ueber der Unterkante. Darum haengt er absolut an
   derselben Grundlinie, die auch die Schirme benutzen (--knopf-mitte
   minus die halbe Tastflaeche). Ausgenommen ist die BUEHNE dieser
   Szene, nicht der Daumen: der Knopf steht auch hier auf den
   Millimeter da, wo er im ganzen Rest des Spiels steht. Seit dem
   27.08.26 liegen ueber ihm rund 50 px Luft bis zur Zeile statt 35,
   weil er 15 px gefallen ist und die Zeile stehen blieb.

   DIE WAHL BRAUCHT KEINE EIGENE ZAHL. Sie haengt an --wahl-boden und
   stapelt nach oben; wird sie dem Text zu nah (die Auflaufform),
   hebt flussAusweichen() den ganzen Fluss an, gemessen statt geraten.

   Die Klasse setzt game.js an buehneAuf/buehneWieder und nimmt sie in
   buehneZu, also genau dann, wenn die zwei Kisten kommen und gehen.
   Keine Szene muss daran denken. */
.spiel.amstapel .fuss{flex-basis:var(--fuss-stapel)}
.spiel.amstapel .fluss{min-height:var(--fluss-stapel)}
.spiel.amstapel .fuss .knopf-weiter{position:absolute;left:0;right:0;
  bottom:calc(var(--knopf-mitte) - 38px)}

/* DER BRIEF NIMMT SICH DEN FLUSS (Laura, 25.08.26: die Zeile "Die
   Rueckseite." verschwindet, sobald der Brief offen ist, "dann wird die
   Flaeche, auf der der Brief erscheint, auch groesser"). Der Fluss faellt
   auf null, die Buehne (flex:1) waechst in den Platz hinein. Ihre
   Gedanken an den Markern kommen auf dem Wortzettel (seit 28.08.26;
   davor als Zeile im Fuss). Beim Zufalten kommt der Fluss zurueck,
   weil die Regie-Zeile l3 dort hingehoert. */
.spiel.briefoffen .fluss{min-height:0;padding-bottom:0}
/* DAS RAETSEL NIMMT SICH DEN FUSS (Laura, 26.08.26, zum Bonraetsel am
   Handy: "die regie muss hier ausnahmsweise viel weiter runter, damit
   das ganze raetsel sichtbar ist"). Solange gelegt wird, steht im Fuss
   nichts: kein Klecks, keine Wahl. Also faellt er auf einen schmalen
   Rand zusammen und der Fluss auf seine eine Zeile; die Buehne
   (flex:1) waechst um beides in die fuenf Schlitze und fuenf Streifen
   hinein, und die Regie-Zeile rutscht dabei ganz nach unten.
   Das Gegenstueck zu .spiel.briefoffen darueber: dort nimmt sich der
   Brief den Fluss, hier nimmt sich das Raetsel den Fuss.
   game.js setzt und nimmt die Klasse in nachtBon(). */
.spiel.raetseloffen .fluss{min-height:0}
/* min-height:0 gehoert dazu: ein Flex-Kasten faellt sonst nie unter
   die Groesse seines Inhalts, und der stille Weiter-Klecks steht auch
   unsichtbar noch 76 px hoch im Fuss. Die 48 px sind der Rand, auf dem
   die Regie-Zeile aufsitzt. */
.spiel.raetseloffen .fuss{flex-basis:48px;min-height:0}
/* der Fuss faehrt zusammen und wieder auf, statt zu springen. Sonst
   animiert er nie: seine Hoehe ist im ganzen Spiel fest. */
.fuss{transition:flex-basis .5s cubic-bezier(.3,.8,.3,1)}

@media (prefers-reduced-motion: reduce){
  .fluss,.fuss{transition:none}
}
/* Die Blende steht in game.js (TAKT.zeileWeg) und kommt von dort als
   --takt-zeile-weg herein: dieselbe Zahl wartet dort ab, bevor die
   Zeile aus dem Dokument geht. Der Rueckfall .45s ist der Wert, der
   hier bis zum 25.08.26 stand, falls das Skript nicht laeuft. */
.satz{margin:0 0 12px;max-width:var(--spalte);margin-inline:auto;width:100%;
  font-size:var(--hanken);line-height:var(--zeile);color:var(--tinte);
  transition:opacity var(--takt-zeile-weg, .45s) ease}
.satz.regie{font-family:var(--s-regie);font-size:var(--barlow);line-height:var(--zeile-barlow);
  color:var(--regie);letter-spacing:.14em;text-transform:uppercase}
.satz.jetzt{animation:satz-rein .5s cubic-bezier(.25,.8,.3,1)}
@keyframes satz-rein{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}
.satz.weg{opacity:0}
/* die Gedanken eines angetippten Grabungs-Dings: zentriert, jeder
   Teil ein eigener Absatz (Laura, 24.08.26: "nicht als textblock") */
.satz.mittig{text-align:center}
.satz.mittig .abs{display:block}
.satz.mittig .abs + .abs{margin-top:.5em}

/* ---------- der Fuss: Knopf und Wahl teilen sich den Platz.
   Die Wahl haengt an der GRUNDLINIE (--wahl-boden) und stapelt nach
   oben: die unterste Kante liegt immer gleich hoch. ---------- */
.fuss{position:relative;flex:0 0 var(--fusshoehe);display:flex;align-items:center;justify-content:center}
.fuss .knopf-weiter{transition:opacity .25s ease}
.fuss .knopf-weiter.still{opacity:0;pointer-events:none}
.fuss .wahlfeld{position:absolute;left:26px;right:26px;
  bottom:calc(var(--wahl-boden) + env(safe-area-inset-bottom, 0px));
  align-items:center;justify-content:flex-end}
/* backwards, nicht both: der Ruecken deckt nur die Anlauf-Verzoegerung
   (animationDelay in game.js). Ein VORWAERTS gefuellter Endwert hielte
   opacity fuer immer auf 1 und schluege .wahl.nicht — der gesperrte
   Lena-Kasten am Kai (28.08.26) stand sonst ungedimmt da. */
.fuss .wahl{animation:wahl-rein .35s cubic-bezier(.25,.8,.3,1) backwards}
@keyframes wahl-rein{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
.fuss .wahlfeld.geht .wahl{transition:opacity .3s ease;opacity:0}

/* Werkbank-Zeilen im Fuss, Systemschrift, nicht Spiel */
.wnotiz{position:absolute;inset:0;display:flex;flex-direction:column;gap:14px;
  align-items:center;justify-content:center;text-align:center;
  font-family:var(--werkzeug);font-size:var(--werkzeug-gross);
  line-height:var(--zeile-werkzeug);letter-spacing:.08em;text-transform:uppercase;
  color:var(--regie);animation:satz-rein .5s ease both}
.wnotiz span{opacity:.45}
.wnotiz button{opacity:.6;padding:8px 14px;letter-spacing:.08em;text-transform:uppercase;
  font-size:var(--werkzeug-gross)}

/* ---------- was auf der Buehne steht ----------
   HOECHSTENS DREI DINGE GLEICHZEITIG (Lauras Ansage: alles auf einmal
   klappt am Handy nicht): das eine Ding gross in der Mitte, die zwei
   Kisten unten. Keine Katze in dieser Szene (Laura, 24.08.26). Der
   Stapel selbst liegt ihr zu Fuessen, ausserhalb des Bildes; jedes
   Ding steigt einzeln von unten herauf. */
.buehne svg{display:block}

/* die zwei Ziele unten: links die Umzugskiste (die groessere),
   rechts die flache Kiste fuer die Strasse */
.ziel{position:absolute;bottom:30px;z-index:3}
.ziel-mit{left:4%;width:min(172px, 45%)}
.ziel-schenk{right:4%;width:min(158px, 41%)}
.ziel .kiste svg{width:100%;height:auto}
/* das Wort unter der Kiste: Regie-Register, still, immer lesbar. Es
   haengt absolut unter dem Ziel, damit Gucker-Zone und Kistenmasse
   nicht mitwandern. */
.ziel-wort{position:absolute;left:-10%;right:-10%;top:100%;margin-top:5px;
  text-align:center;font-family:var(--s-regie);font-size:var(--barlow);
  line-height:var(--zeile-barlow);letter-spacing:.14em;text-transform:uppercase;
  color:var(--regie);opacity:.6;white-space:nowrap}

/* was schon in einer Kiste liegt, lugt ueber ihren Rand. ES LIEGT
   HINTER DER KISTE (26.08.26): ihr Koerper ist ab dem vorderen
   Oeffnungsrand flaechig mit --grund gefuellt (ikonen.js, kistenSVG),
   also schneidet die Zeichnung selbst ab. Vorher lag das Stueck davor
   und ein eigener Deckel schnitt es ab; seine Striche kreuzten dabei
   die der Kiste (Laura, 26.08.26: "sind irgendwie noch Linien, die
   ueberlappen").
   WO ES STEHT, WEISS GAME.JS (--stand, gesetzt in buehneAuf aus der
   Tabelle KISTEN): hier standen 58 und 52 Prozent, geraten aus dem
   Kasten des Bildes. Bei der flachen Strassenkiste lag der Schnitt
   damit ueber der Zeichnung, und was in ihr lag, lugte aus der Luft.
   Die Standlinie ist die UNTERKANTE DER OEFFNUNG, nicht der vordere
   Rand der Kiste: beim Umzugskarton haengen zwei Laschen dazwischen.
   Auch die Breite kommt aus game.js (--pk) und rechnet wie alles
   Gezeichnete mit --e; links steht der Platz in Prozent der Kiste,
   die Mitte des Stueckes trifft ihn ueber translate(-50%). */
.peeks{position:absolute;left:0;right:0;height:52px;overflow:hidden;
  pointer-events:none;bottom:var(--stand, 50%);z-index:1}
.peek{position:absolute;bottom:0;transform:translate(-50%,105%);
  transition:transform .55s cubic-bezier(.3,1.3,.4,1)}
.peek.da{transform:translate(-50%,30%)}
.peek svg{display:block;width:calc(var(--pk, 24px) * var(--e));height:auto}

/* =====================================================================
   DAS FENSTER AN DER SEITE (Laura, 25.08.26). Die Uhrzeiten, die
   Geometrie des Kegels und die Begruendung stehen in game.js (Block
   "DAS FENSTER AN DER SEITE"); hier steht nur, wie es aussieht.

   Alles liegt IN der Buehne auf z-index 1: ueber dem Grund, unter den
   zwei Kisten (3) und unter der Flugebene (5). Ein Ding, das in eine
   Kiste faellt, liegt also vor dem Licht.

   FOKUS IST WOANDERS (Lauras Ansage). Die Deckkraften hier sind
   absichtlich so niedrig, dass man das Licht zuerst uebersieht. Es
   soll den Raum erklaeren, nicht ihn an sich ziehen.

   DIE FARBE IST KEIN BUTTER. Das Gelb des Spiels gehoert dem Daumen
   (Drei-Orte-Regel, design.html). --tag-hell ist ein warmes Weiss, das
   mehr Bernstein traegt, als es "haben" duerfte: bei der Deckkraft,
   die ein dunkles Spiel vertraegt, verschwindet Saettigung sonst
   ganz. Der Abend mischt --orange dazu, eine der vier Grundfarben.
   ===================================================================== */
:root{
  --tag-hell:#ffd49a;
  /* die Farbe des Nachmittags: --tf-warm faehrt sie von Weiss (Stand 1)
     nach Orange (Stand 6). Sie steht an :root, weil auch die Dinge sie
     brauchen, die durch den Kegel fliegen. */
  --tag-farbe:color-mix(in srgb, var(--tag-hell), var(--orange) calc(var(--tf-warm, 0) * 100%));
}

/* er deckt die ganze Spielspalte ab, nicht nur die Buehne (game.js,
   tagfensterBauen). overflow:hidden an ihm selbst: .spiel schneidet
   nicht ab, und am Rechner darf kein Licht neben dem Handy liegen. */
#tagfenster{position:absolute; inset:0; z-index:0; pointer-events:none;
  overflow:hidden; opacity:0; transition:opacity 1.4s ease}
#tagfenster.da{opacity:1}

/* ---------- das Fenster. Rechts angeschnitten: die Mitte liegt bei
   96 % der Breite, also haengt die halbe Scheibe aus dem Bild
   (game.js, TAGFENSTER_ORT). ---------- */
.tf-fenster{position:absolute; transform:translate(-50%,-50%)}
/* die Scheibe: das Hellste im Bild, und trotzdem leise */
.tf-scheibe{position:absolute; inset:0;
  /* deutlich Weiss beigemischt: --orange allein wird bei dieser
     Deckkraft auf dem dunklen Grund schokoladenbraun, und eine
     Fensterscheibe, die dunkler wirkt als das Licht, das aus ihr
     faellt, dreht die ganze Szene um. */
  background:linear-gradient(168deg,
      color-mix(in srgb, var(--tag-farbe), #fff 52%) 0%,
      color-mix(in srgb, var(--tag-farbe), #fff 22%) 56%,
      var(--tag-farbe) 100%);
  opacity:calc(var(--tf-licht, 1) * .30);
  filter:blur(1.5px);
}
/* das Sprossenkreuz: es ist kein Strich, es ist das Fehlen von Licht.
   Duenn: fette Sprossen ziehen den Blick, und der gehoert hier den
   Dingen (Laura: "fokus der szene ist wo anders").

   VIER GLEICHE FELDER (Laura, 26.08.26: "die 4 fensterteile muessen
   schon exakt gleich gross sein"). Das Kreuz sass vorher aus der
   Mitte, quer bei 47 und hoch bei 43,5 Prozent; am Nachmittagsfenster
   fiel das nie auf, weil davon nur ein Ausschnitt im Bild liegt, am
   frei haengenden Morgenfenster sofort. Beide Sprossen stehen jetzt
   mittig, und weil eine Sprosse selbst Dicke hat, faengt sie um die
   halbe Dicke VOR der Mitte an: 50 minus die Haelfte. Wer die Dicke
   aendert, rechnet den Anfang mit. */
.tf-sprosse{position:absolute; background:var(--grund); opacity:.88}
.tf-quer{left:0; right:0; top:48.8%; height:2.4%}
.tf-hoch{top:0; bottom:0; left:49.15%; width:1.7%}
/* der Rahmen, in der Strichsprache des Spiels, aber weit zurueckgenommen:
   er soll das Fenster erklaeren, nicht es umranden */
.tf-rahmen{position:absolute; inset:0;
  border:1.4px solid color-mix(in srgb, var(--tinte), transparent 74%);
  border-right:0;
}

/* ---------- der Kegel. Die Form kommt als clip-path aus game.js und
   wandert mit den sechs Staenden; der Verlauf laeuft entlang seiner
   Achse, am Fenster hell, am Ende aus. Der Blur sitzt auf der HUELLE,
   nicht auf dem geclippten Keil: clip-path wuerde eine unscharfe Kante
   sonst wieder hart abschneiden. ---------- */
.tf-kegel{position:absolute; inset:0; filter:blur(var(--tf-weich, 10px))}
.tf-keil{position:absolute; inset:0;
  /* ER DARF NICHT VORHER AUFHOEREN (Laura, 25.08.26: "der lichtkegel
     nicht ganz realistisch, der hoert sowohl unten als auch oben zu
     frueh auf"). Ein Kegel, der auf halbem Weg verschwindet, sieht aus
     wie ein Fleck; er muss aus dem Bild laufen. Der Verlauf traegt
     darum fast ueber die ganze Achse und geht erst ganz am Ende aus,
     und die Laengen in game.js reichen weit ueber die Buehne hinaus. */
  background:linear-gradient(var(--tf-achse, 206deg),
      color-mix(in srgb, var(--tag-farbe), #fff 22%) 0%,
      var(--tag-farbe) 22%,
      color-mix(in srgb, var(--tag-farbe), transparent 38%) 62%,
      color-mix(in srgb, var(--tag-farbe), transparent 74%) 88%,
      transparent 100%);
  /* mal --handylicht: am Finger das 2,1-fache (siehe den Block
     "WIE STARK DAS LICHT AM HANDY IST" ganz oben) */
  opacity:calc(var(--tf-licht, 1) * .10 * var(--handylicht, 1));
  transition:clip-path 3.6s cubic-bezier(.4,0,.3,1);
}

/* ---------- die fuenf Punkte. Sie tanzen im Kegel und werden von
   derselben Form beschnitten. Nicht unscharf: was tanzt, muss scharf
   sein, sonst ist es Nebel. ---------- */
.tf-tanz{position:absolute; inset:0;
  transition:clip-path 3.6s cubic-bezier(.4,0,.3,1)}
.tf-korn{
  position:absolute; border-radius:50%;
  background:color-mix(in srgb, var(--tag-farbe), #fff 55%);
  box-shadow:0 0 calc(3px * var(--scale, 1)) rgba(255,240,215,.5);
  animation:tagStaub var(--kdur, 18s) ease-in-out var(--kdelay, 0s) infinite;
  will-change:transform;
}
/* sie steigen langsam und sacken zurueck, wie Staub in einem Zimmer,
   in dem sich jemand bewegt hat */
@keyframes tagStaub{
  0%,100%{transform:translate(0,0)}
  50%    {transform:translate(var(--kx,0), var(--ky,-8px))}
}

/* ---------- DIE DINGE WERDEN WARM (Lauras Satz vom 25.08.26: "fuer den
   Moment, in dem es drin ist, ist sein Strich warm statt weiss").
   --imlicht schreibt der Ticker in game.js, 0 bis 1, weich ueber die
   Kegelkante.

   Drei Regeln, weil dingSVG die Farbe ans <svg> haengt, einzelne
   Ikonen eigene stroke-Attribute mitbringen und die Masken-Ikonen
   (der Seestern) ueberhaupt kein stroke haben, sondern eine Flaeche.

   Die drei Ausnahmen bei fill muessen bleiben: #fff und #000 sind die
   Maske selbst (faerbt man sie, verschwindet das Ding), und var(...)
   ist die Verdeckungsfarbe, mit der die Monstera ihre Ueberlappungen
   zumalt. Sie ist kein Bild, sie ist ein Loch.

   Kennt ein Browser color-mix nicht, faellt die Deklaration weg und es
   bleibt beim Attribut, also bei der weissen Tinte. ---------- */
.flieger{--imlicht:0}
.flieger svg{
  stroke:color-mix(in srgb, var(--tinte), var(--tag-farbe) calc(var(--imlicht) * 72%));
  transition:transform .22s ease, stroke .25s linear;
}
.flieger svg [stroke]:not([stroke="none"]){
  stroke:color-mix(in srgb, var(--tinte), var(--tag-farbe) calc(var(--imlicht) * 72%));
}
.flieger svg [fill]:not([fill="none"]):not([fill="#fff"]):not([fill="#000"]):not([fill^="var"]){
  fill:color-mix(in srgb, var(--tinte), var(--tag-farbe) calc(var(--imlicht) * 72%));
  transition:fill .25s linear;
}

@media (prefers-reduced-motion: reduce){
  #tagfenster{transition:opacity .3s ease}
  .tf-keil, .tf-tanz{transition:none}
  .tf-korn{animation:none}
}

/* =====================================================================
   DAS FENSTER AM MORGEN (Laura, 26.08.26). Warum es dasselbe Fenster
   ist, wie die Wolken gerechnet werden und was noch fehlt, steht in
   game.js (Block "DAS FENSTER AM MORGEN"); hier steht nur, wie es
   aussieht.

   Kasten, Rahmen und Sprossenkreuz sind DIESELBEN Klassen wie beim
   Nachmittag (.tf-*): sie kommen aus fensterKoerper(), es gibt sie
   nur einmal. Hier stehen genau die drei Unterschiede: die Seite, an
   der das Fenster aus dem Bild laeuft, der Himmel hinter der Scheibe
   und die Wolken.

   DER HIMMEL HAT KEINEN WEICHZEICHNER, anders als die Lichtflaeche
   des Nachmittags. Der war dort noetig, weil die Scheibe ein Schein
   ist und ein Schein keine Kante hat. Hier ist sie ein Ausblick, und
   ein Ausblick hat eine: die des Rahmens. Weich sind nur die Wolken,
   und ihr Weichzeichner sitzt auf ihnen selbst und nicht auf der
   Scheibe. Sonst rechnete der Browser zwei Minuten lang bei jedem
   Bild den ganzen Himmel neu unscharf.
   ===================================================================== */
#morgenfenster{position:absolute; inset:0; z-index:0; pointer-events:none;
  overflow:hidden; opacity:0; transition:opacity 1.4s ease;
  /* DIE HIMMELSFARBEN stehen hier und nicht bei den vier Grundfarben:
     sie sind kein Akzent, sondern ein Bild, und ausser diesem Fenster
     braucht sie niemand. Sobald der Morgen Licht in den Raum wirft,
     ziehen sie nach :root um, so wie --tag-hell es vorgemacht hat.
     Oben tiefer, unten heller: so steht ein Himmel am Morgen. */
  --himmel-oben:#5f9fd0;
  --himmel-mitte:#84bade;
  --himmel-unten:#b7d9ec;
  /* DIE FARBE DES MORGENLICHTS. Sie ist blasser als das --tag-hell
     des Nachmittags (#ffd49a) und mischt nie --orange dazu: um acht
     ist die Sonne warm, aber noch lange nicht bernsteinfarben, und
     ein Teil dessen, was durch dieses Fenster faellt, ist Himmel und
     kein Sonnenstrahl. Ganz ohne Saettigung geht es trotzdem nicht:
     bei den Deckkraeften, die ein dunkles Spiel vertraegt, wird jedes
     reine Weiss zu Grau. */
  --morgen-strahl:#ffe2b8;
}
#morgenfenster.da{opacity:1}

/* DIE ANDERE SEITE. Beim Nachmittagsfenster liegt die rechte Haelfte
   draussen, hier ein schmaler Streifen der linken. Also faellt der
   Rahmenstrich links weg statt rechts.

   Die hohe Sprosse steht hier nicht mehr: seit die vier Felder gleich
   gross sind, sitzt sie mittig, und die Mitte hat keine Seite, die
   man spiegeln koennte. */
#morgenfenster .tf-rahmen{border-left:0;
  border-right:1.4px solid color-mix(in srgb, var(--tinte), transparent 74%)}

/* die Scheibe. Sie schneidet ab: keine Wolke haengt neben dem Fenster
   im Zimmer. --mf-licht ist der eine Regler, falls der Morgen Laura
   zu hell wird. */
.mf-scheibe{position:absolute; inset:0; overflow:hidden;
  background:linear-gradient(177deg,
      var(--himmel-oben) 0%, var(--himmel-mitte) 54%, var(--himmel-unten) 100%);
  opacity:calc(var(--mf-licht, 1) * .9);
}

/* ---------- das Licht im Raum. Die Form kommt als clip-path aus
   game.js (Block "DAS LICHT IM RAUM"), der Verlauf laeuft entlang
   seiner Achse: am Fenster hell, am Ende aus. Der Blur sitzt auf der
   HUELLE und nicht auf dem geschnittenen Keil, sonst schneidet der
   clip-path die weiche Kante wieder hart ab. Dieselbe Bauweise wie
   am Nachmittag.

   DER LEERE SCHNITT IST DER AUSGANGSWERT und keine Spielerei: ohne
   ihn waere ein Kegel, dessen Mass beim Aufbau noch fehlt (verdeckt
   bootender Tab), eine Lichtflaeche ueber dem ganzen Schirm.

   GANZ DEZENT (Lauras Wort vom 26.08.26). .075 liegt noch unter den
   .10 des Nachmittags. Wer hier heller dreht, macht aus einem Morgen
   einen Scheinwerfer. ---------- */
.mf-kegel{position:absolute; inset:0; filter:blur(var(--mf-weich, 10px))}
.mf-keil{position:absolute; inset:0;
  clip-path:polygon(0 0, 0 0, 0 0, 0 0);
  background:linear-gradient(var(--mf-achse, 116deg),
      color-mix(in srgb, var(--morgen-strahl), #fff 26%) 0%,
      var(--morgen-strahl) 20%,
      color-mix(in srgb, var(--morgen-strahl), transparent 40%) 58%,
      color-mix(in srgb, var(--morgen-strahl), transparent 76%) 86%,
      transparent 100%);
  /* mal --handylicht, wie am Nachmittag: .075 ist der Wert fuer den
     Rechner, am Finger steht das 2,1-fache davon */
  opacity:calc(var(--mf-licht, 1) * .075 * var(--handylicht, 1));
}

/* die Bahn einer Wolke: so breit wie die Scheibe, einmal ganz durch,
   von links nach rechts, hinter dem Rahmen hervor und hinter ihm
   wieder weg. Bewegt wird nur transform. */
.mf-bahn{position:absolute; inset:0; will-change:transform;
  animation:mfZiehen var(--wdur, 120s) linear var(--wstart, 0s) infinite}
@keyframes mfZiehen{
  from{transform:translateX(-100%)}
  to  {transform:translateX(100%)}
}

/* die Wolke: vier weiche Ballen, die sich ueberlappen. Kein Strich:
   eine Wolke ist keine Zeichnung, sie ist Licht, wie der Kegel des
   Nachmittags. */
/* Jeder Ballen hat einen KERN und erst dann den Saum (der mittlere
   Halt bei knapp der Haelfte). Ohne ihn faellt ein radialer Verlauf
   vom ersten Pixel an ab, und die Wolke ist nur noch ein Hauch, den
   man auf dem Handy nicht mehr findet. */
.mf-wolke{position:absolute; left:0;
  background:
    radial-gradient(closest-side, #fff 0%, rgba(255,255,255,.94) 44%, rgba(255,255,255,0) 100%)  4% 64% / 46% 62% no-repeat,
    radial-gradient(closest-side, #fff 0%, rgba(255,255,255,.97) 48%, rgba(255,255,255,0) 100%) 40% 26% / 50% 86% no-repeat,
    radial-gradient(closest-side, #fff 0%, rgba(255,255,255,.92) 44%, rgba(255,255,255,0) 100%) 76% 58% / 44% 68% no-repeat,
    radial-gradient(closest-side, #fff 0%, rgba(255,255,255,.88) 50%, rgba(255,255,255,0) 100%) 50% 84% / 90% 48% no-repeat;
  opacity:var(--wdeck, .85);
  filter:blur(2.4px);
}

/* Wer keine Bewegung will, bekommt trotzdem einen Himmel: die Wolken
   stehen dann still, jede an ihrer Stelle (--wruhe aus game.js). Die
   Klasse setzt game.js, die Media Query faengt den Fall, dass jemand
   die Einstellung erst waehrend des Spiels umlegt. */
#morgenfenster.still .mf-bahn{animation:none; transform:translateX(var(--wruhe, 0%))}
@media (prefers-reduced-motion: reduce){
  #morgenfenster{transition:opacity .3s ease}
  .mf-bahn{animation:none; transform:translateX(var(--wruhe, 0%))}
}

/* ---------- der Regler (?licht=regler). Werkbank, kein Spiel:
   Systemschrift, keine Grammatik-Farbe, liegt ueber allem ausser der
   Testleiste (900). ---------- */
#lichtregler{
  position:fixed; z-index:880; right:8px; bottom:8px; width:min(230px, 62vw);
  padding:9px 11px 11px; border-radius:6px;
  background:rgba(10,10,10,.92); border:1px solid #333;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:10px; letter-spacing:.1em; color:#8a8a8a;
}
#lichtregler.klein{width:auto}
#lichtregler.klein > *:not(.lr-kopf):not(#lr-zu){display:none}
#lichtregler .lr-kopf{margin-bottom:7px; color:#c8c8c8; text-transform:uppercase}
#lichtregler .lr-zeile{display:flex; align-items:center; gap:7px; margin-top:5px}
#lichtregler .lr-zeile span{flex:0 0 62px}
#lichtregler .lr-zeile input{flex:1 1 auto; min-width:0; accent-color:#8a8a8a}
#lichtregler .lr-zeile b{flex:0 0 40px; text-align:right; font-weight:400; color:#c8c8c8}
#lichtregler #lr-zu{margin-top:8px; width:100%; padding:5px; font:inherit; letter-spacing:inherit;
  background:#131313; border:1px solid #2a2a2a; border-radius:3px; color:#8a8a8a}

/* =====================================================================
   DER FUNKENWIRBEL, wenn die Fabi-Kiste aufgeht (Laura, 25.08.26).
   Die Bahn und die Begruendung stehen in game.js (Block "DER
   FUNKENWIRBEL"), hier steht nur, wie ein Funke aussieht.

   Der Schirm liegt auf 95: ueber der Szene (die Schirme der Grammatik
   stehen auf 90), unter dem Handy-Overlay (400) und dem Blitz (800).
   Er schluckt die Klicks, damit im Dunkeln nichts angefasst wird, was
   man nicht sieht.
   ===================================================================== */
#wirbelschirm{
  position:fixed; inset:0; z-index:95; overflow:hidden;
  background:#000; opacity:0;
  /* das Schwarz kommt schneller, als es geht: hereinschneiden, sanft
     wieder aufmachen */
  transition:opacity .76s ease;
}
#wirbelschirm.da{opacity:1; transition:opacity .46s ease}

.wfunke{position:absolute; left:0; top:0; will-change:transform}
/* WALBLAU (Laura, 25.08.26: "mach die punkte walblau"). Vorher war der
   Kern fast weiss und nur der Hof trug die Farbe; im Bild las sich das
   als weisser Funke mit blauem Rand. Jetzt ist der Punkt selbst die
   Farbe des Wals und der Traumglaeser, und die Kiste, die hier
   aufgeht, ist Fabis. */
.wfunke > i{
  position:absolute; inset:0; border-radius:50%;
  background:var(--walblau);
  box-shadow:0 0 calc(5px * var(--scale, 1)) calc(1px * var(--scale, 1)) rgba(4,173,191,.95),
             0 0 calc(15px * var(--scale, 1)) calc(3px * var(--scale, 1)) rgba(4,173,191,.42);
  opacity:var(--wglanz, .8);
  animation:wglitzer var(--wdur, 1.1s) ease-in-out var(--wdelay, 0s) infinite;
}
/* DIE WENIGEN WEISSEN (Laura, 25.08.26: "mische gern noch ein paar
   wenige weisse funken rein"). Sie sind der Kontrapunkt: kaltes Weiss
   mit einem letzten Hauch Blau im Hof, damit sie zum Schwarm gehoeren
   und trotzdem herausstechen. Wenige, sonst kippt die Farbe der Szene. */
.wfunke.wweiss > i{
  background:#f4feff;
  box-shadow:0 0 calc(5px * var(--scale, 1)) calc(1px * var(--scale, 1)) rgba(240,253,255,.95),
             0 0 calc(16px * var(--scale, 1)) calc(3px * var(--scale, 1)) rgba(150,225,240,.4);
}

/* GLITZERIGER (Laura, ebd.). Ein Sinus zwischen hell und halbhell ist
   ein Atmen, kein Glitzern. Ein Glitzern hat Spitzen: fast aus, kurz
   voll da, sofort wieder weg, und das zweimal je Runde in
   unterschiedlicher Staerke.

   Die Groesse geht mit (transform). Das darf sie hier, und nur hier:
   die Bahn laeuft auf dem AEUSSEREN Element, der Kern ist frei. Auf
   demselben Element wuerde die eine Animation die andere ausknipsen. */
@keyframes wglitzer{
  0%,100%{opacity:calc(var(--wglanz, .8) * .12); transform:scale(.6)}
  9%     {opacity:var(--wglanz, .8);             transform:scale(1.42)}
  18%    {opacity:calc(var(--wglanz, .8) * .2);  transform:scale(.74)}
  47%    {opacity:calc(var(--wglanz, .8) * .08); transform:scale(.58)}
  56%    {opacity:calc(var(--wglanz, .8) * .9);  transform:scale(1.24)}
  66%    {opacity:calc(var(--wglanz, .8) * .18); transform:scale(.7)}
}
@media (prefers-reduced-motion: reduce){
  .wfunke > i{animation:none}
}



/* DANEBEN STATT HINEIN (Laura, 25.08.26): die Monstera passt in keine
   Kiste, sie wird neben die gewaehlte gestellt. Am 375er Schirm
   nachgemessen bleiben aussen 15 px Rand und zwischen den Kisten
   23 px; fuer eine Pflanze reicht beides nicht. Sie steht darum an der
   INNENkante und VOR der Kiste, ueberlappt sie um ein gutes Stueck und
   ragt nur ein paar Bildpunkte in die Luecke. Ganz sichtbar ist sie
   trotzdem, weil sie ueber Kiste und Peeks liegt. Unten buendig mit dem
   Kistenboden: beide stehen auf derselben Linie. */
.daneben{position:absolute;bottom:0;z-index:4;opacity:0;
  transition:opacity .35s ease}
.daneben.da{opacity:1}
.ziel-mit .daneben{left:100%;margin-left:-58px}
.ziel-schenk .daneben{right:100%;margin-right:-58px}

/* das Ausgraben: die grosse Kiste und das Grabungsfeld liegen mittig
   auf der Buehne (in fine wohnten sie im Feed; Masse und Innenleben
   kommen aus geraet.css) */
.f2y-kgross{position:absolute;left:50%;top:14px;transform:translateX(-50%);z-index:6}

/* der kleine stehende Schuhkarton im Stapel: fines Basiskiste ist fuer
   ihr Rollenband gerechnet (452 px breit) und liess den Sticker neben
   der Zeichnung stehen (Lauras Befund 24.08.26). Hier traegt der
   Flieger ein eigenes Mass im selben Seitenverhaeltnis. Aufschrift
   und Sticker stecken seit 25.08.26 in Lauras Zeichnung selbst
   (steuerkiste in geraet.js), darum stylen hier nur noch Box und
   Klebeband. */
#buehne .flieger #kistenbox{width:325px;height:232.5px}
#buehne .flieger #kistenbox .kartonface{gap:.06rem}
#buehne .flieger #kband{height:24px;font-size:11px}

/* der GROSSE Karton der Grabung: fines Handy-Regeln fuer die kleine
   Stapelkiste (schmales Band, tiefe Flaeche) griffen auch hier und
   machten das Klebeband schmal (Lauras Befund 24.08.26). Eigenes
   Mass fuer die grosse Buehne: */
#buehne .f2y-kgross #kband{top:36%;height:34px;font-size:13px}
#buehne .kausgrab{position:absolute;left:50%;top:2px;transform:translateX(-50%);
  width:min(374px, 96%);z-index:6}

/* die Grabung passt sich der Buehne an: Reihe zwei der Faecher und
   die ganze Namenszeile hingen unter der Buehnenkante und wurden
   abgeschnitten (Lauras Befund 24.08.26). fines Kiste hat ein
   festes Mass; hier nimmt der Halter die volle Buehne, die Kiste
   gibt als einziges Flex-Kind nach, alles Feste (Faecher-Reihen,
   Namenszeile) behaelt seine Hoehe. */
/* MITTIG, WEIL DIE KISTE JETZT EINEN DECKEL HAT: sie waechst nicht
   mehr in jede Hoehe hinein, also bleibt auf langen Schirmen Platz
   uebrig. Der geht zu gleichen Teilen ueber und unter die Grabung,
   statt als Loch zwischen Faechern und Daumenzeile zu stehen. */
#buehne .kausgrab{height:calc(100% - 4px);justify-content:center}
#buehne .kausgrab .kzeile,
#buehne .kausgrab .kablage,
#buehne .kausgrab .knamenzeile{flex:0 0 auto}

/* DIE KISTE BEHAELT IHRE FORM (Lauras Befund 27.08.26: "die kiste ist
   ploetzlich komisch gestaucht").

   WAS SIE FLACH GEZOGEN HAT: die Kiste war das einzige nachgebende
   Kind der Spalte, und ihre Zeichnung haengt an preserveAspectRatio=
   "none" (game.js, .kwand) -- sie nimmt also JEDE Hoehe an, die
   uebrig bleibt, und zieht das Bild darauf. Auf einem kurzen Schirm
   blieben von 319 Bildpunkten Hoehe noch 120: das Seitenverhaeltnis
   fiel von 0,71 auf 0,35, und die Dinge darin (feste Bildpunkte)
   ragten oben und unten aus dem Karton heraus.

   JETZT GIBT SIE IN BEIDE RICHTUNGEN NACH. aspect-ratio haelt 340:240
   fest, die Hoehe kommt weiter aus dem Flex-Rest, die Breite rechnet
   sich daraus. Beide Deckel (max-height/max-width) sind DASSELBE Mass
   in zwei Richtungen gerechnet, darum kann keiner den anderen
   schief ziehen: 92vw ist die alte Breitengrenze, 240px * --scale die
   alte Hoehe. Ist der Schirm kurz, wird die Kiste kleiner -- nicht
   flacher.

   DIE DINGE SKALIEREN MIT (cqh): die Kiste ist ihr eigener Container,
   44 Prozent ihrer Hoehe ist genau das alte Mass (106px * 1.33 von
   319), 33 Prozent das des Briefs. Wo cq-Einheiten fehlen, faellt die
   Regel weiter unten (feste Bildpunkte) wieder ein. */
#buehne .kausgrab .kbox{flex:1 1 auto;min-height:120px;height:auto;width:auto;
  aspect-ratio:340 / 240;
  max-height:min(calc(240px * var(--scale)), calc(92vw * 24 / 34));
  max-width:min(92vw, calc(340px * var(--scale)));
  container-type:size}
#buehne .kausgrab .kinnen .kding .objektbild{height:44cqh !important;width:auto !important}
#buehne .kausgrab .kinnen .kdbrief .objektbild{height:33cqh !important;width:auto !important}

/* KURZE SCHIRME (etwa das 667er-iPhone): der Kopfstreifen (--kopf)
   nimmt der Buehne oben 60px, damit rutschte die zweite Faecherreihe
   unter die Buehnenkante (nachgemessen bei 375x667: Reihe endete bei
   384, Kante liegt bei 349). Faecher und Kiste geben flacher nach,
   beide Reihen bleiben im Bild; lange Schirme bleiben unberuehrt. */
@media (max-height: 700px){
  #buehne .kausgrab{gap:.2rem}
  /* die Kiste darf hier tiefer fallen; die Form haelt sie trotzdem
     (aspect-ratio oben), sie wird nur kleiner */
  #buehne .kausgrab .kbox{min-height:88px}
  #buehne .kslot, #buehne .kauffalt{height:54px}
  #buehne .kslot .objektbild{max-height:42px}
}

/* die gestrichelten Faecher der Fundleiste: doppelte Strichstaerke
   und helleres Grau (Laura, 24.08.26: "etwa zu fein", dann "muessen
   noch sichtbarer"; der Auffalt-Platz zieht in game.js mit, sein
   bereit-Zustand steigt deshalb auf #999, sonst ginge die Einladung
   im Grundton unter) */
#buehne .kslot{border-width:2px;border-color:#6c6c6c}
#buehne .kauffalt.bereit .kauffalt-bild rect{stroke:#999}

/* DER BRIEF (Stand 25.08.26). Er ist ein Blatt, das man liest: helles
   Papier, dunkle Tinte, gescrollt mit dem Daumen, ohne Falz-Streifen,
   ohne Klick je Absatz und ohne weiche Kanten. Ihre Stimme spricht im
   offenen Brief NUR ueber die Marker, und die oeffnen den Wortzettel
   (seit 28.08.26; davor eine Zeile im Fuss).
   Lesefassung in der Leseschrift, keine Handschrift im Brieftext
   (Laura, 24.08.26: "das ist so viel Text, da liest doch erst recht
   keiner");
   Caveat behaelt das P.S.
   WAS HIER SCHON WAR und wieder ging, damit es niemand zurueckbaut:
   die Ziehharmonika mit Falz-Streifen und Kanten-Stapel (raus 25.08.),
   das dunkle Blatt samt Moewe-Markern (raus 25.08., der Marker traegt
   jetzt Walblau), das weiche Aufloesen an den Schnittkanten (raus
   25.08.) und das Icon BRIEF FAST GEFALTET zwischen offen und zu
   (raus 25.08.). Geblieben ist die Luft nach oben. */
.f2y-brief{position:absolute;left:50%;top:2px;transform:translateX(-50%);
  width:min(374px, 96%);height:calc(100% - 4px);z-index:6;
  display:flex;flex-direction:column;overflow-y:auto;
  padding:clamp(18px, 5.5svh, 46px) 0 14px;
  /* KEINE Maske an den Schnittkanten (Laura, 25.08.26: "ich moechte
     nicht, dass der Brief nach oben oder unten mit so einer Vignette
     auslaeuft"). Das helle Papier schneidet jetzt hart ab, und genau
     das sagt, dass es weitergeht. */
  scrollbar-width:none}
.f2y-brief::-webkit-scrollbar{display:none}

/* DAS HELLE BLATT (Laura, 25.08.26: "man koennte ihn ja jetzt auch
   weiss machen, also nicht ganz weiss, sondern die helle Farbe, die wir
   im Spiel nutzen, auch fuer Schrift, und quasi umkehren"). Papier ist
   --tinte, Tinte ist --tinte-dunkel: derselbe Zweiklang wie sonst im
   Spiel, nur vertauscht. Damit ist der Brief endlich EIN Gegenstand,
   denn .brieffalt und .psbrief waren immer schon hell.
   Die Fassung vom 24.08. (dunkles Blatt, Moewenblau darauf) ist damit
   abgeloest; das Moewenblau war der Grund fuer das dunkle Papier und
   ist beim Marker durch Walblau ersetzt. */
.briefblatt{position:relative;flex:0 0 auto;width:min(360px, 96%);margin:0 auto;
  padding:20px 22px 26px;border-radius:3px;
  background:var(--tinte);
  box-shadow:0 18px 40px rgba(0,0,0,.62), 0 3px 9px rgba(0,0,0,.45),
    inset 0 0 0 1px rgba(0,0,0,.07);
  animation:blatt-auf .7s cubic-bezier(.3,.8,.3,1) both}
@keyframes blatt-auf{from{opacity:0;transform:perspective(760px) rotateX(-34deg) translateY(12px)}}
/* die Falze bei den Dritteln, an denselben Lagen wie auf dem
   gefalteten Brief: hier faellt der Knick ins Dunkle und faengt oben
   einen Hauch Licht */
.briefblatt::before,.briefblatt::after{content:'';position:absolute;top:0;bottom:0;
  width:1.5px;pointer-events:none;
  background:linear-gradient(90deg, rgba(0,0,0,.12), rgba(255,255,255,.75))}
.briefblatt::before{left:33.3%}
.briefblatt::after{left:66.6%}

/* der Brieftext: die fine-Harmonika (geraet.css) in der Schrift-
   Grammatik dieses Spiels. LESEFASSUNG in der Leseschrift (Laura,
   24.08.26: nicht Fabis Handschrift, "das ist so viel text da liest erst
   recht keiner"); seine Hand behaelt nur das kurze P.S. (.psbrief).
   Die Streichungen erben fines dunkle Fassung aus geraet.css. */
/* GESCROLLT, NICHT GEFALZT (Laura, 25.08.26): der Brieftext ist EIN
   Bogen. .harmonika ist er nicht mehr, deshalb bringt .brieftext seine
   Spalte selbst mit; die Falz-Regeln (.streifen, .weggelegt) sind
   ersatzlos weg, mit ihnen die max-height-Bewegung und das
   overflow:hidden, das nur den Falz beschnitten hat. */
.f2y-brief .brieftext{display:flex;flex-direction:column;gap:.9rem}
.f2y-brief .absatz{border-left:0;padding-left:0;color:var(--tinte-dunkel);
  font-family:var(--s-lesen);
  font-size:var(--hanken);line-height:var(--zeile);
  transform-origin:50% 0;
  animation:abs-auf .62s cubic-bezier(.3,.8,.3,1) .08s both}
/* seine Streichungen brauchen auf hellem Papier ihre eigene Tinte:
   das Grau aus der dunklen Fassung verschwindet hier fast */
.f2y-brief .absatz s{color:rgba(18,22,26,.4)}
@keyframes abs-auf{from{opacity:0;transform:perspective(760px) rotateX(-44deg)}}

/* DER TEXTMARKER: ein GEZOGENER STRICH, kein Unterstrich (Laura,
   25.08.26: "ich find auch, dass Moewenblau als Unterstreichung noch
   nicht gut ist, arbeite da mal mit dem Walblau. Und vielleicht gibt es
   einen schoeneren Weg als unterstreichen, der mehr zur Optik des
   Spiels passt"). Also dieselbe Hand wie beim Klecks: eine Flaeche mit
   unruhigen Kanten, quer ueber die Stelle gezogen, in Walblau.
   Was auf dem dunklen Blatt nicht ging, geht auf hellem Papier: eine
   Flaeche UNTER dunkler Tinte kehrt Figur und Grund nicht um, sie
   liegt darunter wie echte Markerfarbe.
   Nebenbei sagt der Strich etwas ueber sie: diesen Brief hat jemand
   mehrfach gelesen (l6) und dabei Stellen angestrichen.
   Das Atmen des alten Unterstrichs ist raus, der Strich ist von selbst
   laut genug. Antippen legt ihren Gedanken auf die Daumenzeile
   (game.js verkabelt die mark[data-m]), danach wird er still.
   WIE er gebaut ist, steht seit dem 26.08.26 nicht mehr hier, sondern
   oben bei „Angestrichen": derselbe Strich traegt jetzt auch die zwei
   Wortknoepfe im Gruppenchat, und eine Form, die an zwei Orten steht,
   ist nach dem zweiten Umbau zwei Formen. Hier bleibt nur, was dem
   Brief gehoert: seine Farbe. */

/* das P.S.-Papier sitzt mittig; der Zettel insgesamt 15% groesser
   (Laura, 24.08.26), zoom skaliert Papier UND Schrift, --ding ist fines
   Geraetemass (geraet.css). Die Regel .f2y-brieffalt fuer den fast
   gefalteten Brief ist am 25.08.26 gestrichen: das Icon dazwischen gibt
   es nicht mehr, gefaltet wird der Brief selbst. */
.f2y-brief .psbrief{flex:0 0 auto;margin:auto;zoom:calc(var(--ding) * 1.15)}

/* ---------- der Kaltstart als Tutorial (Laura, 24.08.26) ---------- */
/* die Anleitungs-Karten (Bildschirm 1 der Grammatik) liegen UEBER dem
   Geraet: das Overlay steht auf 400, der Schirm der Grammatik auf 90 */
.schirm.ueberm-geraet{z-index:500}
/* die erste Karte traegt zwei Zeilen uebereinander: die Regie-Ansage
   und darunter den Satz (Laura, 24.08.26 nachts: "auf der gleichen
   seite"); mit einem Kind aendert column nichts an der Mitte */
.schirm.ueberm-geraet{flex-direction:column}
.schirm-kopf{margin-bottom:16px}
/* die Ueberblendung (Tutorial Ende): kommt und geht von selbst, ohne
   Klecks — sie wartet nicht. Die Zeile spricht Regie. */
.schirm.blende{opacity:0;transition:opacity .5s ease;pointer-events:none}
.schirm.blende.da{opacity:1}
.blende-zeile{font-family:var(--s-regie);font-size:var(--barlow);line-height:var(--zeile-barlow);
  letter-spacing:.14em;text-transform:uppercase;color:var(--regie)}
/* die Antwort-Wahl im Geraetefuss traegt die Kastenwahl der Grammatik
   ("die gewaehlte Antwort" ist Moewe, design.html); eigene Antworten
   stehen rechts wie eigene Blasen.
   ENG AM WORT (Laura, 25.08.26; design.html, Stueck 10): im Chat rueckt
   die gestrichelte Linie an den Text, weil der Platz dort dem Gespraech
   gehoert. Die Zahlen stehen in der Bibel, hier sind sie nachgezogen:
     Polster  .16em / .62em   war .36em / .9em
     Abstand   5 px           war 9
     Radius    8 px           war 11
     Zeile     1,35           war 1,45 (die Blase daneben: 1,4)
     Stapel    .12 / .25rem   war .45 / .5
   Das spart unter dem Chat ein Sechstel der Hoehe. Die Strichelung
   selbst bleibt 4,5/5,5 wie ueberall.
   rx MUSS mit: der Radius steht sonst zweimal da, einmal in CSS und
   einmal als Attribut am rect in game.js, und das Attribut malt den
   alten Bogen unter die neue Ecke. */
#handy-panel .wahlfeld{align-items:flex-end;gap:5px;padding:.12rem .8rem .25rem}
#handy-panel .wahl{line-height:1.35;font-size:.92rem;text-align:left;
  padding:.16em .62em;border-radius:8px}
#handy-panel .wahl .w-rand rect{rx:7.25px}

/* ---------- DAS HANDY, Variante A (Grammatik-Kopie aus design.html,
   24.08.26: "das Geraet ist ein Geraet"). Wortlaut der Regeln
   woertlich von dort; Homebildschirm und App-Raster sind noch nicht
   gebraucht und werden nachgezogen, wenn eine Szene sie ruft. ---------- */
.h-status{flex:0 0 auto;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  padding:9px 15px 4px;font-family:var(--werkzeug);font-size:11.5px;color:#c2c2c8}
.h-status .netz{display:flex;align-items:flex-end;gap:5px}
.h-status .balken{display:flex;align-items:flex-end;gap:1.5px}
.h-status .balken i{width:2.5px;background:#c2c2c8;border-radius:1px;display:block}
.h-status .balken i:nth-child(1){height:3.5px}
.h-status .balken i:nth-child(2){height:5.5px}
.h-status .balken i:nth-child(3){height:7.5px}
.h-status .balken i:nth-child(4){height:9.5px;opacity:.35}
.h-status .netz svg{width:12px;height:12px;display:block;color:#c2c2c8}
.h-status .zeit{justify-self:center;font-weight:600;letter-spacing:.01em}
.h-status .akku{justify-self:end;display:flex;align-items:center;gap:2px}
.h-status .akku .huelle{width:20px;height:10.5px;border:1.2px solid #c2c2c8;border-radius:3px;
  padding:1.4px;display:block}
.h-status .akku .fuell{display:block;height:100%;width:64%;background:#c2c2c8;border-radius:1px}
.h-status .akku .nase{width:1.6px;height:4px;background:#c2c2c8;border-radius:0 1px 1px 0;display:block}
/* WENN DIE ERINNERUNG ZERFAELLT, faellt die Statusleiste mit: sie
   kippt nach oben aus dem Bild. In fine war sie ein ::before am Panel
   (geraet.css, .panel.ostatusfall::before) und wurde deshalb hier nie
   angefasst, weil sie hier ein echtes Element ist. */
.h-status.ostatusfall{transition:transform .9s ease-in, opacity .9s ease-in}
.h-status.ostatusfall.faellt{transform:translateY(-46px) rotate(-4deg);opacity:0}

.h-kopf{flex:0 0 auto;padding:10px 16px 12px;display:flex;align-items:center;gap:10px}
/* Der Pfeil ist ein Quadrat mit zwei Kanten, um 45 Grad gedreht. Die
   ZEICHNUNG liegt im ::before, nicht am Element selbst: das Element
   traegt spaeter das Atmen des Rufs (ein Skalieren), und zwei
   Transformationen auf EINEM Element ueberschreiben sich — dieselbe
   Falle, die in design.html am Ruf steht. Weiter unten, beim Ruf,
   steht der Rest. */
.h-kopf .h-zurueck{position:relative;width:9px;height:9px;flex:0 0 auto}
.h-kopf .h-zurueck::before{content:'';position:absolute;inset:0;
  border-left:1.6px solid #9a9aa0;border-bottom:1.6px solid #9a9aa0;
  transform:rotate(45deg)}
.h-kopf .titel{font-family:var(--werkzeug);font-size:14px;font-weight:600;color:#e2e2e6}
.h-kopf.mit-bild{align-items:center;gap:9px;padding:8px 14px 10px}
.h-kopf.mit-bild .bild{flex:0 0 auto;width:32px;height:32px;border-radius:50%;background:#2b2b31;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--werkzeug);font-size:12px;color:#a6a6ac}
.h-kopf.mit-bild .wer{min-width:0;display:flex;flex-direction:column}
.h-kopf.mit-bild .wer .name,.h-kopf.mit-bild .wer .online{display:block}
.h-kopf.mit-bild .wer .name{font-family:var(--werkzeug);font-size:14px;font-weight:600;color:#e2e2e6;line-height:1.2}
.h-kopf.mit-bild .wer .online{font-family:var(--werkzeug);font-size:11px;color:#8c8c92;line-height:1.3}

.h-liste{flex:1;display:flex;flex-direction:column;overflow:hidden}
.h-zeile{display:flex;align-items:center;gap:11px;padding:9px 16px}
.h-zeile .bild{flex:0 0 auto;width:34px;height:34px;border-radius:50%;background:#2b2b31;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--werkzeug);font-size:12px;color:#a6a6ac}
.h-zeile .mitte{flex:1;min-width:0}
.h-zeile .name{font-family:var(--werkzeug);font-size:13px;color:#e2e2e6;font-weight:600}
.h-zeile .vor{font-family:var(--werkzeug);font-size:12px;color:#8c8c92;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.h-zeile .zeit{flex:0 0 auto;font-family:var(--werkzeug);font-size:10.5px;color:#75757b}
/* der Punkt fuer ungelesene Nachrichten ist seit dem 30.08.26
   moewenblau wie die ganze uebrige Bedienung (design.html) */
.h-zeile .neu{flex:0 0 auto;width:8px;height:8px;border-radius:50%;background:rgb(var(--klecks-rgb))}

.h-blase{max-width:78%;padding:.35em .8em;border-radius:14px;
  font-family:var(--werkzeug);font-size:13px;line-height:1.4;background:#25252a;color:#e2e2e6}
.h-blase.ich{align-self:flex-end;background:var(--moewe);color:var(--tinte-dunkel)}
/* UEBER JEDER BLASE steht, wann sie kam (design.html, woertlich;
   Umbau 25.08.26 auf Lauras Ansage, vorher hiess die Zeile .h-wer
   und trug im Zweierchat Absendernamen und ein "DU"):
     Gruppenchat   Name UND Uhrzeit (.wer)
     Zweierchat    NUR die Uhrzeit
   Bei den EIGENEN Nachrichten stehen in derselben Zeile die HAKEN. */
.h-ueber{font-family:var(--werkzeug);font-size:10px;color:#75757b;
  margin:3px 0 -3px 4px;display:flex;gap:6px;align-items:baseline}
.h-ueber.ich{align-self:flex-end;margin:3px 4px -3px 0}
.h-ueber .wer{color:#9a9aa0}
/* DIE HAKEN (design.html, woertlich): sie stehen in der Zeile UEBER
   der eigenen Blase, nicht in der Blase. Drei Zustaende, und der
   Unterschied ist im Spiel eine Information und keine Kosmetik:
     ein Haken           abgeschickt (.einer)
     zwei Haken          angekommen
     zwei in Moewenblau  gelesen (.gelesen)
   Moewenblau und nicht Butter: gelesen zu werden ist etwas, das die
   WELT tut, und kein Ort, an den der Daumen soll. */
.h-haken{display:inline-flex;align-items:center;color:#75757b}
.h-haken svg{width:15px;height:10px;display:block}
.h-haken.einer svg path:first-child{display:none}
.h-haken.gelesen{color:var(--moewe)}

.h-raster{flex:1;display:grid;grid-template-columns:repeat(4,1fr);
  gap:16px 10px;align-content:start;padding:20px 14px}
.h-app{display:flex;flex-direction:column;align-items:center;gap:5px}
.h-app .kachel{width:44px;height:44px;border-radius:12px;background:#25252a;
  display:flex;align-items:center;justify-content:center}
.h-app .kachel.wichtig{background:var(--moewe)}
.h-app .kachel svg{width:20px;height:20px;display:block}
.h-app span{font-family:var(--werkzeug);font-size:9.5px;color:#9a9aa0;text-align:center;line-height:1.2}

.h-fuss{flex:0 0 auto;display:flex;align-items:center;gap:9px;padding:8px 12px 14px}
.h-fuss .feld{flex:1;min-width:0;background:var(--grund);border-radius:17px;padding:7px 13px;
  font-family:var(--werkzeug);font-size:12.5px;color:var(--tinte)}
/* WAS IM FELD STEHT, IST HELL (Laura, 25.08.26; die Regel und ihre
   Begruendung stehen in design.html an derselben Stelle). Grau ist nur
   der Platzhalter, dunkel wird die Schrift erst auf dem Moewenblau der
   eigenen Blase. Im Spiel tippt game.js in einen <span class="otxt">
   neben den Cursor; der erbt die Feldfarbe und ist damit hell, ohne
   dass die Tippstelle etwas dazuschalten muss. */
.h-fuss .feld .oph{color:#75757b}
/* h-flieger, nicht .flieger: die Buehne vergibt .flieger schon an das
   fliegende Ding (position:absolute) — exakt die Namensfalle aus
   design.html; dort heisst der Sendenknopf im Muster noch .flieger.

   ZWEI ZUSTAENDE, wie in der Bibel — AM 30.08.26 UMGEDREHT (Laura:
   "der ist in Zukunft dunkler und wird moewenblau, wenn man ihn
   klicken kann"):
     .h-flieger          dunkel, mit gestricheltem Rand, der Flieger
                         darin nur halbe Kontur. Er ist da, er gehoert
                         zum Geraet, aber er ruft niemanden.
     .h-flieger.bereit   moewenblau, Rand weg, Flieger dunkel darauf.
                         Ein fertiger Satz steht im Feld und wartet.
   DER GESTRICHELTE RAND IST NOETIG, nicht huebsch: eine Scheibe bei .14
   auf der Mulde des Chatfusses ist kaum vom Grund zu unterscheiden
   (Lauras Befund am Bildschirmfoto). Gestrichelt heisst im ganzen Haus
   OFFEN/ERWARTEND, es ist derselbe Strich wie am Wahlkasten und
   verschwindet dort wie hier, sobald gehandelt werden kann. Es kommt
   also keine Form dazu, nur eine zweite Fundstelle.
   Das schaerft die Farbregel, wie design.html sie formuliert: die Farbe
   heisst nicht "da soll der Daumen hin", sondern "da soll er JETZT
   hin". Bei den drei Klecksen faellt beides zusammen, weil sie nur
   dann ueberhaupt im Bild stehen; der Sendenpfeil ist der erste Fall,
   wo es auseinandergeht.
   BUTTER KOMMT HIER NICHT MEHR VOR, an keinem der zwei Zustaende.

   DAMIT IST DIE ALTE AUSNAHME WEG. Bis zum 25.08.26 abends war er
   hier immer Butter — Laura hatte das zweimal so entschieden ("Nene
   das ist ok so im spiel", "Alles bleibt Butter"), pruef-folding.py
   fuehrte die Stelle unter AUSNAHMEN. In derselben Nacht hat sie es
   umgedreht: der gelbe Knopf lenkte ab, waehrend Fine selbst tippte
   und nichts zu senden war. styles.css folgt der Bibel jetzt wieder
   wortwoertlich, .bereit vergibt game.js (antwortSenden, Opener). */
.h-fuss .h-flieger{flex:0 0 auto;width:34px;height:34px;border-radius:50%;
  background-color:var(--senden-ruhe);color:var(--senden-ruhe-zeichen);
  background-image:var(--flieger-rand);background-size:100% 100%;
  transition:background-color .25s ease, color .25s ease;
  display:flex;align-items:center;justify-content:center;border:0;cursor:pointer}
.h-fuss .h-flieger.bereit{background-color:var(--moewe);color:var(--tinte-dunkel);
  background-image:none}
.h-fuss .h-flieger svg{width:16px;height:16px;display:block}

/* ---------- Szenen-Zusaetze zum Handy (nicht in design.html): der
   Kaltstart braucht ein scrollendes Log und Zustaende am Flieger.
   Uhrzeit-Zeile und Haken stehen oben bei den Grammatik-Kopien
   (.h-ueber, .h-haken). ---------- */
.h-log{flex:1;display:flex;flex-direction:column;gap:7px;padding:10px 14px 6px;
  overflow-y:auto;scrollbar-width:none}
/* die Erinnerung: die Nachricht zieht die Schaerfe vom App-Raster ab,
   und der alte Wortstrich-Verlauf klebt unten im Log wie ein Chat */
.h-raster{transition:filter .7s ease}
.h-raster.weich{filter:blur(2.5px)}
/* das Banner haengt jetzt am Panel und darf die Statuszeile nicht
   decken: es faehrt unter ihr ein */
#handy-panel > .obanner{top:34px}
.h-log > .oalt:first-child{margin-top:auto}
.h-log::-webkit-scrollbar{display:none}
.h-log .h-blase{flex:0 0 auto;align-self:flex-start}
.h-log .h-blase.ich{align-self:flex-end}
/* Fotos in h-Blasen: die fine-Regeln haengen an .nachricht und greifen
   hier nicht — dieselben Masse, nachgezogen. Das Lichtbild bleibt
   grau und klein (ein Anhang, kein Bild an der Wand). */
.h-blase .a-foto{margin-top:.5em;width:min(220px,100%)}
.h-blase .a-foto svg{width:100%;height:auto}
.h-blase .a-foto.a-fotoklein{width:110px;max-width:100%}
/* eine STEHENDE Zeichnung auf der grauen Karte (Quinns Kopf um die
   Ecke): schmaler gesetzt, sonst ist die Karte hoeher als breit und
   nimmt den halben Bildschirm. Woertlich fines Regel. */
.h-blase .a-fotogrund.hoch img{width:46%}
.h-blase .a-foto img.a-fotoecht{display:block;width:100%;height:auto;
  border-radius:10px;border:1px solid #3a3a3a;filter:grayscale(1)}
/* DIE REAKTIONEN UNTER EINER BLASE (26.08.26, aus fine
   uebernommen und auf die h-Blasen umgeschrieben). Sie sind ein
   eigenes Kind im Log und nicht Teil der Blase: eine Reaktion gehoert
   zu einer Nachricht, steht aber nicht in ihr. Der negative Abstand
   nach oben zieht sie an die Unterkante der Blase, ohne den Abstand
   zur naechsten zu vergroessern (das Log hat gap:7px). */
.h-log .h-reaktionen{flex:0 0 auto;align-self:flex-start;display:flex;gap:4px;
  margin:-4px 0 0 6px}
.h-log .h-reaktionen.ich{align-self:flex-end;margin:-4px 6px 0 0}
.h-reaktion{display:inline-flex;align-items:center;gap:3px;
  padding:1px 6px;border:1px solid #2e2e33;border-radius:999px;
  background:#101012;font-size:11px;line-height:1.55}
.h-reaktion i{font-style:normal;color:#8a8a8a;font-size:10px;
  font-variant-numeric:tabular-nums}

/* EIN ANTIPPBARES WORT IN EINER BLASE (Laura, 26.08.26, Svens
   Copepoden und Cladoceren). Es ist ein Knopf und soll trotzdem
   aussehen wie Text.
   HIER STEHT DAZU NICHTS MEHR: das Wort traegt seit Lauras Ja am
   26.08.26 den Textmarker in Fines Orange, und der steht oben bei
   „Angestrichen". Bis dahin hatte es einen gepunkteten Unterstrich in
   Moewenblau, also eine zweite Bauart fuer dieselbe Sache.
   .p-wort ist nur noch der Griff, an dem game.js die zwei Knoepfe
   wiederfindet. */

/* die zwei Haken in der Vorschauzeile der Uebersicht: kleiner als in
   der Blase, denn hier stehen sie in einer 12px-Zeile */
.h-zeile .vor .h-haken{margin-right:4px;vertical-align:-1px}
.h-zeile .vor .h-haken svg{width:13px;height:9px}

.h-liste.rollt{overflow-y:auto;scrollbar-width:none}
.h-liste.rollt::-webkit-scrollbar{display:none}
/* der Weiter-Punkt des Tutorials: unten am Bildschirmrand, UEBER dem
   Geraet (Overlay 400) — genau da, wo Karte 1 ihn angekuendigt hat.
   Seine Mitte sitzt auf --knopf-mitte wie jeder Weiter-Klecks (70 px
   seit dem 27.08.26, design.html; vorher bottom:8px, also Mitte 46):
   bottom = Mitte minus halbe Knopfhoehe (76/2), die Sicherheitszone
   kommt drunter.

   .handy-weiter ist derselbe Punkt ausserhalb des Tutorials (der
   Morgen danach, wo er aus dem Messenger fuehrt). Zwei Namen und eine
   Regel: eine Klasse namens tut- an einer Stelle, an der kein
   Tutorial laeuft, waere in zwei Wochen der falsche Hinweis. */
.tut-weiter,
.handy-weiter{position:fixed;left:0;right:0;z-index:450;
  bottom:calc(var(--knopf-mitte) - 38px + env(safe-area-inset-bottom,0px));
  display:flex;justify-content:center;pointer-events:none}
.tut-weiter .knopf-weiter,
.handy-weiter .knopf-weiter{pointer-events:auto;transition:opacity .25s ease}
.tut-weiter .knopf-weiter.still,
.handy-weiter .knopf-weiter.still{opacity:0;pointer-events:none}
/* Er liegt ueber dem Geraet (z-index 450) und damit auch ueber der
   Teilueberblendung IM Geraet. Solange die Frage steht, geht er weg:
   sonst stuenden zwei gelbe Rufe uebereinander, und einer davon
   klebte mitten auf dem roten Knopf. */
.tut-weiter.zu,
.handy-weiter.zu{opacity:0;pointer-events:none;transition:opacity .2s ease}
/* UND DER KNOPF DARIN AUCH (26.08.26, beim Bauen des Morgens
   aufgefallen). pointer-events:none am Halter nuetzt nichts, solange
   das Kind ausdruecklich pointer-events:auto traegt: der unsichtbare
   Klecks lag weiter ueber dem roten "Chat loeschen" und schluckte dort
   jeden Tipp. Das galt auch im Tutorial, wo derselbe Punkt fuer die
   Loeschfrage weggeht. */
.tut-weiter.zu .knopf-weiter,
.handy-weiter.zu .knopf-weiter{pointer-events:none}
/* der Zurueck-Pfeil ist 9px klein; die Klickflaeche ist es nicht */
.h-kopf .h-zurueck{position:relative;cursor:pointer}
.h-kopf .h-zurueck::after{content:'';position:absolute;inset:-16px}
/* still: er ist noch kein Ausgang. In Lenas Chat bleibt er das,
   solange nicht gelesen wurde (game.js, lenaChat) — ein Weg, der
   dasteht, bevor er gemeint ist, ist schlimmer als gar keiner. */
.h-kopf .h-zurueck.still{opacity:0;pointer-events:none;transition:opacity .35s ease}
/* ES RUFT (design.html, Abschnitt 5; Laura 25.08.26 nachts, statt des
   gelben Tipp-Kleckses, der bis dahin auf ihm klebte): der Pfeil
   bekommt den STUPS. Er wackelt kurz, als haette ihn jemand
   angestossen, und liegt dann wieder still; dazu das leise Atmen.
   Keine Farbe, keine Flaeche, kein Leuchten — er faerbt sich also
   ausdruecklich NICHT, auch nicht heller.

   ZWEI ELEMENTE, wie ueberall beim Ruf: das Atmen (ein Skalieren)
   sitzt auf dem Element, der Stups (ein Drehen) auf dem ::before mit
   der Zeichnung. Auf einem Element wuerde die zweite Animation die
   erste ueberschreiben.

   EIGENE KEYFRAMES, gleich aus zwei Gruenden:

   1  Das ::before steht schon auf rotate(45deg), sonst waere es kein
      Pfeil, sondern eine Ecke. Das gemeinsame ruf-stups faengt bei
      rotate(0) an und wuerde die 45 Grad wegdrehen. Alle Winkel hier
      sind also 45 plus/minus den Ausschlag.
   2  DIESER PFEIL IST NEUN PIXEL GROSS. Die Werte der Bibel (2,6 Grad
      Wackeln, 4,5 % Atmen) bewegen an einem Gegenstand auf der Buehne
      sichtbar etwas; an einem Pfeil von neun Pixeln sind 2,6 Grad
      keinen halben Pixel weit. Laura, 25.08.26 nachts: "der wackelt
      nicht doll genug und es waere auch gut, wenn der ein bisschen
      pulsiert." Der Pfeil bekommt darum kraeftigere Zahlen als der
      Ruf sonst — dieselbe Geste, nur so weit aufgedreht, dass sie an
      dieser Groesse ankommt. Die gemeinsamen ruf-atem/ruf-stups
      bleiben unangetastet, sie gehoeren dem Muelleimer, dem Zettel
      und den abgelegten Dingen.

   EIN TAKT VON SECHS SEKUNDEN, und beide Animationen sind gleich
   lang: nur so bleiben sie fuer immer im Gleichschritt. Im Takt
   stehen zwei ruhige Puls-und-Wackel-Paare, und am Ende — alle sechs
   Sekunden also — der GROSSE: ein deutlich weiterer Puls und ein
   doppelt so starkes Wackeln (Laura: "alle sechs Sekunden soll er
   auch noch mal groesser pulsieren und n bisschen staerker wackeln").
   Wer die Zeiten anfasst, muss sie in BEIDEN Keyframes anfassen,
   sonst wandert der grosse Wackler vom grossen Puls weg. Die Paare
   liegen bei 20/57 Prozent, der grosse Schlag bei 88. */
.h-kopf .h-zurueck.ruft{animation:ruf-atem-pfeil 6s ease-in-out infinite}
.h-kopf .h-zurueck.ruft::before{animation:ruf-stups-pfeil 6s ease-in-out infinite}
/* der Puls: zweimal ruhig (1,08), dann der grosse Atemzug (1,24) */
@keyframes ruf-atem-pfeil{
  0%,40%,74%,100%{transform:scale(1)}
  20%,57%{transform:scale(1.08)}
  88%{transform:scale(1.24)}}
/* das Wackeln, auf denselben Schlaegen: zweimal -7/+5/-2 Grad, beim
   grossen Schlag -14/+9/-3,5 */
@keyframes ruf-stups-pfeil{
  0%,14%,34%,48%,68%,80%,100%{transform:rotate(45deg)}
  18%{transform:rotate(38deg)}
  24%{transform:rotate(50deg)}
  29%{transform:rotate(43deg)}
  52%{transform:rotate(38deg)}
  58%{transform:rotate(50deg)}
  63%{transform:rotate(43deg)}
  85%{transform:rotate(31deg)}
  91%{transform:rotate(54deg)}
  96%{transform:rotate(41.5deg)}}
@media (prefers-reduced-motion: reduce){
  .h-kopf .h-zurueck.ruft,.h-kopf .h-zurueck.ruft::before{animation:none}
}
/* der Flieger wartet still, bis es etwas zu senden gibt; dann winkt er */
.h-fuss .h-flieger.still{opacity:.3;pointer-events:none}
.h-fuss .h-flieger.winkt{animation:flieger-winkt 1.7s ease-in-out infinite}
@keyframes flieger-winkt{0%,100%{transform:scale(1)}50%{transform:scale(1.14)}}
/* LENA LEUCHTET (Laura, 24.08.26: "der muss hell unterlegt sein
   vollständig und bisschen leuchten" — ausdruecklich NICHT die
   Gesten-Sprache): die ganze Zeile traegt eine helle Flaeche und
   atmet einen leisen Schein. */
.h-zeile{position:relative}
.h-zeile.leuchtet{animation:zeile-leuchtet 2.4s ease-in-out infinite}
/* dezenter seit dem 24.08.26 spaetabends (Laura: "nicht so krass
   unterlegt"): etwa die halbe Helligkeit der ersten Fassung */
@keyframes zeile-leuchtet{
  0%,100%{background:#17171b;box-shadow:0 0 8px rgb(230 227 220 / .05)}
  50%{background:#1f1f25;box-shadow:0 0 14px rgb(230 227 220 / .11)}
}
@media (prefers-reduced-motion: reduce){
  .h-zeile.leuchtet{animation:none;background:#1b1b20;box-shadow:0 0 10px rgb(230 227 220 / .08)}
}
.h-zeile.klick{cursor:pointer}
/* TIPPEN (Grammatik, design.html): derselbe Kreis, aber er atmet — er
   sagt nicht "irgendwo hier", sondern genau da. Die Lage kommt aus
   der Szene.
   GERADE VERGIBT DIE KLASSE NIEMAND (Stand 25.08.26 nachts): sie sass
   an genau zwei Stellen, beide Male auf dem Zurueck-Pfeil im Chat,
   und dort ruft seit dieser Nacht der Pfeil selbst. Der Baustein
   bleibt trotzdem stehen — er ist die einzige Uebersetzung des
   Tippen-Kleckses aus der Bibel, und die naechste Szene, die auf
   einen Punkt zeigen muss, braucht ihn wieder. */
.tipp-hier{position:absolute;--kl:48px;pointer-events:none;z-index:6}
.tipp-hier .klecks{animation:klecks-atmet 3.2s ease-in-out infinite}
@keyframes klecks-atmet{0%,100%{transform:scale(.86);opacity:.5}50%{transform:scale(1.07);opacity:1}}
@media (prefers-reduced-motion: reduce){
  .h-fuss .h-flieger.winkt,.h-zeile.ruft,.tipp-hier .klecks{animation:none}
}

/* =====================================================================
   LENAS CHAT LOESCHEN (Lauras Diktat, 25.08.26 abends). Drei Stuecke,
   alle drei aus der Grammatik zusammengesetzt, keins neu erfunden:

     1 die wischbare Zeile    die Wischgeste aus design.html
                              (Abschnitt 3), nur mit RAST statt Weg:
                              ein Messenger haelt die Zeile offen,
                              statt sie fortzuwerfen. Gewischt wird
                              nach RECHTS (Lauras Wort), also liegt
                              das Rote links und die Zeile schiebt
                              sich davon herunter.
     2 der Muelleimer         "Etwas ruft" (design.html, Abschnitt 5):
                              das Atmen auf dem Knopf, der Stups auf
                              dem svg darin — zwei Elemente, sonst
                              ueberschreiben sich die Transformationen.
                              Er darf rufen, weil er ein DING ist; die
                              ausdrueckliche Ausnahme dort gilt Lenas
                              ZEILE, und die leuchtet weiter wie bisher.
     3 die Teilueberblendung  faehrt von unten ins Handyfenster und
                              deckt nur einen Teil; dahinter dunkelt
                              der Rest ab, damit die Frage allein steht.

   DAS ROT ist die einzige neue Farbe des Spiels und steht mit Absicht
   NICHT oben bei den vier Grundfarben: es gehoert dem GERAET, so wie
   die Statusleiste dem Geraet gehoert, und soll nirgends sonst
   auftauchen koennen. Darum lebt es hier, im Handy-Teil.
   ===================================================================== */
#handy-panel{--h-rot:#8d2f2f}

/* 1 · die wischbare Zeile. Der Kasten schneidet ab, die Zeile faehrt
   ueber dem Roten und deckt es zu, solange sie zu ist. Die Zeile
   BRAUCHT ihren eigenen Grund (den des Panels): ohne ihn schiene das
   Rot durch, sobald das Leuchten aus ist. */
/* DER HALTER DARF NICHT SCHRUMPFEN (Lauras Befund am Handy, 26.08.26:
   "dann ist der Chat von Lena automatisch geloescht"). Er war nie
   geloescht, er war null Bildpunkte hoch.

   Die Liste ist eine Flexspalte, und eine Flexspalte darf ihre Kinder
   zusammendruecken, sobald der Inhalt laenger ist als der Kasten. Eine
   gewoehnliche .h-zeile wehrt sich von selbst: ihr min-height:auto
   rechnet sich aus dem Inhalt, weil sie nichts abschneidet. Der
   Wisch-Halter schneidet ab (overflow:hidden, sonst laege das Rot
   daneben), und genau dann ist die selbstgerechnete Mindesthoehe NULL.
   Also gab er als einziger nach und nahm die ganze Ueberlaenge der
   Liste auf sich: auf einem kurzen Bildschirm (Telefon mit
   Adressleiste) blieb von Lenas Zeile nichts uebrig, auf einem langen
   war alles in Ordnung. Deshalb sah es aus wie geloescht, und deshalb
   nur manchmal.

   flex:none heisst: diese Zeile ist so hoch wie ihr Inhalt und keine
   Verhandlung. Das Fallen beim echten Loeschen bleibt davon
   unberuehrt, das setzt seine Hoehe selbst (.h-wisch.faellt, unten). */
.h-wisch{position:relative;overflow:hidden;flex:none}
.h-wisch .h-zeile{position:relative;z-index:2;background:#0a0a0a;
  transform:translateX(var(--dx,0px));touch-action:pan-y}
/* nur beim Einrasten und Zurueckfedern laeuft eine Feder mit; waehrend
   der Finger zieht, folgt die Zeile 1:1 (design.html, woertlich) */
.h-wisch[data-lauf="1"] .h-zeile{transition:transform .3s cubic-bezier(.25,.8,.3,1)}
.h-wisch .h-weg{position:absolute;inset:0;z-index:1;display:flex;
  align-items:center;justify-content:flex-start;background:var(--h-rot)}
/* DIE HERBSTBLAETTER (26.08.26). Der Halter deckt die ganze Buehne und
   laesst alles durch: die Blaetter segeln VOR dem Bild, angefasst wird
   nichts von ihnen. Jedes Blatt sitzt in der linken oberen Ecke und
   wird von seiner eigenen Bahn (transform) durchs Bild getragen —
   darum kein left/top, das waere ein zweites Koordinatensystem. */
/* HINTER DEM TEXT, ABER VOR DEM GRUND (Laura, 26.08.26: "kann man
   machen, dass die hinter dem Text fallen?").

   Das ist eine Ebenen-Frage mit einer Wackelstelle, und die ist der
   Grund fuer die Zeile beim Fluss weiter unten: #fluss war nicht
   positioniert, gehoerte also zum normalen Inhalt und wurde VOR allem
   Positionierten mit z-index 0 gemalt — der Regen lag darueber. Sobald
   aber flussAusweichen() ein transform setzt (das passiert bei jeder
   Wahl), wird derselbe Fluss zu einer eigenen Ebene und liegt ploetzlich
   DARUEBER. Dieselbe Stelle sah also je nach Zeile anders aus.

   Ein z-index von -1 am Regen wuerde das auch loesen, haengt dann aber
   daran, dass ueber ihm kein Grund liegt — und das gilt nur, solange
   .spiel und .buehne keinen bekommen. Darum andersherum: der Regen
   bleibt auf 0, und der FLUSS bekommt seine eigene Ebene darueber
   (unten bei .fluss). Damit steht die Reihenfolge fest, egal was
   flussAusweichen gerade tut. */
.f2y-herbst{position:absolute;inset:0;z-index:0;pointer-events:none;
  overflow:hidden}
.f2y-herbst .hb-blatt{position:absolute;left:0;top:0;will-change:transform}
/* isolation: die Schattierungen im Blatt rechnen mit multiply, und
   ohne diese Zeile blenden sie gegen den schwarzen Grund statt gegen
   ihr eigenes Blatt — die schoenste Stelle waere dann ein Loch. */
.f2y-herbst .hb-blatt svg{display:block;isolation:isolate;
  stroke-width:1.1px}

/* IHRE TO-DO-LISTE (26.08.26). Cremeweisses Papier, dunkle Tinte, ein
   Grad schief und Patrick Hand — woertlich die Bauart ihrer Zettel auf
   der Norddeutschlandkarte (geraet.css, .stadtkarte). Sie hat eine
   Handschrift, und die sieht ueberall gleich aus.
   Die Liste steht LINKSBUENDIG, anders als die Kaertchen der Karte:
   eine To-Do-Liste ist eine Liste. Nur die Ueberschrift steht mittig.
   .schreibt setzt einen dunklen Strich hinter die Zeile, die gerade
   geschrieben wird — die Spitze, nicht ein blinkender Cursor. */
.f2y-todo{position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);
  opacity:0;transition:opacity .6s ease}
.f2y-todo.an{opacity:1}
.f2y-todo .td-blatt{width:min(76vw,290px);
  background:#fbf7ee;border-radius:1px;padding:15px 20px 20px;
  font-family:'Patrick Hand',cursive;color:#1f1d1a;
  transform:rotate(-1.4deg);
  box-shadow:0 1px 2px rgba(16,14,10,.26), 0 9px 20px rgba(0,0,0,.38)}
.f2y-todo .td-titel{text-align:center;font-size:clamp(19px,5.4vw,23px);
  line-height:1.25;margin-bottom:.5em}
.f2y-todo .td-zeile{font-size:clamp(15px,4.3vw,18px);line-height:1.5;
  min-height:1.5em}
.f2y-todo .td-neu .td-txt::after{content:'';display:inline-block;
  width:0;height:0}
.f2y-todo .td-neu.schreibt .td-txt::after{width:1px;height:.95em;
  margin-left:1px;vertical-align:-.12em;background:#1f1d1a;opacity:.55}

/* =====================================================================
   DER WORTZETTEL (Laura, 28.08.26; design.html, Stueck 13). EINE Regel
   fuer jede angestrichene Stelle: Antippen oeffnet ihren Zettel —
   Fines Papier, Patrick Hand, ein Grad schief, die Bauart der To-Do-
   Liste direkt hierueber. Dahinter wird das Spiel unscharf und etwas
   dunkler. Das X oben rechts schliesst, ein Tipp auf den Schleier
   daneben auch.

   Vorher waren es drei Bauarten: ein dunkles Blatt im Chat, eine
   Fusszeile im Brief, eine gewoehnliche Erzaehlzeile in der
   Schildkroeten-Szene. Alle drei sind geloescht (28.08.26).

   DER SCHLEIER SITZT IM HALTER, den game.js ihm gibt: .spiel fuer die
   Buehne, das Handy-Panel fuer den Chat. So bleibt das Geraet ein
   Geraet (der Rand des Handys blurrt nicht mit), und auf der Buehne
   liegt er ueber allem, auch ueber Fluss und Fuss.
   z-index 60: ueber den Buehnen-Haltern und ueber dem h-schleier des
   Handys (30), unter nichts, was noch kaeme. */
.wz-schleier{position:absolute;inset:0;z-index:60;
  background:rgb(4 4 5 / .45);
  -webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);
  opacity:0;transition:opacity .3s ease}
.wz-schleier.da{opacity:1}
/* KEINE UEBERSCHRIFT, NIEMALS (Laura, 28.08.26). Der Zettel ist ein
   Gedanke, kein Lexikonartikel; das angestrichene Wort steht noch
   angestrichen dahinter. Das Polster oben ist hoeher als an den
   Seiten, damit die erste Zeile nicht unter das X laeuft. */
.wie-zettel{position:absolute;left:50%;top:50%;
  width:min(76vw,300px);
  transform:translate(-50%,-50%) rotate(-1.4deg) scale(.96);
  background:#fbf7ee;border-radius:1px;padding:30px 20px 20px;
  font-family:var(--s-fine);color:#1f1d1a;
  box-shadow:0 1px 2px rgba(16,14,10,.26), 0 9px 20px rgba(0,0,0,.38);
  transition:transform .3s cubic-bezier(.25,.8,.3,1)}
.wz-schleier.da .wie-zettel{transform:translate(-50%,-50%) rotate(-1.4deg) scale(1)}
/* im Handy-Panel ist die Flaeche schmaler, der Zettel darf sie nicht
   fuellen: er soll auf dem Chat LIEGEN, nicht ihn ersetzen */
.panel .wie-zettel{width:min(82%,300px)}
.wz-text{font-size:clamp(15px,4.3vw,18px);line-height:1.5}
/* das X: klein gezeichnet, gross anzufassen (die Regel vom Handy-X),
   in ihrer Tinte und gedaempft, damit es zum Zettel gehoert */
.wz-zu{position:absolute;top:12px;right:12px;width:18px;height:18px;
  -webkit-appearance:none;appearance:none;background:none;border:0;padding:0;
  color:#1f1d1a;opacity:.55;cursor:pointer}
.wz-zu::before,.wz-zu::after{content:'';position:absolute;
  left:1px;top:8.2px;width:16px;height:1.7px;background:currentColor;border-radius:1px}
.wz-zu::before{transform:rotate(45deg)}
.wz-zu::after{transform:rotate(-45deg)}
.wz-zu span{position:absolute;inset:-14px}
@media (prefers-reduced-motion: reduce){
  .wz-schleier,.wie-zettel{transition:none}
}

/* =====================================================================
   DER SCHUHKARTON, DIE SCHILDKROETE UND DER ZETTEL (26.08.26).
   Buehnen-Sachen, alle nach demselben Muster wie die Kartenrolle: ein
   Halter, der ein- und ausblendet, darin .blackbox.ding mit
   .objektlabel (die Ding-Grammatik aus geraet.css).
   ===================================================================== */
.f2y-schuhblick,
.f2y-kroeteblick,
.f2y-packen,
.f2y-zettelwand{position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);
  opacity:0;transition:opacity .6s ease}
.f2y-schuhblick.an,
.f2y-kroeteblick.an,
.f2y-packen.an,
.f2y-zettelwand.an{opacity:1}
.f2y-schuhblick svg{width:min(58vw,232px);height:auto;display:block}
/* DIE SCHILDKROETE, NACHDEM SIE AUS DEM KARTON KOMMT (28.08.26). Sie
   traegt einen EIGENEN Namen und nicht den des Kartonblicks: die zwei
   stehen in derselben Sekunde uebereinander und blenden ineinander,
   und ein Mass, das beiden gehoert, waere spaeter nur an einem von
   beiden zu aendern.

   KLEINER ALS DER KARTON (min(92vw, 340px * scale), geraet.css) — sie
   ist eben gerade daraus hervorgekommen. Und groesser als beim Packen
   (dort 64px hoch, objektSVG), denn hier steht sie allein auf der
   Buehne und traegt den Gedanken, mit dem die Erinnerung anfaengt. */
.f2y-kroeteblick svg{width:min(58vw,232px);height:auto;display:block}

/* Die Packflaeche hat feste Masse, und die drei Dinge stehen ABSOLUT
   darin (wie in fine). Der Grund steht in game.js: ein gezogenes Ding
   wird position:fixed, und in einer Reihe wuerden die uebrigen im
   selben Moment nachruecken — die Dose waere weg, sobald der Daumen
   losfaehrt. Oben die zwei Dinge, unten die Dose, darunter die Ecken:
   am Handy zieht der Daumen so eine kurze Strecke nach unten statt
   quer ueber den Schirm. */
.f2y-packen{width:min(92vw,340px);height:420px}
.f2y-packen .p-kroete{position:absolute;left:2%;top:0}
.f2y-packen .p-kamera{position:absolute;right:2%;top:0}
.f2y-packen .p-dose{position:absolute;left:50%;bottom:206px;
  transform:translateX(-50%)}
.f2y-packen .ding{cursor:grab;touch-action:none;
  transition:transform .28s cubic-bezier(.25,.8,.3,1)}
/* waehrend der Finger zieht, folgt das Ding 1:1 und federt nicht */
.f2y-packen .ding.faesst{transition:none}
.f2y-packen .ding.faesst{cursor:grabbing;filter:brightness(1.25)}
.f2y-packen .ding.weg{opacity:0;transition:opacity .4s ease}
/* die Kamera, nachdem sie oben auf dem Deckel liegt: kein Ziehen mehr,
   kein Name mehr, sie ist Teil der Dose */
.f2y-packen .p-kamera.aufdeckel{position:absolute;left:50%;top:-38px;right:auto;
  transform:translateX(-50%);cursor:default;pointer-events:none;z-index:2}
.f2y-packen .p-kamera.aufdeckel svg{width:76px;height:auto}
.f2y-packen .p-kamera.aufdeckel .objektlabel{display:none}
/* die vier Ecken unter der Dose. SEIT 28.08.26 DOPPELT SO GROSS
   (Laura: "sie sind zu klein. doppelt so gross") und darum als
   2x2 statt in einer Reihe: vier Ecken von 104px passen nebeneinander
   auf keine Buehne, und ein Deckel hat seine Ecken ohnehin zwei oben,
   zwei unten. Die Packflaeche ist dafuer von 300 auf 420 gewachsen
   und die Dose nach oben gerueckt. */
.f2y-ecken{position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  display:grid;grid-template-columns:repeat(2,auto);
  gap:14px 18px;justify-items:center;
  transition:opacity .4s ease}
.f2y-ecken.weg{opacity:0}
.f2y-ecken .p-ecke{appearance:none;border:0;background:none;padding:0;
  cursor:pointer;touch-action:manipulation}
.f2y-ecken .p-ecke svg{width:104px;height:auto}
.f2y-ecken .p-ecke.zug{opacity:.55;cursor:default}

/* =====================================================================
   DER ZETTEL AM SCHWARZEN BRETT (26.08.26). Zwei Griffe: ziehen und
   eindruecken.

   ALLES RECHNET AUS DEM BRETT. Es ist 268 breit; seine viewBox misst
   132 x 92, es wird also 187 hoch, und die Flaeche im Rahmen liegt
   zwischen 19 und 167. Der Zettel ist 150 breit, sein Blatt darin 66 x
   68 (viewBox 18..46 mal 12..41 von 64 x 48), und es haengt mit der
   Oberkante auf 55: 36 Luft nach oben, 44 nach unten. Die Zwecke steht
   so, dass ihre Spitze 13 unter der Blattkante aufsetzt. Alle diese
   Zahlen sind aus dem einen Mass gerechnet und nicht geraten — wer die
   268 aendert, rechnet sie mit.

   KEIN transform AUF DEM ZETTEL, solange er gezogen werden kann:
   ziehenAuf() schreibt waehrend des Zugs selbst in style.transform, ein
   translateX(-50%) zum Zentrieren waere im selben Augenblick weg, und
   das Ding spraenge um seine halbe Breite zur Seite. Er steht deshalb
   ueber left und eine feste Breite in der Mitte. Erst .haengt darf
   drehen: da ist der Zug vorbei.
   ===================================================================== */
.f2y-zettelwand{width:calc(268px * var(--e));height:calc(340px * var(--e));
  text-align:center}
.f2y-zettelwand .zw-brett{position:absolute;left:0;top:0}
.f2y-zettelwand .zw-brett svg{width:calc(268px * var(--e));height:auto;display:block}

/* der Zettel, solange er in der Hand ist: unten in der Mitte, fassbar */
.f2y-zettelwand .zw-zettel{position:absolute;left:calc(50% - 75px * var(--e));
  bottom:0;width:calc(150px * var(--e));cursor:grab;touch-action:none;
  transition:top .34s cubic-bezier(.25,.8,.3,1),
             bottom .34s cubic-bezier(.25,.8,.3,1),
             transform .34s cubic-bezier(.25,.8,.3,1)}
.f2y-zettelwand .zw-zettel svg{width:calc(150px * var(--e));height:auto;display:block}
/* waehrend der Finger zieht, folgt er 1:1 und federt nicht */
.f2y-zettelwand .zw-zettel.faesst{transition:none;cursor:grabbing;filter:brightness(1.25)}
/* und wie er haengt: oben mittig, einen Grad schief, wie jeder Aushang */
.f2y-zettelwand .zw-zettel.haengt{top:calc(27px * var(--e));bottom:auto;
  cursor:default;transform:rotate(-1.2deg)}
/* das Eselsohr geht mit der Zwecke hinein, es ist dieselbe Bewegung */
.f2y-zettelwand .z-ohr{transition:transform .5s ease;
  transform-box:view-box;transform-origin:46px 41px}
.f2y-zettelwand .zw-zettel.fest .z-ohr{transform:scale(.1)}

/* DIE REISSZWECKE steht so, dass ihre SPITZE das Papier beruehrt. Beim
   Eindruecken sinkt sie um genau die Stiftlaenge (20,5 von 40
   viewBox-Einheiten, bei 46 px Breite also 23,6 px), und der Stift wird
   in derselben Zeit kuerzer: am Ende sitzt der Kopf da, wo eben die
   Spitze war. Beide Zeiten kommen aus --rz-zeit, das die Szene setzt —
   zwei getrennte Zahlen liefen frueher oder spaeter auseinander. */
.f2y-zettelwand .zw-zwecke{position:absolute;left:calc(50% - 23px * var(--e));
  top:calc(28px * var(--e));width:calc(46px * var(--e));
  cursor:pointer;touch-action:none;z-index:4;opacity:0;
  transition:opacity .4s ease,transform var(--rz-zeit,.9s) linear}
.f2y-zettelwand .zw-zwecke.an{opacity:1}
.f2y-zettelwand .zw-zwecke svg{width:calc(46px * var(--e));height:auto;display:block}
.f2y-zettelwand .zw-zwecke .rz-stift{transform-box:view-box;transform-origin:20px 14px;
  transition:transform var(--rz-zeit,.9s) linear}
.f2y-zettelwand .zw-zwecke.drueckt,
.f2y-zettelwand .zw-zwecke.drin{transform:translateY(calc(23.6px * var(--e)))}
.f2y-zettelwand .zw-zwecke.drueckt .rz-stift,
.f2y-zettelwand .zw-zwecke.drin .rz-stift{transform:scaleY(.03)}
/* losgelassen federt sie schnell zurueck: ein Finger, der weggeht, ist
   sofort weg */
.f2y-zettelwand .zw-zwecke.zurueck,
.f2y-zettelwand .zw-zwecke.zurueck .rz-stift{transition-duration:.24s;
  transition-timing-function:cubic-bezier(.25,1.2,.4,1)}
.f2y-zettelwand .zw-zwecke.drin{cursor:default}
/* der Tipp-Klecks der Grammatik, auf dem Kopf der Zwecke */
.f2y-zettelwand .zw-tipp{left:50%;top:calc(9px * var(--e));transform:translate(-50%,-50%)}
/* die eine Zeile unter dem Brett: erst der Name der Zwecke, am Ende der
   Satz, dass der Zettel haengt */
.f2y-zettelwand .zw-name{position:absolute;left:50%;top:calc(198px * var(--e));
  transform:translateX(-50%);white-space:nowrap}

/* =====================================================================
   DIE RADFAHRT (26.08.26). Die Karte nimmt die GANZE Buehne: in dieser
   Szene ist sie das Bild, und was Fine denkt, laeuft darunter im Fluss
   wie ueberall sonst.

   SIE RECHNET NICHT MIT --e, als einziges Bild des Spiels. Alles andere
   Gezeichnete hat eine Referenzgroesse und soll auf jedem Handy
   denselben Anteil der Breite einnehmen. Eine Karte hat keine: sie ist
   ein Ausschnitt aus einer Welt, und ein groesserer Schirm soll MEHR
   davon zeigen, nicht dasselbe groesser. Das Mass steht darum in
   game.js und wird gemessen — eine logische Einheit ist eine CSS-
   Einheit, das Backing traegt die Geraeteaufloesung.
   ===================================================================== */
.f2y-radkarte{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:stretch;opacity:0;transition:opacity .6s ease}
.f2y-radkarte.an{opacity:1}
#radkarte{flex:1 1 auto;width:100%;min-height:0;display:block;
  background:var(--grund);touch-action:none;cursor:pointer}
.radzeile{flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  min-height:calc(2.4 * var(--zeile-barlow));padding:.3em .7em 0}
/* die Zeile gehoert der KARTE und nicht Fine: hier steht, was zu tun
   ist. Gesetzt wie jede Regie, nur enger gesperrt, weil sie oft aus
   drei Saetzen besteht. */
.radfrage{font-family:var(--s-regie);font-size:var(--barlow);
  line-height:var(--zeile-barlow);letter-spacing:.09em;
  color:var(--regie);text-align:center}
/* ⟦VON MIR, LAURA KANN ES STREICHEN⟧ Wenn die Karte auf eine Hand
   wartet, ATMET ihre Zeile. Grund: hier gilt das Gesetz "kein
   Bildschirm ohne sichtbaren Weg weiter" nicht (gelenkt wird ueber die
   Bildhaelften, Lauras Entscheidung vom 26.08.26), es gibt also keinen
   Klecks, der ruft. Das Atmen ist die kleinste Uebersetzung davon und
   erfindet keine neue Gestalt: es ist derselbe Takt wie beim
   Tipp-Klecks (3,2 s), nur an der Schrift statt am Kreis. */
.radfrage.fragt{animation:radfrage-atmet 3.2s ease-in-out infinite}
@keyframes radfrage-atmet{0%,100%{opacity:.6}50%{opacity:1}}
@media (prefers-reduced-motion: reduce){ .radfrage.fragt{animation:none} }

/* =====================================================================
   DER TAG AM TIESSENKAI (26.08.26). Lauras Umbau aus fine, hierher
   uebertragen: der Text sagt dreimal hellen Tag ("Sommer, klare Luft",
   "KEIN BLITZ, TAGESLICHT"), also zeigt das Bild einen.

   VON OBEN NACH UNTEN: Himmel, Horizont, ein duenner Streifen Meer,
   die Uferlinie — und darunter der Kai, der die Buehne selbst ist und
   SCHWARZ bleibt. Die Reihenfolge ist nicht Geschmack: lagen Wasser
   und Uferlinie ganz unten, las sich das Bild als "der Turm steht im
   Meer" (Lauras Befund).

   Zwei Zahlen halten die Aufteilung, --k-ufer und --k-meer; game.js
   setzt sie aus KAI. Himmel und Wolken sind DIESELBEN wie am
   Morgenfenster (--himmel-oben bis --himmel-unten, .mf-wolke); fine
   hat sie sich von hier geholt, hier kommen sie zurueck.
   ===================================================================== */
.f2y-kai{position:absolute;inset:0;overflow:hidden;
  --himmel-oben:#5f9fd0; --himmel-mitte:#84bade; --himmel-unten:#b7d9ec;
  opacity:0;transition:opacity .8s ease}
.f2y-kai.an{opacity:1}
.f2y-kai .k-himmel{position:absolute;left:0;right:0;top:0;
  bottom:calc(var(--k-ufer, 20px) + var(--k-meer, 40px));pointer-events:none;
  background:linear-gradient(177deg, var(--himmel-oben) 0%,
    var(--himmel-mitte) 54%, var(--himmel-unten) 100%)}
.f2y-kai .k-wolken{position:absolute;left:0;right:0;top:0;
  bottom:calc(var(--k-ufer, 20px) + var(--k-meer, 40px));
  overflow:hidden;pointer-events:none}
.f2y-kai .k-bahn{position:absolute;inset:0;will-change:transform;
  animation:mfZiehen var(--wdur, 120s) linear var(--wstart, 0s) infinite}

/* DAS MEER ist gemalt wie der Himmel und nicht gezeichnet: eine
   Flaeche mit Verlauf (am Horizont die Farbe des Himmels, zum Ufer hin
   tiefer, ganz unten fast Buehne) und darauf sechs sehr flache weiche
   Lichtbaender. Die gezeichneten Kraeusel liegen als dunkle Linien
   darueber. */
.f2y-kai .k-meer{position:absolute;left:0;right:0;bottom:var(--k-ufer, 20px);
  height:var(--k-meer, 40px);overflow:hidden;pointer-events:none;
  background:linear-gradient(to bottom,
    color-mix(in srgb, var(--himmel-unten), #24506e 42%) 0%,
    color-mix(in srgb, var(--himmel-mitte), #143247 66%) 58%,
    color-mix(in srgb, var(--himmel-oben), #060d14 82%) 100%)}
.f2y-kai .k-band{position:absolute;
  background:radial-gradient(closest-side, rgba(255,255,255,.92) 0%,
    rgba(255,255,255,.55) 46%, rgba(255,255,255,0) 100%);
  opacity:var(--bdeck, .5);filter:blur(1.4px);
  animation:kaiMeerzug var(--bdur, 60s) linear var(--bstart, 0s) infinite}
@keyframes kaiMeerzug{from{transform:translateX(-130%)}to{transform:translateX(230%)}}

/* die driftenden Kraeusel im Meer, nahtlos geloopt (SPAN/2 sind sechs
   Wellenlaengen, darum trifft translateX(-50%) die Kurve auf sich
   selbst) */
.f2y-kai .k-wasser{position:absolute;left:0;right:0;bottom:var(--k-ufer, 20px);
  height:var(--k-meer, 40px);overflow:hidden;pointer-events:none}
.f2y-kai .k-wasser .welle{position:absolute;left:0;top:0;width:200%;height:100%;
  animation:kaiDrift var(--wdur, 20s) linear infinite}
.f2y-kai .k-wasser .welle.rueck{animation-direction:reverse}
.f2y-kai .k-wasser .welle path{fill:none;stroke:#123043;stroke-width:1.1;
  vector-effect:non-scaling-stroke;stroke-linecap:round}
@keyframes kaiDrift{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* die Uferlinie: EIN Strich, und er ist dunkel, weil er den schwarzen
   Kai vom hellen Wasser trennt */
.f2y-kai .k-kante{position:absolute;left:0;right:0;bottom:var(--k-ufer, 20px);
  height:calc(16px * var(--e));pointer-events:none}
.f2y-kai .k-kante svg{display:block;width:100%;height:100%}
.f2y-kai .k-kante path{fill:none;stroke:#14242e;stroke-width:1.2}
.f2y-kai .k-kante .ripple{stroke:#1b2f3b;stroke-dasharray:6 12}

/* DIE KANTE DER DINGE. objektSVG zeichnet mit stroke="#999" im
   SVG-Kopf; das reicht auf schwarzer Buehne und verschwindet vor einem
   Himmel. In dieser einen Szene tragen Turm, Stein und Kroete darum
   eine helle Kante (Fuellung bleibt Buehnenfarbe, der Strich wird
   hell). Die Regel steht auf den KINDERN und nicht auf dem <svg>: CSS
   schlaegt nur so das geerbte Praesentationsattribut. */
.f2y-kai .ding svg path,.f2y-kai .ding svg rect,
.f2y-kai .ding svg line,.f2y-kai .ding svg circle{stroke:#e8f0f4}
.f2y-kai .objektlabel{color:#dfe6ea;text-shadow:0 1px 3px rgba(0,0,0,.55)}
.f2y-kai .k-turm,.f2y-kai .k-stein{position:absolute;pointer-events:none}
.f2y-kai .k-kroete{position:absolute;left:4%;top:6%;
  cursor:grab;touch-action:none;z-index:3;
  opacity:0;transition:opacity .5s ease}
.f2y-kai .k-kroete.an{opacity:1}
.f2y-kai .k-kroete.faesst{cursor:grabbing;filter:brightness(1.25)}
.f2y-kai .k-kroete.sitzt{cursor:default}
/* sie SETZT sich: ein kurzes Wackeln, lautlos */
.f2y-kai .k-kroete.setzt{animation:kaiSetzt var(--wackel, .24s) ease-out 1;
  transform-origin:50% 100%}
@keyframes kaiSetzt{
  0%{transform:rotate(-2.2deg) translateY(-1.5px)}
  55%{transform:rotate(1.2deg)}
  100%{transform:rotate(0)}
}
/* die vier Ecken der Dose stehen NOCH NICHT auf dem Kai: sie kommen
   davor, auf der leeren Buehne, und haben darum ihren eigenen Halter
   (.f2y-kecken weiter unten). Der Grund steht in game.js. */
/* DIE KAMERA-GRIFFE (Ausloeser, Kurbel) SIND KURZ DER WEITER-KNOPF
   (28.08.26: "der Ausloeser muss den Weiterknopf ersetzen, danach die
   Kurbel, dann kommt der Weiterknopf wieder"). Dieselbe Regel wie im
   Foto-Geraet (s.u. "DER AUSLOESER IST KURZ DER WEITER-KNOPF"): der
   Griff setzt sich mit seiner MITTE auf --knopf-mitte, genau dorthin,
   wo sonst der Klecks sitzt; solange er da ist, ist der Klecks still
   (knopfAn(false) in game.js), danach uebernimmt der Klecks zurueck.
   Vorher hingen die Griffe unten rechts IN der Kai-Welt und standen
   dort neben dem sichtbaren Klecks — zweierlei Knoepfe zugleich, und
   der Ausloeser lag auf dem Turm. column-reverse stellt die
   Beschriftung UEBER den Knopf: unter der Knopfmitte bleiben nur
   28 px Sockel (84er Knopf, halbe Hoehe 42). */
.fuss .k-ritual{position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  transition:opacity .4s ease}
.fuss .k-ritual.weg{opacity:0}
.fuss .k-ritual .ausloeserbox,
.fuss .k-ritual .kurbelbox{flex-direction:column-reverse;
  padding:0 0 calc(var(--knopf-mitte) - 42px)}
.fuss .k-ritual .ausloeserknopf,
.fuss .k-ritual .kurbelknopf{width:84px;height:84px}

/* DER SUCHER: vier Eckwinkel, sonst nichts. Eine Einwegkamera ist ein
   leeres Plastikfenster. Er ist HOCHKANT wie das spaetere Foto, kommt
   beim Ansetzen von unten hoch und sinkt beim Weglegen.
   NICHT REINES WEISS im Ruhezustand: Weiss gehoert dem Einrasten.
   Der Schlagschatten ist der Grund, warum derselbe Winkel oben im
   Himmel und unten auf dem schwarzen Kai zu sehen ist. */
.f2y-kai .k-sucher{position:absolute;pointer-events:none;opacity:0;
  transform:translateY(calc(8px * var(--e)));
  transition:opacity .4s, transform .4s;z-index:8}
.f2y-kai .k-sucher.an{opacity:1;transform:translateY(0)}
.f2y-kai .k-sucher.aktiv{pointer-events:auto;cursor:grab;touch-action:none}
.f2y-kai .k-sucher.aktiv:active{cursor:grabbing}
.f2y-kai .k-sucher.rastet{animation:kaiRuck var(--ruck, .19s) ease-out 1}
@keyframes kaiRuck{
  0%{transform:translateY(-2px) rotate(.5deg)}
  60%{transform:translateY(1px) rotate(-.3deg)}
  100%{transform:translateY(0)}
}
.f2y-kai .k-ecke{position:absolute;border:0 solid #dfe6ea;--ew:4.3px;
  filter:drop-shadow(0 0 3px rgba(0,0,0,.6)) drop-shadow(0 1px 1px rgba(0,0,0,.4))}
.f2y-kai .k-ecke.lo{left:0;top:0;border-left-width:var(--ew);border-top-width:var(--ew);transform-origin:left top}
.f2y-kai .k-ecke.ro{right:0;top:0;border-right-width:var(--ew);border-top-width:var(--ew);transform-origin:right top}
.f2y-kai .k-ecke.lu{left:0;bottom:0;border-left-width:var(--ew);border-bottom-width:var(--ew);transform-origin:left bottom}
.f2y-kai .k-ecke.ru{right:0;bottom:0;border-right-width:var(--ew);border-bottom-width:var(--ew);transform-origin:right bottom}
/* EINRASTEN, sichtbar: der Ruck am Rahmen allein war zu leise. Die
   vier Winkel schnappen einmal auf und bleiben danach dicker stehen —
   der Ausschnitt ist gefunden und haelt. Die Farbe setzt game.js
   (Weiss = Ereignis), hier steht nur die Form. */
.f2y-kai .k-sucher.gerastet .k-ecke{--ew:5.6px}
.f2y-kai .k-sucher.rastet .k-ecke{animation:kaiSchnapp var(--ruck,.19s) ease-out 1}
@keyframes kaiSchnapp{
  0%{transform:scale(1);filter:none}
  38%{transform:scale(1.32);filter:drop-shadow(0 0 7px rgba(255,255,255,.9))}
  100%{transform:scale(1);filter:none}
}
.f2y-kai .k-verschluss{position:absolute;inset:0;background:#050505;opacity:0}

/* wer keine Bewegung will, bekommt trotzdem einen Himmel: Wolken und
   Lichtbaender halten an ihrer Stelle an, statt zu verschwinden
   (dieselbe Regel wie am Morgenfenster) */
.f2y-kai.still .k-bahn{animation:none;transform:translateX(var(--wruhe, 0%))}
.f2y-kai.still .k-band{animation:none;transform:translateX(var(--bruhe, 40%))}
.f2y-kai.still .k-wasser .welle{animation:none}
@media (prefers-reduced-motion: reduce){
  .f2y-kai .k-bahn{animation:none;transform:translateX(var(--wruhe, 0%))}
  .f2y-kai .k-band{animation:none;transform:translateX(var(--bruhe, 40%))}
  .f2y-kai .k-wasser .welle{animation:none}
  .f2y-kai .k-kroete.setzt{animation:none}
  .f2y-kai .k-sucher{transform:none}
  .f2y-kai .k-sucher.rastet,.f2y-kai .k-sucher.rastet .k-ecke{animation:none}
}

/* DAS FOTO AUF DEM DISPLAY. Es ist das einzige Bild des Spiels, das
   FARBE traegt und keine Zeichnung auf Schwarz ist: es soll aussehen
   wie ein Foto und nicht wie eine Skizze. Darum stehen hier auch die
   Farben literal und nicht als Grammatik-Variablen. */
/* die vier Ecken der Tupperdose, auf der leeren Buehne vor dem Kai.
   Doppelt so gross und als 2x2, wie beim Packen am Vormittag
   (28.08.26, die Begruendung steht dort). */
.f2y-kecken{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  display:grid;grid-template-columns:repeat(2,auto);
  gap:calc(16px * var(--e)) calc(20px * var(--e));justify-items:center;
  opacity:0;transition:opacity .5s ease}
.f2y-kecken.an{opacity:1}
.f2y-kecken .p-ecke{appearance:none;border:0;background:none;padding:0;
  cursor:pointer;touch-action:manipulation}
.f2y-kecken .p-ecke svg{width:calc(104px * var(--e));height:auto}
.f2y-kecken .p-ecke.zug{opacity:.55;cursor:default}

.f2y-ltrahmen{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:calc(230px * var(--e));max-width:86%;
  border:1px solid #2a2f33;border-radius:2px;overflow:hidden;
  opacity:0;transition:opacity .6s ease}
.f2y-ltrahmen.an{opacity:1}
.f2y-ltrahmen svg{display:block;width:100%;height:auto}

/* =====================================================================
   DAS AUFFALTEN AM KAI (28.08.26): das Schildkroeten-Blatt auf der
   leeren Buehne, Bauart und Masse des Wals aus der Nacht (bogenSVG,
   die vier Stufen). Das HAIKU liegt in der MITTE des offenen Blatts,
   auf dessen weisser Rueckseite (fine, Hanna 29.07.26: erzaehlt wird
   das nirgends — man sieht es): das einzige Ding im Spiel mit eigener
   Papierflaeche, das handgeschriebenste Artefakt — Caveat (--s-hand),
   nie gesperrt. Kein Reinweiss (Kanon: Weiss = Ereignis), #faf8f1.
   Der Falz laeuft bei 34 %: durch die Leerzeile, nicht durch die
   erste Gedichtzeile.
   ===================================================================== */
.f2y-falten{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:14px;
  opacity:0;transition:opacity .6s ease}
.f2y-falten.an{opacity:1}
#buehne .f2y-falten #faltbogen{width:min(190px,56vw);height:min(130px,32vh);position:relative}
#buehne .f2y-falten #faltbogen.offen1{width:min(250px,72vw);height:min(210px,36vh)}
#buehne .f2y-falten #faltbogen.offen2{width:min(300px,84vw);height:min(300px,40vh)}
#buehne .f2y-falten #faltbogen.offen3{width:min(340px,90vw);height:min(360px,44vh)}
/* Rueckfall wie beim Wal: ohne Renderer bleibt die Blackbox spielbar */
.f2y-falten .blackbox{display:flex;align-items:center;justify-content:center;
  border:1px dashed #444;color:#8a8a8a;letter-spacing:.2em;
  font-size:calc(var(--barlow) * .72);font-family:var(--s-regie)}
.f2y-falten .blackbox.als-svg{border-color:transparent;color:transparent}
.f2y-falten #faltbogen.ziehbar{cursor:grab;touch-action:none}
/* der FESTHALTEN-Knopf der Boee: fines Masse (150 x 60); den Balken
   und die haltend/gehalten-Kanten bringt haltenGeste mit */
.f2y-falten .halteknopf{appearance:none;background:none;padding:0;
  width:150px;height:60px;cursor:pointer;touch-action:none;
  opacity:0;transition:opacity .4s ease}
.f2y-falten .halteknopf.da{opacity:1}
.f2y-falten .haiku{position:absolute;left:50%;top:50%;
  pointer-events:none;  /* nie interaktiv — ausgeblendet fing es sonst
                           den Rueckfalt-Zug vor dem Blatt ab */
  transform:translate(-50%,-50%) rotate(-.6deg);  /* ein Blatt liegt nie ganz gerade */
  text-align:center;color:#1a1a1a;line-height:1.9;
  font-family:var(--s-hand);font-weight:500;font-size:1.3rem;letter-spacing:0;
  background:#faf8f1;padding:1.6rem 1.3rem;width:max-content;max-width:min(19rem,80vw);
  border-radius:1px;box-shadow:0 3px 16px rgba(0,0,0,.5);
  opacity:0;transition:opacity .6s ease}
.f2y-falten .haiku.da{opacity:1}
.f2y-falten .haiku::before{content:'';position:absolute;left:0;right:0;top:34%;
  border-top:1px dashed #ddd8ca}
@media (prefers-reduced-motion: reduce){
  .f2y-falten,.f2y-falten .haiku,.f2y-falten .halteknopf{transition:none}
}

/* =====================================================================
   DER NACHMITTAG AM STEIN (28.08.26, k2s6): die Fotos vom Oktober
   2024 im Handy und der Status-Schlag "FABI · Zuletzt online" ueber
   dem Blatt. Bauart der Status-Bahn woertlich aus fines
   .displayzeile.nstatus: zwei Haarlinien oeffnen eine Bahn, links das
   Etikett, rechts die Zeit.
   ===================================================================== */
/* DIE FOTO-ROLLE (29.08.26, Lauras Umbau: eine Seite je Schritt,
   vier Punkte wie am Handy, der Klecks blaettert — die rollende
   Liste .fotoblock/.fototext von davor ist damit raus). Das Foto
   liegt ganz auf Schwarz (object-fit:contain, wie ein Foto-Viewer)
   und traegt DASSELBE GRAU wie die Hamburg-Nacht: grayscale, die
   Regel der .fglage im Fotogeraet. Die Punkte sind Geraetechrome,
   grau — Butter bleibt dem Klecks. */
.fotorolle{flex:1 1 auto;min-height:0;display:flex;
  align-items:center;justify-content:center;
  padding:8px 16px 34px;
  /* senkrecht bleibt dem Browser (der lange Text rollt), waagerecht
     gehoert dem Wisch (game.js) */
  touch-action:pan-y}
.fotorolle .fotoseite{position:relative;
  display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:14px;max-height:100%;min-height:0;width:100%;
  animation:fotoseite-an .45s ease both}
/* die Wisch-Einladung auf dem ersten Foto: der Klecks zieht nach
   links, bis die Geste einmal sass (Bauart wie .wisch-zug in der
   Chatliste, nur in die andere Richtung) */
.fotorolle .rolle-wisch{position:absolute;left:50%;bottom:15%;
  --kl:48px;margin-left:calc(var(--kl) / -2);pointer-events:none;z-index:3}
.fotorolle .rolle-wisch .klecks{
  animation:klecks-wischt-links 2.9s cubic-bezier(.35,0,.3,1) infinite}
@keyframes klecks-wischt-links{
  0%{transform:translateX(34px);opacity:0}
  16%{opacity:.95}
  62%{transform:translateX(-34px);opacity:.95}
  82%,100%{transform:translateX(-48px);opacity:0}}
.fotorolle .fotovoll{max-width:100%;min-height:0;flex:0 1 auto;
  object-fit:contain;display:block;border-radius:4px;
  filter:grayscale(1)}
.fotorolle .fotowort{min-height:0;flex:0 1 auto;overflow-y:auto;
  overscroll-behavior:contain;padding:0 6px}
.fotorolle .fotowort p{margin:0;font-family:var(--s-lesen);
  font-size:calc(var(--hanken) * .88);line-height:1.75;color:#cfcfcf}
.fotorolle .fotowort.gedanke p{color:#bcbcbc;font-style:italic}
.fotopunkte{flex:0 0 auto;display:flex;gap:7px;
  align-items:center;justify-content:center}
.fotopunkte .fpunkt{width:6.5px;height:6.5px;border-radius:50%;
  background:#3a3a3e}
.fotopunkte .fpunkt.an{background:#a8a8ac}
@keyframes fotoseite-an{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion: reduce){
  .fotorolle .fotoseite{animation:none}
  .fotorolle .rolle-wisch .klecks{animation:none}
}
/* das plopp ist anklickbar (fines Osterei) — seit dem 29.08.26 als
   ANGESTRICHENE Stelle (Laura: "warum ist das plopp so blau? wir
   haben dafuer doch eine Regel in design.html? es ist hinterlegt"):
   den Strich bringen die Klassen angestrichen/walblau mit, hier
   steht nichts Eigenes mehr — keine eigene Farbe, kein Schein. */
/* (der "Handy sinken lassen"-Knopf aus fine stand kurz hier und ist
   wieder raus, 28.08.26: das Geraet kennt nur Zurueck-Pfeil und den
   Weiter-Klecks — .handy-weiter, weiter oben) */
/* der Status-Schlag: die Bahn schwebt UEBER dem Blatt, nicht im
   Fluss. Eigener Grund und z-index: auf kleinen Buehnen reicht das
   offene Blatt weit hinauf, die Bahn darf nicht von seiner Kante
   durchschnitten werden. */
.f2y-status{position:absolute;left:50%;top:4%;transform:translateX(-50%);
  width:min(85%, 340px);display:flex;align-items:baseline;
  justify-content:space-between;gap:1.2rem;z-index:5;
  background:var(--buehne);
  padding:.75rem 2px .85rem;border-top:1px solid #3a3a3a;
  border-bottom:1px solid #3a3a3a;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .82);
  letter-spacing:.18em;color:#8f8f8f;
  opacity:0;transition:opacity .5s ease}
.f2y-status.da{opacity:1}
.f2y-status .nzeit{flex:none;letter-spacing:.12em;color:#6e6e6e}
@media (prefers-reduced-motion: reduce){ .f2y-status{transition:none} }
.ltfoto .ltf-ding path,.ltfoto .ltf-ding rect,
.ltfoto .ltf-ding line,.ltfoto .ltf-ding circle{stroke:#eef4f8;stroke-width:1.4;
  vector-effect:non-scaling-stroke;fill:none}
.ltfoto .ltf-ding [fill="var(--buehne)"]{fill:#0b0b0b}
.ltfoto .ltf-wfern,.ltfoto .ltf-wnah{filter:blur(2.2px)}
.ltfoto .ltf-wfern path{fill:#fff;fill-opacity:.86;stroke:none}
.ltfoto .ltf-wnah path{fill:#fff;fill-opacity:.94;stroke:none}
.ltfoto .ltf-moewe path{fill:none;stroke:#33454f;stroke-width:1.1;
  vector-effect:non-scaling-stroke;stroke-linecap:round}
.ltfoto .ltf-kante{fill:none;stroke:#1d3140;stroke-width:1.4;
  vector-effect:non-scaling-stroke}
.ltfoto .ltf-horizont{fill:none;stroke:#cfe4f0;stroke-width:1;opacity:.7;
  vector-effect:non-scaling-stroke}
.ltfoto .ltf-ripple{fill:none;stroke:#e8f4fb;stroke-width:1;opacity:.55;
  vector-effect:non-scaling-stroke;stroke-linecap:round}

/* das Blatt selbst, als Zeile im Fluss: enger gesetzt als ein Satz und
   linksbuendig, damit es wie ein Aushang liest und nicht wie ein
   Gedanke */
.satz.blatt{font-size:calc(var(--hanken) * .92);line-height:1.5;
  text-align:left;color:#c8c6c1;
  border-left:1px solid #3a3a3a;padding-left:14px}
.satz.blatt b{font-weight:600;color:var(--tinte)}

/* 1b · DIE STILLE ZEILE (26.08.26, Laura: "der Lena Chat hat oben
   sone rote Kante. Das ist beim ersten Mal, wenn einem das Loeschen
   gezeigt wird, wie das gehen kann, nett, darf aber spaeter nicht mehr
   passieren").

   Das Rote liegt unter der Zeile und blitzt an ihrer Kante durch: die
   Zeile faehrt auf einer eigenen Ebene (transform), und deren Rand
   faellt nicht auf denselben Geraetepunkt wie der Kasten darunter. Im
   Tutorial ist das die halbe Erklaerung — da liegt etwas unter dieser
   Zeile. Ueberall danach ist es ein Versprecher: ein Chat, an dem
   schon jemand war.

   .still nimmt beides weg, die Einladung und das Rot, und gibt das Rot
   in dem Augenblick zurueck, in dem der Finger die Zeile wirklich
   fasst. Das ist .gefasst, und das setzt wischRast selbst beim ersten
   Querzug — also noch bevor sich die Zeile bewegt und eine Luecke
   entstehen koennte. Wer die Kante wiederhaben will, laesst .still
   einfach weg. */
.h-wisch.still .wisch-zug{opacity:0}
.h-wisch.still .h-weg{opacity:0}
.h-wisch.still.gefasst .h-weg{opacity:1}

/* 2 · der Muelleimer. Sein Aussehen steht EINMAL da und gilt an
   beiden Orten (im Roten unter der Zeile und im Blatt): es ist
   derselbe Knopf, zweimal gefragt. Nur was sich unterscheidet, steht
   beim jeweiligen Ort — sonst faellt beim naechsten Mal auf, dass das
   display:flex nur an einer der zwei Stellen ankam und die Zeichnung
   im Blatt in eine eigene Zeile rutscht. */
.h-loeschen{display:flex;align-items:center;justify-content:center;gap:9px;
  color:#f2e6e6;font-family:var(--werkzeug);font-size:12px;
  font-weight:600;letter-spacing:.01em;cursor:pointer}
/* im Roten: so hoch wie die Zeile, und linksbuendig — er kommt ja von
   links unter ihr hervor. Er ruft erst, wenn die Zeile offen steht. */
.h-weg .h-loeschen{height:100%;padding:0 17px;justify-content:flex-start}
.h-loeschen .eimer{flex:0 0 auto;display:flex;width:19px;height:19px}
.h-loeschen .eimer svg{width:100%;height:100%;display:block;overflow:visible}
.h-loeschen.ruft .eimer{animation:ruf-atem 3.4s ease-in-out infinite}
.h-loeschen.ruft .eimer svg{animation:ruf-stups 4.6s ease-in-out infinite}
/* die Wisch-Einladung, quer: derselbe Klecks der Grammatik (29 px,
   Butter, 2,9 s, dieselbe Beschleunigung), nur zieht er nach rechts.
   Er sitzt am linken Ende der Zeile und deutet den Weg; beim ersten
   Griff ist er weg und kommt nicht wieder.
   DIE BEWEGUNG IST DIE DER DOSE: klecks-zieht-rechts steht weiter
   unten (beim Oeffner) und wird hier MITBENUTZT, nicht neu gesetzt.
   Zwei @keyframes gleichen Namens sind in CSS kein Fehler, sondern
   eine stille Uebernahme — die letzte gewinnt fuer alle, und die
   erste ist dann eine Regel, die dasteht und nichts tut. */
/* WO ER SITZT, IST EINE FRAGE DER LESBARKEIT: mittig auf der Zeile
   legt er sich quer ueber den NAMEN, und der Name ist das, was man
   hier lesen muss. Er sitzt darum eine Zeile tiefer, auf der grauen
   Vorschau — sie ist zweitrangig, und er ist ohnehin weg, sobald
   einmal angefasst wurde. Losfahren tut er auf dem Bild links, also
   dort, wo der Daumen von selbst liegt. */
.h-wisch .wisch-zug{position:absolute;left:14px;top:calc(50% + 11px);z-index:3;--kl:48px;
  margin-top:calc(var(--kl) / -2);pointer-events:none;transition:opacity .25s ease}
.h-wisch .wisch-zug .klecks{animation:klecks-zieht-rechts 2.9s cubic-bezier(.35,0,.3,1) infinite}
.h-wisch[data-zieht="1"] .wisch-zug,.h-wisch.gefasst .wisch-zug{opacity:0}
/* die Luecke schliesst sich: die Zeile faehrt weg, dann faellt ihre
   Hoehe zusammen und die Liste rueckt nach. Zwei Schritte, damit man
   BEIDES sieht — das Weggehen und das Zugehen. */
.h-wisch{transition:height .34s cubic-bezier(.4,0,.2,1),opacity .34s ease}
.h-wisch.faellt{height:0 !important;opacity:0;overflow:hidden}
@media (prefers-reduced-motion: reduce){
  .h-loeschen.ruft .eimer,.h-loeschen.ruft .eimer svg,
  .h-wisch .wisch-zug .klecks{animation:none}
}

/* 3 · die Teilueberblendung. Sie liegt IM Handyfenster (Lauras Wort:
   "von unten ploppt in das handyfenster eine teilueberblendung"), also
   im Panel und nicht ueber dem Bildschirm: das Geraet bleibt ein
   Geraet, und der Rest des Handys bleibt sichtbar, nur abgedunkelt. */
.h-schleier{position:absolute;inset:0;z-index:30;background:rgb(4 4 5 / .62);
  opacity:0;transition:opacity .28s ease}
.h-schleier.da{opacity:1}
.h-blatt{position:absolute;left:0;right:0;bottom:0;z-index:31;
  background:#191920;border-radius:16px 16px 0 0;
  /* KEINE Sicherheitszone hier: das Panel haelt sie schon unten frei
     (geraet.css), und ein absolut gesetztes bottom:0 sitzt ohnehin an
     der Innenkante des Polsters. Zweimal gerechnet waere es doppelt. */
  padding:20px 20px 24px;
  transform:translateY(100%);transition:transform .3s cubic-bezier(.25,.8,.3,1)}
.h-schleier.da .h-blatt{transform:translateY(0)}
.h-blatt .frage{font-family:var(--werkzeug);font-size:14px;font-weight:600;
  line-height:1.35;color:#e2e2e6;padding-right:34px;margin-bottom:18px}
/* der Knopf im Blatt traegt dasselbe Rot wie das Feld unter der Zeile
   und denselben Muelleimer — es ist dieselbe Tat, zweimal gefragt */
.h-blatt .h-loeschen{width:100%;height:46px;border-radius:11px;
  background:var(--h-rot);font-size:13.5px}
.h-blatt .h-loeschen:active{filter:brightness(1.14)}
/* das X oben rechts: klein gezeichnet, gross anzufassen (dieselbe
   Regel wie beim Zurueck-Pfeil) */
.h-blatt .h-zu{position:absolute;top:14px;right:14px;width:20px;height:20px;
  color:#9a9aa0;cursor:pointer}
.h-blatt .h-zu::before,.h-blatt .h-zu::after{content:'';position:absolute;
  left:2px;top:9.2px;width:16px;height:1.6px;background:currentColor;border-radius:1px}
.h-blatt .h-zu::before{transform:rotate(45deg)}
.h-blatt .h-zu::after{transform:rotate(-45deg)}
.h-blatt .h-zu span{position:absolute;inset:-14px}
/* Nummer 4 war das Wort-Blatt der zwei Chat-Woerter; geloescht am
   28.08.26, sie oeffnen den Wortzettel (oben, "DER WORTZETTEL"). Der
   h-schleier bleibt: er traegt weiter das Loesch-Blatt des
   Muelleimers. */

@media (prefers-reduced-motion: reduce){
  .h-schleier,.h-blatt,.h-wisch,.h-wisch[data-lauf="1"] .h-zeile{transition:none}
}

/* das Geraet (die Fabi-Erinnerung) darf unsere Lese-Zeile nicht
   erben: --zeile ist in px gerechnet, und px vererbt den BERECHNETEN
   Wert — das Sendefeld bekam 26px Zeilen auf 13px Schrift (Lauras
   Befund 24.08.26). fines eigener body setzt gar keine line-height,
   normal stellt genau das wieder her; alles mit eigener Zeile
   (Blasen, Chatkopf) behaelt sie. */
#ov-handy{line-height:normal}

/* DER RUF SITZT IN DER ABLAGE, NICHT IM KARTON (Laura, 24.08.26:
   "erst auf sich aufmerksam machen, wenn sie in den boxen unten
   liegen") und ruft als STUPS (design.html, spaetabends): das
   Kaertchen atmet, das Bild darin wackelt kurz — Atmen und Stups auf
   zwei Elementen, die Keyframes kommen aus der Grammatik oben. Die
   Stups-Animation am .objektbild ueberschreibt nur dessen
   transform:none aus dem Handy-Mass, das traegt keine Lage. Der
   Brief ruft nie, ihn laedt der Auffalt-Platz ein. */
#buehne .kabgelegt{position:relative}
#buehne .kabgelegt.ruft{animation:ruf-atem 3.4s ease-in-out infinite}
#buehne .kabgelegt.ruft .objektbild{animation:ruf-stups 4.6s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){
  #buehne .kabgelegt.ruft,#buehne .kabgelegt.ruft .objektbild{animation:none}
}

/* alle Dinge in der Kiste zehn Prozent groesser (Laura, 24.08.26) */
#buehne .kinnen .kding .objektbild{height:min(calc(106px * var(--scale)), 17.6vh) !important;width:auto !important}
#buehne .kinnen .kdbrief .objektbild{height:min(106px, 13.2vh) !important;width:auto !important}

/* die Ebene, auf der gehoben und geflogen wird. Das gehaltene Ding
   atmet kaum sichtbar, zwei Bildpunkte, mehr nicht: es liegt in einer
   Hand, es ruft nicht. */
.flugebene{position:absolute;inset:0;pointer-events:none;z-index:5}
.flieger svg{animation:ding-ruht 4.6s ease-in-out infinite;transition:transform .22s ease}
@keyframes ding-ruht{0%,100%{transform:translateY(0)}50%{transform:translateY(-2px)}}

/* ---------- das Ziehen ----------
   Anfassbar heisst: die Zielflaeche ist groesser als das Ding, der
   Daumen verdeckt ja die Haelfte. Gefasst hoert das Atmen auf (es
   liegt jetzt wirklich in der Hand) und das Ding waechst einen Hauch.
   Die Kiste, ueber der es schwebt, richtet sich ihm leicht entgegen. */
.flieger.fassbar{pointer-events:auto;cursor:grab;touch-action:none}
.flieger.fassbar::after{content:"";position:absolute;inset:-18px}
.flieger.gefasst{cursor:grabbing}
.flieger.gefasst svg{animation:none;transform:scale(1.05)}
/* z-index 2 haelt die Kiste VOR den herauslugenden Stuecken (.peeks
   liegt auf 1): ihr gefuellter Koerper deckt zu, was in ihr steckt */
.ziel .kiste{display:block;position:relative;z-index:2;
  transition:transform .22s ease;transform-origin:50% 100%}
.ziel.will .kiste{transform:scale(1.045)}

/* die Einladung und die vorgemachte Hand: derselbe Klecks wie ueberall,
   seit dem 30.08.26 der AUSGEFUELLTE Kringel in Weiter-Groesse (48).
   GEFASST HAT KEINE EIGENE FARBE MEHR. Vorher stand das Butter hier
   pur statt auf 85 % und die helle Zweitlage sprang auf .34; beides
   gibt es nicht mehr — der gefuellte Kreis hat keine zweite Lage, und
   seine Farbe steht ohnehin voll da. Gefasst sackt er zusammen, wie
   der Knopf beim Druecken, und sagt damit dasselbe mit der Bewegung. */
.zieh-zug{position:absolute;left:50%;top:50%;--kl:48px;z-index:3;
  pointer-events:none;transform:translate(-50%,-50%)}
.zieh-zug.fest .klecks::before{transform:scale(.9)}

/* der Namensbalken aus fine: ihr Nachname faellt weiss aus */
.namensbalken{display:inline-block;width:4.4em;height:.72em;
  background:var(--tinte);border-radius:2px}

/* der schwarze Bildschirm taucht weich auf; sein Spalten-Deckel steht
   seit dem 24.08.26 als --spalte in design.html (Befund Laura: im
   breiten Fenster lief der Text quer durchs Bild) */
.schirm{animation:auftauchen .3s ease both}
.schirm-zeile{max-width:var(--spalte);margin:0 auto}

/* ---------- das Gegenlicht ----------
   FESTE REGEL DER GRAMMATIK, seit dem 24.08.26 als Stueck 9 in
   design.html (Laura: "damit das immer zu finden ist. mit den exakten
   werten"); Begruendung, Herkunft der Werte und das Nachschaerf-Gesetz
   stehen dort am CSS-Block der Regel. Hier die woertliche Kopie: wer
   aendert, aendert in design.html und zieht hier nach, nie umgekehrt.
   Jede Quinn auf dunklem Grund bekommt sie; die Klasse liegt auf einem
   Kasten UM das Bild (ein img traegt kein ::before), und der Kasten
   ist so breit wie das BILD, nicht wie der Schirm. */
.gegenlicht{position:relative;display:block}
.gegenlicht > *{position:relative;z-index:2}
/* zwei Staerken seit dem 24.08.26 abends, beide zweimal von Laura
   nachgestellt: ohne Zusatz die helle Fassung fuer das reine Schwarz
   der Bildschirme (fine-Reihe mal 1,3225), mit .auf-grund die
   dunklere fuer den Buehnengrund #0e0e10 (mal 0,68) */
.gegenlicht::before{content:'';position:absolute;z-index:1;pointer-events:none;
  inset:-30% -45%;
  background:radial-gradient(66% 54% at 50% 48%,
    rgb(200 200 200 / 25.78875%) 0%,
    rgb(200 200 200 / 17.85375%) 24%,
    rgb(200 200 200 / 8.926875%) 50%,
    rgb(200 200 200 / 2.975625%) 68%,
    rgb(0 0 0 / 0%) 80%)}
.gegenlicht.auf-grund::before{
  background:radial-gradient(66% 54% at 50% 48%,
    rgb(200 200 200 / 13.26%) 0%,
    rgb(200 200 200 / 9.18%) 24%,
    rgb(200 200 200 / 4.59%) 50%,
    rgb(200 200 200 / 1.53%) 68%,
    rgb(0 0 0 / 0%) 80%)}
.schirm-quinn{display:block;width:122px;height:auto}

/* =====================================================================
   DER PAKETBOTE (30.08.26): das Geraet des Boten, eine Kritzelflaeche
   mitten im Bild. KEIN Geraete-Grau aus der Handy-Reihe (die gehoert
   dem Handy, nie der Buehne): die Flaeche ist Buehnengrund mit einer
   ruhigen Linie im Werkbank-Grau #8a8a8a — dieselbe Stimme wie die
   Briefkasten-Linie in k4s3 —, gekritzelt wird in Tinte (game.js,
   TINTE). Der Rand ist NICHT gestrichelt: gestrichelt hiesse offen
   wie eine Wahl (SPEC · feste Regeln), und dieses Feld ist keine.
   Die Tipp-Einladung sitzt mittig auf der leeren Flaeche und geht
   mit dem ersten Strich (game.js). */
.f2y-paket{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .6s ease;pointer-events:none}
.f2y-paket.an{opacity:1;pointer-events:auto}
.pk-flaeche{position:relative;display:block;padding:6px;margin:0;
  background:var(--buehne);border:1.5px solid #8a8a8a;border-radius:6px;
  touch-action:none}
.pk-pad{display:block;width:min(300px, 78vw);height:auto}
.pk-tipp{left:50%;top:50%;margin:calc(var(--kl) / -2) 0 0 calc(var(--kl) / -2)}

/* die Traumglaeser: die ganze Szene sitzt mittig im Bildschirm
   (Laura, 24.08.26), die Saetze fallen unter das Bild */
.f2y-traum{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(374px, 96%);z-index:6}
.flieger{position:absolute;left:0;top:0;will-change:transform}

/* DAS BILD STEHT STILL (Laura, 25.08.26: beim Antippen wanderte "die
   Grafik ganz kurz einen Sprung nach oben und dann wieder zurueck").
   Der Halter oben ist mittig gerechnet, also zaehlt jeder Satz unter
   dem Bild mit: der erste Satz machte den Halter 29 px hoeher und schob
   die Glaeser damit 16 px nach oben, der abgeraeumte Satz schob sie
   wieder zurueck. Deshalb steht der Platz fuer eine Zeile von Anfang an
   da (min-height) und die Saetze haengen absolut darin. Wer laenger
   spricht, waechst nach unten; das Bild rechnet nicht mehr mit.
   Steht hier und nicht in geraet.css: das ist der maschinelle Auszug,
   der bei jedem Neuziehen aus site/spiel/ ueberschrieben wird. */
.tf-buehne{position:relative;min-height:calc(1.72 * 1.05rem * var(--ts))}
.tf-gruppe{position:absolute;left:0;right:0;top:0;margin:0}

/* Auftauchen beim Szenenstart */
.taucht{animation:auftauchen .7s ease both}
@keyframes auftauchen{from{opacity:0}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
}

/* =====================================================================
   DIE DEMO (24.08.26): Schlusskarte, Fragebogen und das Fragezeichen.
   Sichtbar nur im oeffentlichen Bau (DEMO in game.js) bzw. mit
   ?hilfe=1; Logik am Ende von game.js, Texte in T.demo.
   Der Block stand urspruenglich am Dateiende; inzwischen haengt
   Weiteres dahinter. Das ist unschaedlich, weil er nur eigene Namen
   benutzt (f2y-demo, de-, bo-, hf-, hilfe-, neustart-) und mit keiner
   Regel darunter um dieselbe Eigenschaft streitet. Wer hier etwas
   ergaenzt, das einen fremden Namen ueberschreibt, muss den Block
   wieder ans Ende schieben.
   Bausteine aus der Grammatik: Wahl-Kaesten fuer alle Antworten,
   Moewe fuer Gewaehltes. Butter NUR am Abschicken-Knopf, und dort
   erst, wenn eine Antwort dasteht: das ist die Senden-Regel aus
   design.html (Moewe im Ruhezustand, Butter wenn wirklich zu senden
   ist), keine neue Butter-Stelle.
   ===================================================================== */

/* ---------- der Deckel ---------- */
.f2y-demo{position:fixed;inset:0;z-index:600;background:var(--grund);
  overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}
.de-innen{max-width:var(--spalte);margin:0 auto;
  padding:72px 26px calc(72px + env(safe-area-inset-bottom, 0px))}
.de-marke{font-family:var(--s-regie);font-size:var(--barlow);line-height:var(--zeile-barlow);
  letter-spacing:.22em;text-transform:uppercase;color:var(--regie)}
.de-satz{margin:18px 0 0;color:var(--tinte)}
.de-frage{margin-top:44px}
.de-fragtitel{margin:0;color:var(--tinte)}
.de-fragsatz{margin:8px 0 20px;font-family:var(--s-regie);font-size:var(--barlow);
  line-height:var(--zeile-barlow);color:var(--regie)}
.de-zurueck{display:inline-block;margin-top:52px;font-family:var(--s-regie);
  font-size:var(--barlow);letter-spacing:.14em;text-transform:uppercase;
  color:rgb(var(--moewe-rgb) / .6);text-decoration:none}

/* ---------- der Bogen ---------- */
.bo-fragen{margin-top:34px}
.bo-frage{margin:0 0 38px}
.bo-text{margin:0 0 6px;color:var(--tinte)}
.bo-nr{display:inline-block;min-width:1.35em;font-family:var(--s-regie);
  font-size:var(--barlow);color:rgb(var(--moewe-rgb) / .6)}
.bo-zusatz{margin:0 0 12px;font-family:var(--s-regie);font-size:var(--barlow);
  line-height:var(--zeile-barlow);color:var(--regie)}

/* Ja/Nein: zwei Wahl-Kaesten der Grammatik, wie eine Wahl im Spiel */
.bo-janein{display:flex;flex-wrap:wrap;gap:10px;margin-top:14px}
.bo-janein .wahl{animation:none;min-width:96px;text-align:center}

/* Kacheln: BEWUSSTE DESIGN-AUSNAHME (Laura, 24.08.26: "platzsparender
   und deutlich uebersichtlicher"). Lange Antwortlisten stehen als
   kompakte Haken-Liste untereinander, nicht als Wahl-Kaesten: bei
   dreizehn Kaesten war die Frage eine unruhige Wolke. Eine Zeile ist
   rund 40 px hoch und bleibt damit fingertauglich. */
.bo-kacheln{display:flex;flex-direction:column;gap:2px;margin-top:12px}
.bo-kacheln.bo-zweispaltig{display:grid;grid-template-columns:1fr 1fr;gap:2px 14px}
.bo-kachel{display:flex;align-items:center;gap:11px;text-align:left;
  padding:8px 4px;border-radius:8px;
  font-size:calc(var(--hanken) * .87);line-height:1.3;
  color:rgb(236 233 226 / .72);
  transition:color .18s ease, opacity .18s ease}
.bo-kachel .bo-kaest{flex:0 0 auto;width:19px;height:19px;
  display:flex;align-items:center;justify-content:center;
  border:1.5px solid rgb(255 255 255 / .34);border-radius:5px;
  transition:background-color .18s ease, border-color .18s ease}
.bo-kachel .bo-kaest svg{width:13px;height:13px;fill:none;
  stroke:var(--tinte-dunkel);stroke-width:3;
  stroke-linecap:round;stroke-linejoin:round;opacity:0}
.bo-kachel.gewaehlt{color:var(--tinte)}
.bo-kachel.gewaehlt .bo-kaest{background:var(--moewe);border-color:var(--moewe)}
.bo-kachel.gewaehlt .bo-kaest svg{opacity:1}
.bo-kachel.nicht{opacity:.38}
/* genau eine (die Neugier-Frage): runde Kaestchen mit Punkt, die
   Formular-Konvention fuer Einfachwahl */
.bo-kacheln.bo-eine .bo-kaest{border-radius:50%}
.bo-kacheln.bo-eine .bo-kaest svg{display:none}
.bo-kacheln.bo-eine .bo-kaest::after{content:'';width:9px;height:9px;
  border-radius:50%;background:var(--tinte-dunkel);
  opacity:0;transition:opacity .18s ease}
.bo-kacheln.bo-eine .bo-kachel.gewaehlt .bo-kaest::after{opacity:1}

/* der Regler: echtes input[type=range], Spur und Griff in Moewe */
.bo-regler{margin-top:16px}
.bo-rspur{position:relative;height:32px;display:flex;align-items:center}
.bo-rspur input{-webkit-appearance:none;appearance:none;width:100%;height:32px;
  margin:0;background:none;position:relative;z-index:2}
.bo-rspur input::-webkit-slider-runnable-track{height:2px;
  background:rgb(255 255 255 / .22);border-radius:1px}
.bo-rspur input::-moz-range-track{height:2px;
  background:rgb(255 255 255 / .22);border-radius:1px}
.bo-rspur input::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;
  width:22px;height:22px;margin-top:-10px;border-radius:50%;
  background:var(--moewe);border:0}
.bo-rspur input::-moz-range-thumb{width:22px;height:22px;border-radius:50%;
  background:var(--moewe);border:0}
.bo-rasten{position:absolute;left:10px;right:10px;top:50%;height:0;z-index:1;
  display:flex;justify-content:space-between;pointer-events:none}
.bo-rasten i{width:4px;height:4px;border-radius:50%;transform:translateY(-2px);
  background:rgb(255 255 255 / .3)}
.bo-renden{display:flex;justify-content:space-between;margin-top:4px;
  font-family:var(--s-regie);font-size:var(--barlow);color:rgb(var(--moewe-rgb) / .6)}
.bo-rwert{min-height:var(--zeile);margin-top:6px;color:var(--tinte);opacity:0;
  transition:opacity .2s ease}
.bo-regler.beruehrt .bo-rwert{opacity:1}

/* der Freitext */
.bo-freitext{margin-top:14px}
.bo-freitext textarea{width:100%;padding:.6em .75em;resize:vertical;
  background:rgb(255 255 255 / .05);color:var(--tinte);
  font-family:var(--s-lesen);font-size:var(--hanken);line-height:var(--zeile);
  border:1.5px solid rgb(255 255 255 / .18);border-radius:11px;outline:none}
.bo-freitext textarea:focus{border-color:rgb(var(--moewe-rgb) / .55)}
.bo-freitext textarea::placeholder{color:rgb(255 255 255 / .28)}

/* Abschicken: der Senden-Knopf des Bogens. AM 30.08.26 MITGEDREHT, wie
   der Chat-Flieger: dunkel in Ruhe, moewenblau sobald mindestens eine
   Antwort dasteht (.fertig, game.js). Vorher Moewe in Ruhe und Butter
   wenn fertig — das hiesse jetzt, dass der ruhende Knopf so aussieht
   wie der fertige Flieger nebenan.
   Kein gestrichelter Rand: der Bogenknopf ist eine breite Leiste ueber
   die ganze Spalte und nicht zu uebersehen; der Strich ist da, wo ein
   Ding sonst im Grund verschwindet. */
.bo-fuss{margin-top:10px}
.bo-ab{display:block;width:100%;padding:.6em 1em;border-radius:11px;
  background:var(--senden-ruhe);color:var(--senden-ruhe-zeichen);
  transition:background-color .25s ease, color .25s ease, opacity .25s ease}
.bo-ab.fertig{background:var(--moewe);color:var(--tinte-dunkel)}
.bo-ab:disabled{opacity:.4}

/* ---------- das Fragezeichen und der Neustart ---------- */
#hilfe-zugang{position:fixed;z-index:560;
  top:calc(10px + env(safe-area-inset-top, 0px));right:10px;
  width:44px;height:44px;display:flex;align-items:center;justify-content:center;
  color:rgb(var(--moewe-rgb) / .5)}
#hilfe-zugang:hover{color:rgb(var(--moewe-rgb) / .85)}
/* der Neustart links daneben, gleiche Box, gleiche Farbe; das Wort
   haengt als eigene Zeile unter der Box, damit die zwei Symbole exakt
   auf einer Hoehe fluchten */
#neustart-zugang{position:fixed;z-index:560;
  top:calc(10px + env(safe-area-inset-top, 0px));right:56px;
  width:44px;height:44px;display:flex;align-items:center;justify-content:center;
  color:rgb(var(--moewe-rgb) / .5)}
#neustart-zugang:hover{color:rgb(var(--moewe-rgb) / .85)}
#neustart-zugang span{position:absolute;top:100%;left:50%;transform:translateX(-50%);
  margin-top:-3px;font-family:var(--s-regie);font-size:10px;letter-spacing:.14em;
  /* line-height 1: die geerbte Zeilenhoehe liess die Wortbox bis 77px
     reichen und haette den Kopfstreifen (--kopf) breiter erzwungen */
  line-height:1;
  text-transform:uppercase;white-space:nowrap}
#hilfe-schleier{position:fixed;inset:0;z-index:570;background:rgb(0 0 0 / .55);
  opacity:0;pointer-events:none;transition:opacity .25s ease}
#hilfe.offen #hilfe-schleier{opacity:1;pointer-events:auto}
#hilfe-fenster{position:fixed;z-index:575;left:50%;
  top:calc(64px + env(safe-area-inset-top, 0px));
  transform:translateX(-50%) translateY(-8px);
  width:min(330px, calc(100% - 32px));
  background:#16161a;border:1px solid rgb(255 255 255 / .12);border-radius:14px;
  padding:16px 18px 18px;opacity:0;pointer-events:none;
  transition:opacity .25s ease, transform .25s ease}
#hilfe.offen #hilfe-fenster{opacity:1;pointer-events:auto;
  transform:translateX(-50%) translateY(0)}
.hf-kopf{display:flex;align-items:baseline;justify-content:space-between}
.hf-titel{color:var(--tinte)}
.hf-zu{font-size:22px;line-height:1;color:rgb(var(--moewe-rgb) / .6);padding:2px 6px}
.hf-marke{margin-top:12px;font-family:var(--s-regie);font-size:var(--barlow);
  letter-spacing:.14em;text-transform:uppercase;color:rgb(var(--moewe-rgb) / .6)}
.hf-ort{margin-top:6px}
.hf-szene{font-family:var(--s-regie);font-size:var(--barlow);color:var(--regie)}
.hf-zeile{margin-top:4px;color:var(--tinte);font-size:calc(var(--hanken) * .88);
  line-height:1.45;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical}
.hf-melden{display:block;width:100%;margin-top:16px;padding:.55em 1em;
  border-radius:11px;background:var(--moewe);color:var(--tinte-dunkel);
  transition:opacity .25s ease}
.hf-melden:disabled{opacity:.4}
.hf-danach{margin-top:10px;font-family:var(--s-regie);font-size:var(--barlow);
  line-height:var(--zeile-barlow)}
.hf-danach.gut{color:var(--regie)}
.hf-danach.schief{color:#c96a4a}

/* =====================================================================
   QUINN IM FLUR (die Ankunft, zwischen "Tutorial Ende" und dem Stapel;
   Laura, 24.08.26 abends: "jo tun wir so")
   Bild und Blinzeln WOERTLICH aus site/fine-umzug/styles-dark.css
   (.a-flur, Masse vom 19.08.26: Flaeche 320x300, Quinn-Unterkante
   34.4%); neu ist nur der Halter .f2y-flur, der das Bild mittig in
   die Buehne legt (dieses Spiel hat keinen Feed). Sperrbildschirm und
   Riss gehoeren zum Geraet; Zeichnung und Gesetz des Risses stehen in
   design.html (Abschnitt "Der Riss im Display"), die Klasse heisst im
   Spiel .hriss und traegt z-index 420 gegen die Overlay-Staffel, wie
   es dort im Kommentar steht.
   ===================================================================== */
.f2y-flur{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  padding:12px;opacity:0;transition:opacity .9s ease}
.f2y-flur.an{opacity:1}
.f2y-flur .a-flur-kasten{width:min(86vw, 360px);max-width:100%}
.a-flur{position:relative;aspect-ratio:320 / 300}
.a-flur svg{position:absolute;inset:0;width:100%;height:100%;display:block}
/* Unterkante unter der Boxkante: sie guckt ueber sie (Box-Front im
   320x300-Bild: x 70..190, Oberkante y 188) */
.a-flur-quinn{position:absolute;left:27%;width:27%;bottom:34.4%}
.a-flur-quinn img{width:100%;height:auto;display:block}
/* Die Lider liegen im Koordinatensystem von Lauras Datei (viewBox
   424 33 70 58) und decken damit genau ihre Augen. Fellschwarz, kein
   Rand: das Auge ist einfach weg, solange das Lid unten ist. Der
   Doppelschlag liegt am ANFANG des Takts (das erste Zufallen bei
   0,94 s, wenn das Bild fertig aufgeblendet ist); Takt 7,2 s. */
.a-flur-blinzel .a-lid{
  transform-box:fill-box;transform-origin:50% 0;
  transform:scaleY(0);
  animation:quinnBlinzeln 7.2s ease-in-out infinite}
@keyframes quinnBlinzeln{
  0%, 12.5%    {transform:scaleY(0)}
  13.9%, 15.1% {transform:scaleY(1)}
  16.5%, 18.9% {transform:scaleY(0)}
  20.1%, 21.3% {transform:scaleY(1)}
  22.7%, 100%  {transform:scaleY(0)}
}
@media (prefers-reduced-motion: reduce){
  .a-flur-blinzel .a-lid{animation:none}
}

/* Der Sperrbildschirm: Uhr und Datum, sonst nichts. Glatte 2rem und
   nicht 2rem mal --scale: das Panel traegt selbst schon
   zoom calc(var(--scale) * var(--ding)), ein zweites --scale liesse
   die Uhr quadratisch mitwachsen (fine-umzug, woertlich). */
.rsperr{flex:1;min-height:0;display:flex;flex-direction:column;align-items:center;
  padding-top:20%;gap:.5rem}
.rsuhr{font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  font-size:2rem;font-weight:700;letter-spacing:.18em;
  color:#ccc;font-variant-numeric:tabular-nums;line-height:1}
.rsdat{font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  font-size:.82rem;font-weight:400;letter-spacing:.06em;color:#8a8a8a}

/* Der Riss: als letztes Kind im Panel, ueber allem, auch ueber der
   Statusleiste (design.html) */
.hriss{position:absolute;inset:0;pointer-events:none;z-index:420}
.hriss svg{display:block;width:100%;height:100%}

/* =====================================================================
   DER ABEND (Laura, 25.08.26). Drei neue Halter fuer die Szenen hinter
   den Traumglaesern: Quinn auf der Fensterbank, die fressende Quinn in
   der Kueche, die Kartenrolle im Flur. Das grosse Karten-Overlay selbst
   (#ov-karte) ist der woertliche fine-Port und wohnt in geraet.css.
   ===================================================================== */

/* Quinn setzt sich zu den Glaesern (Coda der Traumglaeser): sie sitzt
   HINTER der Glaeser-Zeichnung (erstes Kind, das SVG malt drueber),
   gross wie eine echte Katze neben echten Marmeladenglaesern, die
   Fuesse auf der Banklinie. Masse in % der 340x190-viewBox des
   Traumbilds; die Zeichnung ist 105x155 (quinn-sitzend-aufrecht). */
.tr-quinn{position:absolute;left:62.9%;top:20.8%;width:24%;opacity:0;
  transition:opacity 1.4s ease}
/* 20,8 % ist gerechnet, nicht geschaetzt: die Zeichnung laesst in
   ihrer viewBox (410 31 105 155) unten 10,3 Einheiten Luft (Inhalt
   endet bei y 175,7 von 186). Der sichtbare Po soll auf y 152 der
   Traumbild-viewBox sitzen (die Glaeser enden auf der Banklinie 150):
   top = (152 - 112,5) / 190. Wer die Zeichnung tauscht, misst mit
   getBBox nach.
   62,9 % ist genauso gerechnet (26.08.26, seit die Glaeser kleiner
   sind): links laesst die Zeichnung 10,15 ihrer Einheiten Luft, im
   Bild sind das 7,9. Quinns Fell soll gut zehn Einheiten neben dem
   letzten Glas anfangen, und das steht nach dem Ruecken auf 211,6.
   Sie sass vorher auf 79 % — mit den kleineren Glaesern klaffte
   dazwischen ein halbes Bild leere Bank. */
.tr-quinn.da{opacity:1}
.tr-quinn img{display:block;width:100%;height:auto}
/* DAS BILD TRITT EINEN SCHRITT ZURUECK (26.08.26). Solange die Glaeser
   fuer sich sprechen, fuellen sie das Bild. Wenn alles durch ist und
   Quinn dazukommt, ruecken sie nach links UND werden klein, und die
   Bank wird flacher mit (Laura: "wenn quinn so zu glaesern kommt
   muessen die glaeser kleiner werden, die bank. eine katze ist groesser
   als so ein glas" und "nein die glaeser werden erst klein, wenn die
   katze dazukommt, wenn alles schon durch ist").

   Es ist eine Kamera, die zurueckgeht, keine zweite Zeichnung. Darum
   verkleinert sich ALLES Gezeichnete um denselben Faktor und um
   denselben Punkt: die Standlinie in der Mitte des Kastens, 170 von
   340 und 150 von 190 (= 78,947 %). Die Glaeser stehen dabei auf der
   Stelle, sie werden nur kleiner. Quinn ist die Ausnahme, sie ist ja
   noch gar nicht da: sie kommt gleich in ihrer richtigen Groesse
   herein, und die stimmt erst nach dem Schritt zurueck.

   Die Bank wird nur FLACHER (scaleY), nicht kuerzer: sie laeuft links
   und rechts aus dem Bild, eine Bank hat kein Ende.

   ZWEI SCHREIBWEISEN FUER DIESELBE STRECKE: das SVG rechnet in
   Einheiten seiner viewBox, der Wickel mit den Gluehpunkten ist HTML
   und rechnet in Bildschirm-px. 28 Einheiten sind 8,235 % der 340
   breiten viewBox, und Prozent vom Wickel (er ist so gross wie das
   ganze Bild) sind genau dieselben 8,235 %. Wer eine Zahl aendert,
   aendert beide. */
.traumbild{--tr-klein:.55}
/* der Wickel laesst Klicks durch; die eine Klickflaeche, die sie
   annehmen soll, holt sich das Durchreichen mit .tf-hit.aktiv zurueck */
.traumbild .tr-punkte{position:absolute;inset:0;pointer-events:none}
.traumbild .tr-rutsch{transform-origin:170px 150px}
.traumbild .tr-punkte{transform-origin:50% 78.947%}
.traumbild .tr-bankflaeche{transform-origin:0 150px}
.traumbild .tr-rutsch, .traumbild .tr-punkte, .traumbild .tr-bankflaeche{transition:transform 1.1s ease}
.traumbild.rutsch .tr-rutsch{transform:translateX(-28px) scale(var(--tr-klein))}
.traumbild.rutsch .tr-punkte{transform:translateX(-8.235%) scale(var(--tr-klein))}
.traumbild.rutsch .tr-bankflaeche{transform:scaleY(var(--tr-klein))}
@media (prefers-reduced-motion: reduce){
  .tr-quinn{transition:none}
  .traumbild .tr-rutsch, .traumbild .tr-punkte, .traumbild .tr-bankflaeche{transition:none}
}

/* die Kueche: Quinn am Napf, mittig (dasselbe Muster wie .f2y-flur) */
.f2y-napf{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  padding:12px;opacity:0;transition:opacity .9s ease}
.f2y-napf.an{opacity:1}
.f2y-napf img{display:block;width:min(64vw,260px);height:auto}
@media (prefers-reduced-motion: reduce){ .f2y-napf{transition:none} }

/* Quinn am Morgen: sie steht an der UNTERKANTE der Buehne (Laura,
   26.08.26: "am untern rand vom bildschirm") und faehrt beim Kommen um
   ihre eigene Fusshoehe herauf. Die Buehne schneidet ab, man sieht
   also eine Katze, die ins Bild kommt, und keine, die dasteht.
   Mittig, weil dort das Morgenlicht auf dem Boden liegt.

   SIE STEHT SO TIEF, WIE SIE GANZ INS BILD PASST, und das ist genau
   die Unterkante. Am 26.08.26 stand hier kurz -100px ("quinn 100px
   weiter runter"); davon lagen 100 der 148 px, die die Zeichnung hoch
   ist, unter der Bildkante, und mit ihnen ihr Kopf samt Augen. Lauras
   Befund eine Minute spaeter: "quinn ist abgeschnitten". Wer sie
   nochmal tiefer setzen will, muss sie aus der Buehne herausnehmen
   (die schneidet ab) und ueber den Fluss haengen, wo spaeter die
   Zeilen stehen. Das ist eine Layout-Entscheidung, keine Zahl. */
/* --qrechts ist Lauras Versatz nach rechts (26.08.26: "setz quinn doch
   noch mal 50px weiter rechts"). Er steht im transform und nicht in
   left/right, weil dasselbe transform auch das Hereinfahren traegt;
   zwei Orte fuer eine Bewegung waeren zwei Orte zum Vergessen. */
/* --qgrund ist EINE Zeichnungs-Einheit von Lauras Bogen in Pixeln.
   212 px und 52vw sind ihre Groesse fuer die Streck-Pose (Laura,
   26.08.26: "mach quinn noch 10% kleiner"), und die ist 176 Einheiten
   breit; 212/176 und 52/176 sind also dieselbe Groesse, nur pro
   Einheit gerechnet. Jede andere Zeichnung traegt ihre eigene
   Einheitenzahl und ist damit von selbst gleich gross. Wer Quinn
   groesser oder kleiner will, dreht hier und nirgends sonst.

   Der Halter blendet in derselben Zeit auf wie das Fenster: der Morgen
   wird hell, und sie liegt einfach schon da.

   --qrechts ist Lauras Versatz aus der Mitte nach rechts, in drei
   Schritten gewachsen (26.08.26: erst 50, dann "noch 20px nach
   rechts", dann noch 15). Viel Luft ist da nicht mehr: die gestreckte
   Quinn ist 212 px breit, bei einer 420 px breiten Spalte stoesst ihre
   rechte Kante etwa bei 104 an den Bildrand. Er steht im transform des
   Halters und nicht in left/right, damit die Zentrierung darunter
   unberuehrt bleibt. */
.f2y-qmorgen{--qrechts:85px; --qgrund:min(0.2955vw, 1.2045px);
  position:absolute;left:0;right:0;bottom:0;
  display:flex;align-items:flex-end;justify-content:center;padding:0 12px;
  opacity:0;transform:translateX(var(--qrechts));
  transition:opacity 1.4s ease}
.f2y-qmorgen.an{opacity:1}

/* ---------- DIE ZWEI BILDER (26.08.26). Warum gespiegelt, warum links
   ausgerichtet und warum in Stufen, steht in game.js (Block "QUINN
   WACHT AUF"); hier steht nur, wie es gemacht ist.

   Die gestreckte liegt unten und traegt den Kasten, weil sie die
   groessere ist; die schlafende haengt absolut in ihrer linken unteren
   Ecke. Beide stehen damit auf derselben Bodenlinie, ohne dass jemand
   etwas ausrechnen muss. ---------- */
.f2y-qmorgen .q-lauf{position:relative;display:block}
.f2y-qmorgen .q-wach{display:block;height:auto;
  width:calc(var(--q-wach-b, 176) * var(--qgrund))}
.f2y-qmorgen .q-schlaf{position:absolute;left:0;bottom:0;height:auto;
  width:calc(var(--q-schlaf-b, 127) * var(--qgrund));
  /* GESPIEGELT: Lauras schlafende Katze hat den Kopf rechts, die
     gestreckte links. Ungespiegelt spraenge er mitten in der Blende
     auf die andere Seite. Die Zeichnung selbst bleibt unangetastet. */
  transform:scaleX(-1)}

/* DIE BLENDE LAEUFT IN STUFEN, nicht weich (Laura, 26.08.26: "eine
   Ueberblendung, die Schritt fuer Schritt stattfindet. Schnell genug,
   dass es wie eine Animation aussieht, langsam genug, dass es nicht
   einfach 'n Bildwechsel ist"). Eine weiche Blende sieht aus wie ein
   Trick, ein harter Schnitt wie ein Bildwechsel; ein paar sichtbare
   Stufen sehen aus wie Bewegung.

   --q-schritt kommt als ganze Funktion aus game.js und nicht als blosse
   Zahl: eine var() mitten in steps() ist heikler als eine var(), die
   die ganze Zeitfunktion traegt. */
.f2y-qmorgen .q-wach{opacity:0}
.f2y-qmorgen .q-schlaf{opacity:1}
.f2y-qmorgen.wacht .q-wach,
.f2y-qmorgen.wacht .q-schlaf{
  transition:opacity var(--q-blende, 780ms) var(--q-schritt, steps(6, end))}
.f2y-qmorgen.wacht .q-wach{opacity:1}
.f2y-qmorgen.wacht .q-schlaf{opacity:0}

/* ohne Bewegung ein Schnitt: eine Blende in sechs Stufen IST Bewegung,
   und der Riegel gilt auch fuer kleine. */
.f2y-qmorgen.wach-sofort .q-wach{opacity:1}
.f2y-qmorgen.wach-sofort .q-schlaf{opacity:0}
@media (prefers-reduced-motion: reduce){
  .f2y-qmorgen{transition:none}
  .f2y-qmorgen.wacht .q-wach,
  .f2y-qmorgen.wacht .q-schlaf{transition:none}
}

/* der Flur: Karte und Posterrolle mittig auf der Buehne; die Reihe
   selbst (.kartenrolle) kommt woertlich aus fine (geraet.css) */
.f2y-krolle{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  padding:12px;opacity:0;transition:opacity .9s ease}
.f2y-krolle.an{opacity:1}
@media (prefers-reduced-motion: reduce){ .f2y-krolle{transition:none} }

/* =====================================================================
   DIE DOSE (Kueche, aus Spiel 2 uebernommen). Zwei Zeichnungen liegen
   deckungsgleich uebereinander und blenden um; der Oeffner geht einmal
   nach rechts darueber, die Schnittkante waechst mit ihm.

   Lauras Zeichnung ist schwarzer Strich auf weissem Papier, darum
   dreht filter:invert sie um. brightness(.985) nimmt dem Weiss die
   letzte Haerte, damit die Linien nicht ueber dem Buehnengrund
   flimmern (Wert aus Spiel 2, FutterCard.module.css).
   ===================================================================== */
.f2y-dose{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  padding:12px;opacity:0;transition:opacity .9s ease}
.f2y-dose.an{opacity:1}
.d-platz{position:relative;display:block;width:min(38vw,150px)}
.d-bild{display:block;width:100%;height:auto;filter:invert(1) brightness(.985);
  transition:opacity .42s ease}
.d-platz .d-auf{position:absolute;left:0;top:0;opacity:0}
.d-platz .d-auf.da{opacity:1}
.d-bild.weg{opacity:0}

/* die Schnittkante, die der Oeffner hinter sich laesst: sie liegt auf
   dem Deckelrand und reicht genau so weit, wie er gekommen ist */
.d-schnitt{position:absolute;left:9%;top:9.5%;width:calc(82% * var(--anteil,0));height:2px;
  background:#e8e8e8;opacity:calc(var(--anteil,0) * .9);pointer-events:none;z-index:3;
  transform:rotate(-1.5deg);transform-origin:left center}

/* der Oeffner: Kurbel und Klinge, wie drueben. Er sitzt links am
   Deckelrand und folgt dem Finger nach rechts, dabei kippt er leicht. */
.d-oeffner{position:absolute;left:-6%;top:-2%;width:44px;height:44px;padding:0;margin:0;
  background:none;border:0;cursor:grab;touch-action:none;z-index:4;
  transform:translateX(var(--dx,0px)) rotate(calc(var(--anteil,0) * -8deg));
  transition:transform .18s ease}
.d-oeffner.zieht{transition:none;cursor:grabbing}
.d-oeffner.weg{opacity:0;transition:opacity .42s ease}
.d-kurbel{position:absolute;top:12px;left:50%;width:22px;height:9px;margin-left:-11px;
  border:2px solid #e8e8e8;border-radius:2px;background:var(--buehne,#0e0e10)}
.d-klinge{position:absolute;top:21px;left:50%;width:3px;height:12px;margin-left:-1.5px;
  background:#e8e8e8}
/* Die Einladung ist die WISCHGESTE der Grammatik (design.html, Baustein 3):
   der Klecks setzt an, zieht sanft in die Richtung, verblasst, faengt von
   vorn an. Ein Weg, kein Hin und Her. Masse und Kurve woertlich von dort
   (29 px, 2,9 s, dieselbe Beschleunigung); gespiegelt ist nur die Richtung,
   weil der Oeffner nach rechts geht und die Geste dorthin zeigen muss, wo
   der Daumen hin soll. */
.d-zug{position:absolute;left:-6%;top:-2%;width:44px;height:44px;z-index:5;
  display:flex;align-items:center;justify-content:center;--kl:48px;
  pointer-events:none;transition:opacity .25s}
.d-zug .klecks{animation:klecks-zieht-rechts 2.9s cubic-bezier(.35,0,.3,1) infinite}
/* Weg (66 px), Zeitpunkte und Deckkraft sind die des Bausteins; nur der
   Nullpunkt liegt hier auf dem Oeffner statt links davor, damit die Geste
   dort ansetzt, wo der Daumen hinfasst, und nicht neben der Dose beginnt. */
@keyframes klecks-zieht-rechts{
  0%{transform:translateX(0);opacity:0}
  16%{transform:translateX(6px);opacity:.9}
  74%{transform:translateX(50px);opacity:.9}
  100%{transform:translateX(66px);opacity:0}}
.d-zug.still{opacity:0}
@media (prefers-reduced-motion: reduce){
  .f2y-dose{transition:none}
  .d-bild{transition:none}
  .d-oeffner{transition:none}
  .d-zug .klecks{animation:none}
}


/* am Wal der Nacht (Laura, 25.08.26: die Zuggeste der Grammatik "bei
   JEDEM Zug, nicht nur beim ersten", und WOERTLICH aus design.html
   genommen): Halter und Kurve sind Baustein 3 (.w-zug und
   klecks-zieht, dieselben Werte, dieselbe Zeit, dasselbe Easing),
   nur die Achse ist auf die Zugrichtung des Auffaltens gedreht,
   nach unten. Er weicht bei Beruehrung und kommt nach dem Loslassen
   wieder; game.js haengt ihn vor jedem Zug frisch an (walZug). */
.wal-zug{position:absolute;left:50%;top:36%;margin-left:calc(var(--kl) / -2);
  z-index:4;--kl:48px;pointer-events:none;transition:opacity .25s}
.wal-zug.still{opacity:0}
.wal-zug .klecks{animation:klecks-zieht-runter 2.9s cubic-bezier(.35,0,.3,1) infinite}
@keyframes klecks-zieht-runter{
  0%{transform:translateY(-26px);opacity:0}
  16%{transform:translateY(-20px);opacity:.9}
  74%{transform:translateY(24px);opacity:.9}
  100%{transform:translateY(40px);opacity:0}}
@media (prefers-reduced-motion: reduce){ .wal-zug .klecks{animation:none} }


/* =====================================================================
   DIE NACHTTISCHLAMPE (Laura, 25.08.26 spaetabends). Sie steht mittig
   auf der Buehne, brennt, und der Spieler legt den Schalter um. Die
   Zeichnung baut ikonen.js (nachttischlampeSVG) in EINEM Stueck; an
   und aus sind hier nur Farbe und Licht, damit der Schalter sich
   bewegen kann statt dass ein Bild gegen ein anderes getauscht wird.

   DER KNOPF GEHT WIRKLICH RUNTER (Lauras Ansage im selben Atemzug).
   Der Schalter ist auf der Zeichnung 5,5 Einheiten hoch und steht auf
   dem Fuss; gedrueckt wird er zusammengestaucht, nicht verschoben:
   sein Fusspunkt (y = 121,8) bleibt, der Deckel faellt um rund 2,7
   Einheiten in den Fuss hinein. Der Drehpunkt steht ausdruecklich da
   (siehe unten), sonst rechnet der Browser vom Mittelpunkt des
   Kastens aus und der Schalter wandert quer durchs Bild.

   DIE FLAECHE ZUM DRUECKEN IST EIN EIGENER KNOPF, nicht der gezeichnete
   Deckel: der ist am Handy keine 12 px breit, und mit dem Daumen
   trifft ihn niemand. Der Knopf liegt unsichtbar darueber und ist 56
   gross (Hausmass fuers Handy); er sitzt auf den Anteilen, an denen
   der Deckel in der Zeichnung steht (42,5 von 140 und 116,3 von
   136,8). Wer die Zeichnung aendert, zieht die zwei Prozentzahlen mit.
   ===================================================================== */
.f2y-lampe{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;padding:12px;opacity:0;transition:opacity .9s ease}
.f2y-lampe.an{opacity:1}
.ntl{position:relative;width:min(64vw,260px);
  color:var(--tinte);transition:color .55s ease}
/* DER KEGEL DARF UEBERSTEHEN (Laura, 26.08.26: er soll breiter werden).
   Ein SVG schneidet von Haus aus an seinem Kasten ab; der weite Keil
   endet aber bei 149 von 140, weil der Kasten absichtlich auf der
   Fassung vom 25.08. festgehalten ist (an ihm haengen der Drehpunkt des
   Schalters und die zwei Prozente des Griffs, siehe unten). Ohne diese
   Zeile stuende rechts eine gerade Kante im Licht. Sonst steht nichts
   ausserhalb des Kastens: die Lampe selbst ist mit einer halben
   Strichbreite Rand hineingerechnet. */
.ntl-bild{display:block;width:100%;height:auto;overflow:visible}
/* der Koerper ist in beiden Fassungen mit dem Grund gefuellt: die
   Lampe ist ein Strich, kein Scherenschnitt, und was hinter ihr liegt,
   soll nicht durch sie hindurchscheinen */
.ntl-koerper{fill:var(--grund)}
.ntl-mundflaeche{fill:var(--akz);fill-opacity:.5;
  transition:fill .55s ease, fill-opacity .55s ease}
.ntl-birne{fill:var(--akz);transition:fill .55s ease}
.ntl-licht{opacity:1;transition:opacity .7s ease}
.ntl-halo{transition:opacity .7s ease}

/* aus: der Strich faellt auf Moewe halbwegs zum Grund, das Licht geht */
.ntl.aus{color:#5c6267}
.ntl.aus .ntl-mundflaeche{fill:var(--grund);fill-opacity:1}
.ntl.aus .ntl-birne{fill:var(--grund)}
.ntl.aus .ntl-licht,
.ntl.aus .ntl-halo{opacity:0}

/* ETWAS RUFT, ABER ERST NACH SECHS SEKUNDEN (Laura, 25.08.26
   spaetabends: "der schalter bekommt dann ETWAS RUFT ... damit macht er
   auf sich aufmerksam", und gleich darauf: "wenn man den als spieler
   nach 6 sekunden nicht findet, darf der ein mal wackeln. und nach 6s
   wieder"). Baustein 5 der Bibel, auf ihre Zeit gestellt.

   DER STUPS STEHT ALLEIN. Baustein 5 ist Stups PLUS leises Atmen, hier
   ist es nur der Stups: "wenn man ihn nicht findet" heisst, dass er
   vorher nichts tut, und etwas, das die ganze Zeit atmet, ruft die
   ganze Zeit. Sechs Sekunden Stille, ein Wackeln, sechs Sekunden
   Stille. Sonst nichts: kein Leuchtkranz, keine Flaeche, keine zweite
   Farbe, kein Klecks; Butter gehoert ohnehin nur Weiter, Senden und
   Ungelesen.

   DIE UHR STEHT IN game.js, nicht hier: eine CSS-Animation kann ihre
   Pause nur VOR dem ersten Durchgang halten, nicht zwischen den
   Durchgaengen. Sechs Sekunden Pause und dann alle sechs Sekunden
   wieder waere hier nur als ein 6,74-Sekunden-Takt zu haben, und das
   sind nicht ihre sechs. Der Stups selbst ist woertlich der der Bibel,
   nur aus seinem 4,6-Sekunden-Rad herausgeloest: dieselben drei
   Winkel, dieselbe Reihenfolge, dieselbe Dauer (0,74 s).

   ZWEI HALTER, weil sich drei Transformationen sonst gegenseitig
   ueberschreiben: aussen der Druck, innen der Stups.

   DER DREHPUNKT MUSS DASTEHEN. Ein SVG rechnet transform-origin ohne
   Angabe von der Mitte des KASTENS aus, nicht von der Mitte des Dings:
   der Schalter sitzt bei 42,5 / 121,8 in einem Kasten von 140 x 136,8,
   und ohne die zwei Zahlen unten wandert er beim Atmen quer durchs
   Bild, statt zu atmen. Beide Halter drehen und stauchen um seinen
   Fusspunkt: da steht er auf, da kippt er, da wird er eingedrueckt. */
.ntl-schalter,
.ntl-schalterkopf{transform-origin:42.5px 121.8px}
.ntl-schalterkopf.wackelt{animation:ntl-wackelt .74s ease-in-out}
@keyframes ntl-wackelt{
  0%{transform:rotate(0)}
  25%{transform:rotate(-2.6deg)}
  50%{transform:rotate(1.7deg)}
  75%{transform:rotate(-.5deg)}
  100%{transform:rotate(0)}}

/* gedrueckt: der Fusspunkt bleibt, der Deckel faellt um die halbe
   Hoehe in den Fuss hinein. Das Ausmass ist die 0,5. */
.ntl-schalter{transition:transform .13s cubic-bezier(.3,.7,.4,1)}
.ntl.gedrueckt .ntl-schalter{transform:scaleY(.5)}
.ntl.gedrueckt .ntl-schalterkopf{animation:none}

.ntl-griff{position:absolute;left:30.4%;top:86.9%;
  transform:translate(-50%,-50%);
  width:56px;height:56px;padding:0;border:0;border-radius:50%;
  background:none;cursor:pointer;-webkit-tap-highlight-color:transparent}
.ntl-griff:focus-visible{outline:2px solid var(--moewe);outline-offset:2px}
.ntl-griff[disabled]{cursor:default}

@media (prefers-reduced-motion: reduce){
  .f2y-lampe{transition:none}
  .ntl-schalterkopf.wackelt{animation:none}
}

/* =====================================================================
   DER KREISEL: DIE NACHTGEDANKEN (Laura, 26.08.26)
   Der ganze Text der Nacht liegt als eine Zeile auf einer Spirale und
   wandert nach innen; einzelne Fetzen richten sich daraus auf. Die
   Regie steht in game.js (nachtGedanken), hier nur die Gestalt.
   Entworfen in proben/probe-nachtkreisel.html.

   DREI EBENEN, und die Reihenfolge ist der ganze Trick:
     .nk-dreh/.nk-worte  der Kreisel selbst
     .nk-loch            der Deckel aus Grundfarbe ueber der Mitte
     .nk-vorn            der Satz, der gerade gelesen wird
   Der Deckel liegt ueber dem Kreisel, aber UNTER dem Satz (Lauras
   Befund: "die Schrift ist unter dem Schatten in der Mitte, dadurch
   kann man viele Saetze nicht lesen"). Wer die Reihenfolge im Markup
   dreht, nimmt der Szene ihre Lesbarkeit.
   ===================================================================== */
.f2y-kreisel{position:fixed;inset:0;z-index:600;background:#000;
  opacity:0;transition:opacity .8s ease}
.f2y-kreisel.an{opacity:1}
.f2y-kreisel .nk-svg{position:absolute;inset:0;width:100%;height:100%;display:block}

/* SIE DENKT IN IHRER EIGENEN HANDSCHRIFT (Laura, 26.08.26). Patrick
   Hand ist Fines Schrift, und die Nacht ist ihr Kopf. */
.f2y-kreisel .nk-svg text{font-family:'Patrick Hand',cursive;fill:var(--tinte);
  text-rendering:optimizeSpeed}
/* FARBE TRAEGT NUR FABIS BRIEF. Alles andere in der Nacht sieht aus
   wie alles andere, und genau darin liegt der Schrecken.
   Der Selektor nennt text mit: die Grundregel darueber ist
   .f2y-kreisel .nk-svg text und schlaegt sonst die Klasse. */
.f2y-kreisel .nk-svg text.nk-brief{fill:var(--walblau)}
.f2y-kreisel .nk-svg use{color:rgb(236 233 226 / .82)}
/* jedes Wort kann einzeln auftauchen (die Spirale fuellt sich am
   Anfang von innen nach aussen) */
.f2y-kreisel .nk-svg text,
.f2y-kreisel .nk-svg use{transition:opacity .8s ease}

/* WER LIEST, LIEST NUR EINEN SATZ: solange sich einer aufrichtet, geht
   der Rest des Kreisels zurueck. Sonst steht die gerade Zeile zwischen
   lauter grossen Woertern und ist genau dann nicht zu lesen, wenn sie
   es sein soll. */
.f2y-kreisel .nk-worte{transition:opacity .55s ease}
.f2y-kreisel.liest .nk-worte{opacity:.42}

/* der Schluss: der Kreisel geht aus, Quinns Satz bleibt */
.f2y-kreisel .nk-dreh,
.f2y-kreisel .nk-vorn,
.f2y-kreisel .nk-loch{transition:opacity 1.4s ease}
.f2y-kreisel.aus .nk-dreh,
.f2y-kreisel.aus .nk-vorn,
.f2y-kreisel.aus .nk-loch{opacity:0}

/* QUINNS SATZ IST KEIN GEDANKE (Laura, 26.08.26: er ist der einzige
   Satz der Nacht, der im JETZT passiert). Er wird nicht gedacht, er
   wird gespuert, darum steht er still, allein und in der Leseschrift
   des Spiels. */
.f2y-kreisel .nk-schluss{position:absolute;left:50%;top:44%;transform:translate(-50%,-50%);
  width:74%;text-align:center;font-family:var(--s-lesen);
  font-size:clamp(17px,4.8vw,21px);line-height:1.45;color:var(--tinte);
  opacity:0;transition:opacity 1.8s ease 1s;pointer-events:none}
.f2y-kreisel.aus .nk-schluss{opacity:1}

/* derselbe Fuss wie auf jedem Bildschirm. KEIN BILDSCHIRM OHNE
   SICHTBAREN WEG WEITER: der Klecks geht nie ganz aus, er wird nur
   leiser, solange kein Satz auf den Daumen wartet. */
.f2y-kreisel .st-fuss{position:absolute;left:0;right:0;bottom:0;display:flex;z-index:3;
  height:calc(var(--knopf-mitte) * 2 + env(safe-area-inset-bottom,0px));
  align-items:center;justify-content:center;
  padding-bottom:env(safe-area-inset-bottom,0px)}
.f2y-kreisel .knopf-weiter{opacity:1;transition:opacity .55s ease}
.f2y-kreisel .knopf-weiter.still{opacity:.26}

@media (prefers-reduced-motion: reduce){
  .f2y-kreisel,
  .f2y-kreisel .nk-worte,
  .f2y-kreisel .nk-svg text,
  .f2y-kreisel .nk-svg use{transition:none}
}

/* =====================================================================
   DIE NACHT MIT DER TASCHENLAMPE (25.08.26). Die fine-Bausteine
   (Kegel, Dunkelraum, Funken, Bon, Foto-Geraet) stehen woertlich am
   Ende von geraet.css; hier stehen die Uebersetzungen in diese
   Grammatik und die Szenen-Korrekturen, die bei gleicher Spezifitaet
   gewinnen muessen (styles.css laedt nach geraet.css).
   ===================================================================== */

/* der Buehnen-Halter der Nacht: mittig, eine Spalte (erst die Uhr,
   dann der Wal, dann Raetsel und Kamera; es steht immer nur ein Ding
   im Bild, wie ueberall in diesem Spiel) */
.f2y-nacht{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:.6rem}

/* die Uhr des Aufwachens: Systemschrift wie auf einem Geraet, nicht
   die Spielschrift (fine) */
.nacht-uhr{font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:.18em;
  font-size:2.4rem;color:#ccc;opacity:0;transition:opacity .9s ease}
.nacht-uhr.da{opacity:1}
@media (prefers-reduced-motion: reduce){ .nacht-uhr{transition:none} }

/* der Wal in der Buehne: fines Einzeiler-Masse (dort px mal --scale
   1 am Handy). geraet.css traegt fines Rechner-Rueckfall mit --scale
   1.33, der hier zu gross waere; die zwei IDs gewinnen. Die Hoehen
   sind Anteile des Halters, damit der offene Bogen nie aus der
   Buehne waechst. */
#buehne .f2y-nacht .bogenhalter{width:100%;flex:0 1 auto;min-height:0}
#buehne .f2y-nacht #walbogen{width:min(190px,56vw);height:min(130px,32vh)}
#buehne .f2y-nacht #walbogen.offen1{width:min(250px,72vw);height:min(210px,36vh)}
#buehne .f2y-nacht #walbogen.offen2{width:min(300px,84vw);height:min(300px,40vh)}
#buehne .f2y-nacht #walbogen.offen3{width:min(340px,90vw);height:min(360px,44vh)}

/* Rueckfall, falls der Bogen-Renderer ausfaellt: die Blackbox bleibt
   sichtbar und spielbar (fine) */
.f2y-nacht .blackbox{display:flex;align-items:center;justify-content:center;
  border:1px dashed #444;color:#8a8a8a;letter-spacing:.2em;
  font-size:calc(var(--barlow) * .72);font-family:var(--s-regie)}
.f2y-nacht .blackbox.als-svg{border-color:transparent;color:transparent}

/* das Bonrätsel liegt im Halter und darf die Buehne fuellen; die
   Meldungen sprechen Regie. Faellt die Buehne zu kurz aus (nur nackte
   Testfenster ohne Rahmen), scrollt das Raetsel in sich. */
.f2y-nacht .bonraetsel{width:min(92vw,340px);align-self:center;max-height:100%;overflow-y:auto}
/* Lauras Ansagen (25.08.26): die Schlitz-Beschriftung und die
   Streifenschrift je eine Stufe groesser als fines Masse (dort .62
   und .72 rem), und KOPF, ORT usw. in hellem Weiss statt fines
   dunklem Grau (die Tinte des Spiels, kein reines #fff) */
.slothint{font-size:calc(.74rem * var(--ding));color:var(--tinte)}
.bonstreifen{font-size:calc(.84rem * var(--ding))}
/* UND EIN DECKEL FUER KURZE BILDSCHIRME (26.08.26). Das Raetsel ist
   zehn Kaesten hoch: fuenf Schlitze, fuenf Streifen. Mit den Abstaenden
   dazwischen sind das 10 mal Kastenhoehe plus 94 px. Darueber und
   darunter liegen der Kopfstreifen (66), die Regie-Zeile (56) und der
   Fussrand, den sich das Raetsel oben gelassen hat (48), zusammen
   170. Fuer EINEN Kasten bleibt also (Bildschirm minus 264) durch 10.
   Ab 624 px Bildschirmhoehe kommt dabei mehr als fines Mass heraus,
   und es gilt wieder 36 px; darunter werden die Kaesten flacher, statt
   dass das Raetsel unten abreisst. 22 px ist die Grenze, unter der die
   Streifenschrift nicht mehr sitzt.
   Schlitz und Streifen MUESSEN dieselbe Zahl bekommen, sonst passt der
   Streifen nicht mehr in den Schlitz. */
.f2y-nacht .bonslot,
.f2y-nacht .bonstreifen{
  height:max(22px, min(calc(36px * var(--ding)),
             calc((100svh - env(safe-area-inset-top,0px) - 264px) / 10)))}
/* UND DER STREIFEN FUELLT SEINEN SCHLITZ (26.08.26). Er ist
   min(270px, 90%) breit; im Vorrat sind die 90 % die volle Spalte, im
   Schlitz aber 90 % von dessen 270 px. Eingerastet sass er dadurch
   27 px zu schmal und linksbuendig in einem Rahmen, der rechts
   herausschaute. Sichtbar wird das erst, wenn der Bon fertig liegt. */
.f2y-nacht .bonslot .bonstreifen{width:100%}
.bonmeldung{min-height:1.3em;text-align:center;color:var(--regie);
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .82);letter-spacing:.14em}

/* Kamera und Ritual (Ausloeser, Kurbel) stehen mittig */
.nacht-kamera{text-align:center;touch-action:none;cursor:pointer}
.nacht-ritual{display:flex;flex-direction:column;align-items:center}

/* WAEHREND DIE LAMPE BRENNT: der Fuss (Klecks und Wahlkaesten) liegt
   UEBER dem Nachtschleier. KEIN BILDSCHIRM OHNE SICHTBAREN WEG WEITER
   gilt auch nachts; die Zeile darueber bleibt bewusst im Dunkeln und
   will geleuchtet werden (Lauras Einzeiler-Gesetz aus fine: nicht
   automatisch beleuchtet). #kegel liegt auf 300, die Zettel auf 420. */
body.dunkel .fuss{z-index:365}

/* und der Finger fuehrt nur noch das Licht: solange die Lampe brennt,
   scrollt und zieht am Spielfeld nichts (fines Lehre vom iPhone; die
   Wahl-Kaesten und der Klecks sind Taps und bleiben davon unberuehrt) */
@media (pointer:coarse){
  body.dunkel .spiel{touch-action:none}
}

/* die eine Zeile im Foto-Geraet: unten auf dem Bild, ueber dem
   Ausloeser-Platz. Halo kommt vom Geraet (text-shadow erbt). */
.fgzeilen{position:absolute;left:1.15rem;right:1.15rem;z-index:4;
  /* ueber dem Weiter-Klecks der Szene (Lauras Befund 25.08.26: der
     Klecks lief durch den Text). Klecks-Oberkante = --knopf-mitte plus
     halber Knopf 38px; darueber ein Polster von 14. Die Zeile rechnet
     aus der Variable und faellt darum am 27.08.26 mit dem Knopf um
     15 px mit. Vorher bottom:5.6rem, das kollidierte. */
  bottom:calc(var(--knopf-mitte) + 52px + env(safe-area-inset-bottom, 0px));
  display:flex;flex-direction:column;gap:.45rem;pointer-events:none}
/* steht der Ausloeser im Geraet, rutscht die Zeile ueber seinen
   Sockel (Lauras Befund 25.08.26: die Regie-Zeile lief mitten durch
   den Knopf). 10rem = Knopf 84px + Beschriftung + Sockel-Polster.
   Die Klasse setzt ausloeser() in game.js. Bewusst OHNE transition
   auf bottom: die fror im versteckten Tab ein und taeuschte beim
   Messen einen toten Selektor vor. */
.fginnen.mitausloeser .fgzeilen{bottom:calc(10rem + env(safe-area-inset-bottom, 0px))}

/* =====================================================================
   DER AUSLOESER IST KURZ DER WEITER-KNOPF (Laura, 27.08.26)

   Erst die Lage. Das Foto-Geraet ist Vollbild und rechnet seinen Boden
   aus sich selbst, nicht aus dem Fuss der Szene. Sein Ausloeser sass
   darum immer schon im Weiter-Knopf: gemessen am 27.08.26 lag der 84er
   Knopf auf 60 bis 144 px ueber dem Rand und seine Beschriftung auf
   26 bis 52, waehrend die Tastflaeche des Weiter-Knopfes 32 bis 108
   belegt. Die Beschriftung lag also VOLLSTAENDIG im Weiter-Knopf.
   Lauras erste Ansage war, beides nach oben zu raeumen. Ihre zweite
   war besser: "der ausloeserknopf ist ja quasi kurzzeitig der
   weiterknopf. koennte man das so umgehen?"

   ALSO WEICHT ER NICHT AUS, ER UEBERNIMMT. Der Ausloeser setzt sich
   mit seiner MITTE auf --knopf-mitte, genau dorthin, wo in jeder
   anderen Szene der Klecks sitzt. Es steht damit nie zweierlei an
   derselben Stelle: solange der Ausloeser da ist, ist der Klecks still
   (knopfAn(false)), und danach uebernimmt der Klecks den Platz zurueck.
   Der Daumen muss nicht umlernen, und das Gesetz "kein Bildschirm ohne
   sichtbaren Weg weiter" ist erfuellt, weil der Ausloeser der Weg
   weiter IST.

   DIE BESCHRIFTUNG WANDERT NACH OBEN. Unter der Knopfmitte bleiben nur
   noch 28 px, dort passt kein Wort mehr hin; column-reverse dreht die
   zwei Kinder, ohne dass game.js etwas davon wissen muss. Sie steht
   damit ueber dem Knopf statt darunter.

   ZWEI ZAHLEN, BEIDE GERECHNET. Der Sockel ist --knopf-mitte minus die
   halbe Knopfhoehe (84 / 2 = 42), also 28. Der Block darueber ist
   84 + 8 (gap .5rem) + 26 (Beschriftung) = 118 hoch und endet bei 146;
   die Regie-Zeile im Ausloeser-Zustand steht auf ihren 10rem (160) und
   behaelt damit ihre 14 px Luft. Sie muss nicht angefasst werden.
   Faellt der Knopf noch einmal, faellt der Ausloeser von selbst mit.

   NUR AM HANDY (Hausregel: Handy-Fixes bleiben am Handy). Ueber 700 px
   ist das Geraet ein schwebendes Panel und sein Boden nicht der
   Bildschirmboden; dort gibt es den Konflikt nicht, und die Zahlen aus
   geraet.css bleiben stehen.

   DIE KAI-GRIFFE FOLGEN SEIT DEM 28.08.26 DERSELBEN REGEL: ihr
   .k-ritual haengt jetzt im Fuss auf --knopf-mitte (Regel weiter oben
   bei .fuss .k-ritual), nicht mehr unten rechts an der Buehne. Nur
   .nacht-ritual laeuft weiter im Fluss der Nachtbuehne mit.
   ===================================================================== */
@media (max-width:700px){
  #fotogeraet .fginnen > .ausloeserbox{
    flex-direction:column-reverse;
    padding-bottom:calc(var(--knopf-mitte) - 42px + env(safe-area-inset-bottom, 0px))}
}
.fgz{margin:0;font-family:var(--s-lesen);font-size:var(--hanken);line-height:var(--zeile);
  color:var(--tinte);opacity:0;transform:translateY(6px);
  transition:opacity .45s ease,transform .45s ease}
.fgz.da{opacity:1;transform:none}
.fgz.weg{opacity:0;transition:opacity .25s ease}
/* Regie ist Moewenblau, sonst keine (design.html; das fine-Grau
   #b4b4b4 ist raus, Laura 25.08.26) */
.fgz.regie{font-family:var(--s-regie);font-size:var(--barlow);line-height:var(--zeile-barlow);
  color:var(--regie);letter-spacing:.14em}
.fgz.gedanke{color:#bcbcbc;font-style:italic}
.fgz.leise{font-size:calc(var(--hanken) * .82);color:#a8a8a8}
@media (prefers-reduced-motion: reduce){ .fgz{transition:none;transform:none} }

/* =====================================================================
   SCHRIFT- UND FARB-ANGLEICH DER PORTS (Laura, 25.08.26, beim
   Regel-Audit). geraet.css ist ein maschineller fine-Auszug und wird
   nicht von Hand gepflegt; was dort gegen die Grammatik spricht, wird
   HIER ueberschrieben (styles.css laedt nach geraet.css und gewinnt
   bei gleicher Spezifitaet).
     · Patrick Hand IST FINES HANDSCHRIFT (Lauras Festlegung am Abend
       des 25.08.26, festgehalten in design.html). Der Audit-Stand vom
       Vormittag, nach dem die Stadtkarten Caveat sprechen sollten,
       ist damit zurueckgedreht: die Zettel der Norddeutschlandkarte
       stehen wieder in Patrick Hand ("es sollte patricks hand haben
       ja. die zettel"), genau wie die NACHT-ZETTEL ("das sind Fines
       Zettel"). Beide Regeln liegen in geraet.css, hier steht kein
       Override mehr.
     · IBM Plex Mono "darf nicht sein": die Grabungs-Namenszeile steht
       in der Regie-Schrift, die Bonstreifen in der Leseschrift
       (Lauras Korrektur, 25.08.26: "die bonstreifen kriegen gill
       sans"; die Leseschrift hiess damals so). Nur die Werkbank
       (rahmen.html, Testmarken) behaelt ihr Mono, sie ist kein Spiel
       — seit dem 27.08.26 aber das des Systems: Laura hat die Schrift
       selbst gestrichen ("ibm plex ist raus"). Die Rolle bleibt Mono,
       gesetzt wird ui-monospace,SFMono-Regular,Menlo,monospace; was
       nicht Spiel ist, ist Systemschrift, und System-Mono IST eine.
     · Die Dreh-Anweisung der Karte sprach fine-Grau #b4b4b4; Regie
       ist Moewenblau, sonst keine. Die leisere Rechner-Zeile
       darunter bleibt bewusst leiser.

   ZWEI OVERRIDES SIND AM 25.08.26 WIEDER RAUS. Sie zielten auf
   Markup, das dieses Spiel nie baut:
     · #handy-panel:has(.w-liste) .panelkopf.app > span
       .w-liste gibt es hier nicht; das Spiel baut nur
       .panelkopf.a-kopf (geraet.js, chatkopf).
     · .inv-ding .objektlabel
       das Inventar ist eine fine-Sache, .inv-ding wird nie gebaut.
   Beide Male war auch die Mono-Regel dahinter (geraet.css) tot, es
   entsteht also keine Luecke. Der Fehler kam daher, dass der Audit
   geraet.css gelesen hat statt das, was im Spiel auf dem Schirm
   landet. Wer hier einen Override ergaenzt, prueft zuerst mit grep,
   ob game.js die Marke ueberhaupt vergibt.
   ===================================================================== */
.bonstreifen{font-family:var(--s-lesen)}
.knamenzeile{font-family:var(--s-regie)}
#ov-karte.handy .kd-wort{color:var(--regie)}

/* =====================================================================
   DIE ZEILE ZUM DREH-SCHALTER (26.08.26). Sie steht am Handy unter der
   Anweisung, an derselben Stelle, an der im Rahmen die Rechner-Zeile
   steht, und sieht auch aus wie sie: dasselbe Regie-Register, kleiner
   und dunkler als die Anweisung. Die Anweisung bleibt die Ansage, das
   hier ist der Hinweis fuer den, bei dem sie nichts bewirkt.
   line-height steht hier, weil die Zeile laenger ist als die
   Rechner-Zeile und am schmalen Handy umbricht; ohne sie klebten die
   zwei Zeilen aneinander.
   ===================================================================== */
#ov-karte.handy .kd-sperre{
  font-family:var(--s-regie); font-size:calc(var(--barlow) * .62); letter-spacing:.14em;
  text-transform:uppercase; color:#6f6f6f; margin-top:-10px; line-height:1.55}

/* =====================================================================
   DAS ROUTENRAETSEL (28.08.26): Lauras neue Radfahrt, als Overlay wie
   die Karte im Flur — quer gespielt, hochkant steht die Dreh-Anweisung
   (dieselbe Zeichnung und Animation wie an der Karte, geraet.css:
   kdHandyDrehen/kdHandyZurueck sind globale Keyframes). Die Buehne ist
   ein Canvas; Zettel, Klick-Zaehler und Regie-Zeile liegen darueber.
   ===================================================================== */
#ov-rad{position:fixed;inset:0;background:var(--grund);z-index:720;
  opacity:0;transition:opacity .5s ease}
#ov-rad.an{opacity:1}
#ov-rad canvas{display:block;width:100%;height:100%}
#ov-rad .rr-klicks{position:absolute;left:0;right:0;top:10px;text-align:center;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .8);
  letter-spacing:.2em;color:var(--tinte);text-transform:uppercase}
#ov-rad .rr-zeile{position:absolute;left:16px;right:16px;
  bottom:max(12px, env(safe-area-inset-bottom));text-align:center;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .8);
  letter-spacing:.14em;color:var(--regie);text-transform:uppercase;line-height:1.9}
/* WAEHREND SIE DENKT (29.08.26, Fahrtwind der Heimfahrt): Gedanken
   sind Lesetext, keine Regie — die Zeile wechselt Schrift und Farbe,
   solange die k2s7-Gedanken durchziehen (game.js setzt .denkt). */
#ov-rad .rr-zeile.denkt{font-family:var(--s-lesen);
  font-size:calc(var(--hanken) * .8);letter-spacing:0;
  color:var(--tinte);text-transform:none;line-height:1.6}
/* der Startzettel: ihre Handschrift, leicht schief — die Bauart der
   To-Do-Liste (f2y-todo), nur als Anschlag mitten im Bild */
#ov-rad .rr-zettel{position:absolute;left:50%;top:50%;width:min(400px,78%);
  transform:translate(-50%,-50%) rotate(-1.6deg);
  background:#f6f1e5;color:#1f1d1a;border-radius:3px;
  box-shadow:0 10px 40px rgb(0 0 0 / .5);
  font-family:var(--s-fine);font-size:calc(1.3rem * var(--ts));line-height:1.5;
  padding:24px 30px;text-align:center;cursor:pointer;
  transition:opacity .45s ease;z-index:4}
#ov-rad .rr-zettel.weg{opacity:0;pointer-events:none}
/* hochkant steht die Dreh-Anweisung; nach der Szene, noch quer, die
   Rueckdreh-Anweisung (.zurueck) */
#ov-rad .rad-dreh{position:absolute;inset:0;display:none;place-items:center;
  background:var(--grund);z-index:5;text-align:center;cursor:pointer}
#ov-rad:not(.liegt) .rad-dreh, #ov-rad.zurueck .rad-dreh{display:grid}
#ov-rad .kd-handy{display:block;width:34px;height:60px;border:2px solid #8a8a8a;
  border-radius:7px;position:relative;margin:0 auto 18px;
  animation:kdHandyDrehen 3.2s ease-in-out infinite}
#ov-rad .kd-handy::after{content:'';position:absolute;left:50%;bottom:5px;
  width:8px;height:8px;margin-left:-4px;border-radius:50%;background:#8a8a8a}
#ov-rad.zurueck .kd-handy{animation-name:kdHandyZurueck}
#ov-rad .kd-wort{font-family:var(--s-regie);font-size:calc(var(--barlow) * .8);
  letter-spacing:.18em;color:var(--regie);text-transform:uppercase;line-height:2}
#ov-rad .kd-sperre,#ov-rad .kd-rechner{font-family:var(--s-regie);
  font-size:calc(var(--barlow) * .62);letter-spacing:.14em;
  text-transform:uppercase;color:#6f6f6f;line-height:1.55}
@media (prefers-reduced-motion: reduce){
  #ov-rad .kd-handy{animation:none;transform:rotate(-90deg)}
  #ov-rad.zurueck .kd-handy{animation:none;transform:rotate(0)}
}

/* =====================================================================
   DIE TESTLEISTE (Laura, 25.08.26). Nur mit ?test=1 in der Adresse,
   nie im Demo-Bau; gebaut von testleisteBauen() in game.js, dort steht
   auch die Begruendung. Sie ist WERKBANK, kein Spiel: darum System-Mono
   wie die Marken im PC-Rahmen und keine Farbe aus der Grammatik.
   (27.08.26, Laura: hier stand IBM Plex Mono. Die Schrift ist raus,
   die Rolle bleibt Mono — was nicht Spiel ist, ist Systemschrift, und
   System-Mono IST eine Systemschrift.)

   Sie steht am Ende der Datei, damit keine Szenenregel sie erwischt,
   und liegt hoeher als alles andere (der hoechste Wert im Spiel ist
   der Blitz mit 800 in geraet.css).
   ===================================================================== */
#testleiste{position:fixed;z-index:900;
  top:calc(10px + env(safe-area-inset-top,0px));left:10px;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:11px;letter-spacing:.14em}
#testleiste button{font:inherit;letter-spacing:inherit;
  background:#0d0d0d;border:1px solid #2a2a2a;border-radius:3px;color:#6a6a6a;
  -webkit-tap-highlight-color:transparent}
#testleiste .testlabel{display:block;padding:9px 13px;line-height:1;
  text-transform:uppercase}
#testleiste .testlabel::after{content:' \25B8'}          /* zugeklappt */
#testleiste .tl-liste{display:none}

/* aufgeklappt: ein Kasten ueber der ganzen Breite, das Etikett bleibt
   oben kleben und ist damit immer der Weg wieder zu */
#testleiste.offen{right:10px;
  max-height:calc(100vh - 20px);
  max-height:calc(100dvh - 20px);
  overflow-y:auto;background:#0a0a0a;border:1px solid #333;border-radius:5px}
#testleiste.offen .testlabel{position:sticky;top:0;z-index:1;
  width:100%;text-align:center;background:#0a0a0a;
  border-color:transparent;border-bottom-color:#262626;border-radius:0;
  padding:11px 13px}
#testleiste.offen .testlabel::after{content:' \25BE'}     /* aufgeklappt */
#testleiste.offen .tl-liste{display:block;padding:0 8px 8px}
#testleiste .tl-liste button{display:block;width:100%;text-align:left;
  padding:11px 12px;margin-top:6px;line-height:1.2}
/* die zwei Schalter oben sind heller und abgesetzt, damit sie sich
   nicht unter die Sprungmarken mischen */
#testleiste .tl-schalter{color:#8a8a8a;border-color:#3a3a3a}
#testleiste .tl-trenn{margin-top:12px}
/* wo der Durchgang gerade steht */
#testleiste .tl-liste button.hier{color:#c8c8c8;border-color:#555}

/* =====================================================================
   DER ZURUECK-STREIFEN (Laura, 26.08.26)

   WOFUER: Android hat eine Zurueck-Taste bzw. eine Randgeste, und
   Menschen benutzen sie dort staendig. Im Spiel gibt es aber nichts
   zum Zumachen (die Karte im Flur ist das einzige Overlay mit einem
   eigenen Ausgang), also fuehrt Zurueck geradewegs hinaus, mitten aus
   der Szene. Der Spielstand ueberlebt und der Wiedereinstieg faengt
   die Stelle ab, aber der Moment ist weg.

   Also der Android-Weg: erstes Zurueck wird geschluckt und
   beantwortet, ein zweites innerhalb von zwei Sekunden laesst raus.
   Die Mechanik steht in game.js unter zurueckFangen().

   WIE ER AUSSIEHT: Etikettenschrift und Moewenblau, damit er nicht
   mit der Stimme der Geschichte spricht. Butter ist er nicht, Butter
   gehoert Weiter, Senden und Ungelesen. Er traegt einen Grund unter
   sich: er kann ueber einer Wahl, ueber der Karte oder ueber dem
   Fragebogen erscheinen und muss dort lesbar bleiben.

   WO ER SITZT: ueber dem Klecks und nicht neben ihm — was neben dem
   Klecks laege, saehe aus wie ein zweiter Klecks. 44 px ueber der
   Knopfmitte laesst dem 48er Klecks seine 20 px Luft. env(safe-area-inset-bottom) ist auf Android in
   der Regel 0 und auf dem iPhone der Home-Indikator; beide Male
   rechnet die Zeile richtig.

   z-index 700: ueber allem, auch ueber dem Demo-Fragebogen (600) und
   der liegenden Karte (520). Ein Hinweis, den man nicht sieht, ist
   keiner.
   ===================================================================== */
.zurueckstreifen{
  position:fixed;left:50%;transform:translateX(-50%) translateY(6px);
  bottom:calc(var(--knopf-mitte) + 44px + env(safe-area-inset-bottom,0px));
  z-index:700;pointer-events:none;
  max-width:min(var(--spalte), calc(100vw - 32px));
  padding:9px 16px;border-radius:4px;
  background:rgb(14 14 16 / .92);
  box-shadow:0 2px 14px rgb(0 0 0 / .5);
  font-family:var(--s-regie);font-size:var(--barlow);
  line-height:var(--zeile-barlow);letter-spacing:.04em;
  color:rgb(var(--moewe-rgb) / .82);
  text-align:center;white-space:nowrap;
  opacity:0;
  transition:opacity .22s ease, transform .22s ease;
}
.zurueckstreifen.da{opacity:1;transform:translateX(-50%) translateY(0)}
/* Wer Bewegung abgestellt hat, bekommt ihn trotzdem — nur ohne das
   Auffahren. Der Streifen ist kein Schmuck, er ist die Antwort auf
   einen Tastendruck. */
@media (prefers-reduced-motion: reduce){
  .zurueckstreifen{transition:opacity .01s linear;transform:translateX(-50%)}
  .zurueckstreifen.da{transform:translateX(-50%)}
}

/* =====================================================================
   DIE HEIMKEHR-KETTE (29.08.26): Treppenhaus, Spachteln + Amira,
   Stick, Film, Zuordnung, Ansicht. Nichts hier erfindet Grammatik:
   Buehnen-Halter wie ueberall (.an blendet ein), die Farben sind
   Grund, Tinte, Moewe; Butter nur, wo der Daumen JETZT hin soll,
   Walblau nur an Fabis Dateien.
   ===================================================================== */

/* ---------- eine Quinn mit Schein ----------
   Den Schein bringt die Grammatik mit: .gegenlicht.auf-grund
   (design.html, Stueck 9 — Ellipse, vier Stuetzpunkte, Kasten so
   breit wie das BILD). Hier steht nur noch, wo die Katze steht und
   wie sie einblendet; die Zeichnung selbst wird nie angefasst. */
.quinnmoment{position:absolute;left:50%;top:50%;
  transform:translate(-50%,-52%);
  opacity:0;transition:opacity .6s ease}
.quinnmoment.an{opacity:1}
.quinnmoment img{display:block;width:100%;height:auto}

/* ---------- Spachteln: sechs Duebelloecher und das Handy ---------- */
.f2y-spachteln{position:absolute;inset:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:calc(40px * var(--e));
  opacity:0;transition:opacity .6s ease}
.f2y-spachteln.an{opacity:1}
.f2y-spachteln .duebelreihe{display:flex;gap:calc(10px * var(--e));
  align-items:center;justify-content:center;flex-wrap:wrap;
  max-width:min(92vw, 380px)}
.f2y-spachteln .duebel{appearance:none;background:none;border:0;padding:0;
  width:calc(46px * var(--e));height:calc(46px * var(--e));
  cursor:pointer;position:relative;touch-action:manipulation}
.f2y-spachteln .duebel svg{width:100%;height:100%;display:block}
/* Zeichnungston der Buehne (#999, wie objektSVG) — die Geraete-Graus
   gehoeren ins Handy, nie auf die Buehne (design.html, Grundfarben) */
.f2y-spachteln .duebel .loch{fill:#050505;stroke:#999;stroke-width:1.4}
.f2y-spachteln .duebel .masse{fill:rgb(236 233 226 / .82);stroke:none;
  opacity:0;transform:scale(.55);transform-origin:center;
  transition:opacity .28s ease, transform .34s cubic-bezier(.2,.9,.3,1.15)}
.f2y-spachteln .duebel.voll{cursor:default}
.f2y-spachteln .duebel.voll .masse{opacity:1;transform:scale(1)}
.f2y-spachteln .duebel.voll .loch{opacity:0;transition:opacity .28s ease}
/* gesperrt sieht gleich aus — es antwortet nur nicht; das Handy
   ruckt stattdessen (fine) */
/* DER ABSTAND NACH OBEN GEHT MIT DER GROESSE (30.08.26). Hier stand
   top:-40px, solange die Marke 31 breit war: die Unterkante lag dann 9
   px UEBER dem Loch, auf das sie zeigt. Mit 48 lag sie 8 px DARIN — die
   17 px Zuwachs haben den Abstand aufgefressen und aus dem Zeigen ein
   Draufliegen gemacht. -57 stellt die 9 px wieder her. Wer die Groesse
   noch einmal aendert, rechnet hier mit. */
.f2y-spachteln .duebel-tipp{--kl:48px;left:50%;top:-57px;transform:translateX(-50%)}
.f2y-spachteln .bodenhandy{opacity:0;transition:opacity .5s ease;
  cursor:pointer;padding:10px}
.f2y-spachteln .bodenhandy.da{opacity:1}
.f2y-spachteln .bodenhandy svg{display:block}
.f2y-spachteln .bodenhandy.ruft{animation:ruf-atem 3.4s ease-in-out infinite}
.f2y-spachteln .bodenhandy.ruft svg{animation:ruf-stups 4.6s ease-in-out infinite}
.f2y-spachteln .bodenhandy.ruckt svg{animation:handy-ruckt .22s ease 2}
@keyframes handy-ruckt{0%,100%{transform:translateX(0)}25%{transform:translateX(-3px)}75%{transform:translateX(3px)}}
@media (prefers-reduced-motion: reduce){
  .f2y-spachteln .bodenhandy.ruft,
  .f2y-spachteln .bodenhandy.ruft svg,
  .f2y-spachteln .bodenhandy.ruckt svg{animation:none}
  .f2y-spachteln .duebel .masse{transition:none}
}

/* ---------- Amira: Systemzeile, Screenshots ---------- */
/* die Systemzeile gehoert dem Messenger, nicht dem Gespraech: Bauart
   des Zeittrenners, nur mit Gewicht — sie meldet einen Zustand */
.h-log .systemzeile{text-align:center;color:#8a8a8a;
  font-size:.72rem;letter-spacing:.08em;margin:.85rem 0 .35rem}
/* die Blase mit dem Screenshot: das Bild ist der Inhalt */
.h-blase.mit-shot{padding:6px}
.h-blase.mit-shot .a-weiter{display:block;margin:2px 4px 6px}
.shotblase{appearance:none;background:none;border:0;padding:0;
  display:block;cursor:pointer}
.shothuelle{display:block;position:relative;overflow:hidden;
  border-radius:8px;border:1px solid #2a2a2e;background:#0a0a0c}
.shotgeraet{width:390px;height:844px;background:#0e0e10;
  display:flex;flex-direction:column;transform-origin:top left;
  pointer-events:none}
/* im Screenshot ist der Chat unten angeschlagen und nichts rollt */
.shotgeraet .h-log{flex:1;overflow:hidden;
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:0 14px 10px}
.shotgeraet .h-fuss{flex:0 0 auto}
/* das Vollbild im Panel: randlos, das Kreuz schwebt darueber */
.shotvoll{position:absolute;inset:0;z-index:40;
  background:rgb(0 0 0 / .92);
  display:flex;align-items:center;justify-content:center}
.shotvoll .shotzu{position:absolute;top:10px;right:12px;z-index:2;
  appearance:none;background:rgb(14 14 16 / .8);border:1px solid #333;
  border-radius:50%;width:38px;height:38px;color:#c8c8c8;
  font-size:1rem;line-height:1;cursor:pointer}

/* ---------- der Stick auf dem Kuechentisch ---------- */
.f2y-stick{position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .6s ease}
.f2y-stick.an{opacity:1}
/* die drei Dinge der Stick-Szene (30.08.26): Laptopkante links,
   Adapter Mitte, Stick rechts, alle auf einer Achse. Gezogen wird
   nichts — die Tipps stossen die Fluege an, geflogen wird ueber
   transform-Deltas auf die Ruhelagen (Rucksack-Muster). */
.f2y-stick .stickbuehne{position:relative;
  width:min(92vw, 420px);height:190px}
.f2y-stick .sding{position:absolute;top:50%;transform:translateY(-50%);
  appearance:none;background:none;border:0;margin:0;padding:6px;
  cursor:pointer;touch-action:manipulation}
.f2y-stick .sding svg{display:block}
.f2y-stick .slaptop{left:-6px;z-index:40}
/* 29 %, nicht mittig: auf einer 330px-Handybuehne brauchen die drei
   Zeichnungen die ganze Zeile — weiter rechts kuesst der Adapter den
   Stick schon in der Ruhelage */
.f2y-stick .sadapter{left:29%;z-index:30}
.f2y-stick .sstick{right:4%;z-index:20}
/* ein Takt fuer alles: Anfahren, Abprallen, Umdrehen, Einfahren */
.f2y-stick .sding.gleitet{transition:transform .45s cubic-bezier(.45,.85,.35,1)}
@media (prefers-reduced-motion: reduce){
  .f2y-stick .sding.gleitet{transition:none}
}

/* ---------- das Explorerfenster (der Laptop) ----------
   Geraetechrome wie beim Handy: Flaechen, kein Gestrichel. Der Kopf
   spricht versal (Regie-Schrift), die Liste liest sich in der
   Werkzeug-Schrift des Geraets, die Fusszeile ist klein und grau —
   sie faellt erst auf, wenn jemand sie liest.
   ALLE GROESSEN IM FENSTER EINE STUFE HOEHER (Laura, 29.08.26:
   "Alle, die dort stehen, eine Schriftgröße größer") — auch
   Etiketten, Marken, Dokument und Systemdialog gehoeren dazu.
   UND NOCH EINE STUFE (Hanna, 30.08.26: die Schrift im Fenster
   weiter zu klein) — dazu darf das Fenster selbst etwas hoeher und
   breiter stehen, damit die groesseren Zeilen nicht mehr Rollen
   erzwingen. Nur der Fensterkopf bleibt, wie er war: er traegt den
   laengsten Text und spricht ohnehin versal. */
.f2y-explorer{position:absolute;inset:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:18px;
  opacity:0;transition:opacity .6s ease}
.f2y-explorer.an{opacity:1}
.f2y-explorer .explorer{width:min(92vw, 420px);
  max-height:min(68vh, 560px);min-height:230px;
  display:flex;flex-direction:column;position:relative;
  background:#101013;border:1px solid #26262b;border-radius:10px;
  box-shadow:0 14px 40px rgb(0 0 0 / .5);
  overflow:hidden}
.f2y-explorer .exkopf{flex:0 0 auto;padding:10px 14px;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .9);
  letter-spacing:.14em;color:#b9b5ac;
  border-bottom:1px solid #1d1d21;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.f2y-explorer .exliste{flex:1 1 auto;overflow-y:auto;padding:6px 0}
.f2y-explorer .exfuss{flex:0 0 auto;padding:7px 14px;
  font-family:var(--werkzeug, system-ui);font-size:.78rem;
  letter-spacing:.12em;color:#5c5c60;border-top:1px solid #1d1d21}
.f2y-explorer .exdatei{display:flex;align-items:center;gap:9px;
  padding:10px 14px;cursor:pointer;
  font-family:var(--werkzeug, system-ui);font-size:1.05rem;color:#d6d3cc}
.f2y-explorer .exdatei:hover{background:#16161a}
/* das Zeichen vor dem Namen: ein echtes Fenster sagt, was jede Zeile
   ist — genau diese Echtheit traegt die Klick-Einladung (Laura,
   29.08.26, SPEC-Ausnahme in game.js) */
.f2y-explorer .exicon{flex:0 0 auto;display:block}
.f2y-explorer .exname{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
.f2y-explorer .exmeta{flex:0 0 auto;font-size:.78rem;color:#6a6a6e;
  letter-spacing:.03em;text-align:right}
/* Fabis Dateien tragen seine Farbe als schmale Kante (design.html:
   Walblau ist Fabis Farbe) */
.f2y-explorer .exdatei.seins{box-shadow:inset 2px 0 0 rgb(4 173 191 / .55)}
.f2y-explorer .exdatei.gespielt{color:#8a8a8a}
/* versteckte Elemente: halbdurchsichtig, wie es das System zeigt;
   .geist/.entwickelt (geraet.css) blenden sie ein */
.f2y-explorer .exdatei.versteckt{color:#8f8f93;font-style:italic}
/* KEIN .dran/.ruft an Dateien (Laura, 29.08.26: "Atmen darf es
   nicht"): die Klick-Einladung ist die Echtheit des Fensters selbst
   (SPEC-Ausnahme, s. filmSzene in game.js) */

/* die geoeffnete Datei: Titel + laufende Liste, rollbar. KEIN
   scroll-behavior:smooth: ein weiches Rollen ist eine Animation, und
   im verdeckten Tab friert sie ein — die Liste bliebe oben stehen
   (dieselbe Falle wie fines requestAnimationFrame-Verbot). Den Takt
   macht schon das Erscheinen der Zeilen. */
.f2y-explorer .exdoku{flex:1 1 auto;overflow-y:auto;
  padding:12px 16px 16px}
.f2y-explorer .extitel{font-family:var(--werkzeug, system-ui);
  font-weight:700;font-size:1.15rem;color:#e2dfd8;
  text-align:center;margin:4px 0 12px}
.f2y-explorer .filmzeile{font-family:var(--werkzeug, system-ui);
  font-size:1.05rem;line-height:1.5;color:#cfccc5;margin:0 0 .55rem;
  opacity:0;filter:blur(3px);
  transition:opacity .55s ease, filter .55s ease}
.f2y-explorer .filmzeile.entwickelt{opacity:1;filter:blur(0)}
@media (prefers-reduced-motion: reduce){
  .f2y-explorer .filmzeile{transition:none;opacity:1;filter:none}
}

/* ---------- die Zuordnung ----------
   Seit dem 30.08.26 (Hanna) wird gezogen: die Etiketten sind
   Griffe. touch-action:none nur auf ihnen — die Liste darunter
   rollt weiter mit dem Finger, gezogen wird am Etikett. */
.f2y-explorer .etiketten{flex:0 0 auto;display:flex;flex-wrap:wrap;
  gap:7px;padding:10px 12px;border-bottom:1px solid #1d1d21;
  transition:opacity .5s ease}
.f2y-explorer .etiketten.weg{opacity:0;pointer-events:none}
.etikett{appearance:none;background:#17171b;border:1px solid #34343a;
  border-radius:7px;padding:7px 12px;cursor:grab;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .98);
  letter-spacing:.1em;color:#c9c5bc;
  touch-action:none;user-select:none;-webkit-user-select:none}
.etikett.gewaehlt{border-color:#ece9e2;color:#ece9e2;background:#222227}
.etikett.platziert{opacity:.34}
/* gepackt: das Etikett selbst wird zum Loch in der Reihe, der Geist
   traegt seinen Text unterm Finger */
.etikett.gepackt{opacity:.25;border-style:dashed;cursor:grabbing}
.etiGeist{position:fixed;left:0;top:0;z-index:90;pointer-events:none;
  background:#1d1d22;border:1px solid #55555c;border-radius:7px;
  padding:7px 12px;width:max-content;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .98);
  letter-spacing:.1em;color:#ece9e2;
  box-shadow:0 10px 26px rgb(0 0 0 / .55);
  will-change:transform}
/* der Flug: angenommen gibt er an die Marke ab, abgelehnt federt er
   in die Reihe zurueck (die Kurve schwingt ueber) */
.etiGeist.flug{transition:transform .24s cubic-bezier(.3,1.3,.4,1),
  opacity .22s ease}
.f2y-explorer .zuordliste{padding-bottom:8px}
.zuordZeile{position:relative;display:block;
  padding:9px 16px 9px 20px;cursor:pointer;
  font-family:var(--werkzeug, system-ui);font-size:1.05rem;
  line-height:1.5;color:#cfccc5}
.zuordZeile .ztxt{display:block}
.zuordZeile .etikettMarke{display:block;width:max-content;
  margin:0 0 3px;padding:2px 8px;
  border:1px solid #3c3c42;border-radius:5px;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .9);
  letter-spacing:.12em;color:#d6d3cc;background:#17171b}
.zuordZeile .etikettMarke.leer{display:none}
.zuordZeile.wahlOffen{background:#16161a}
/* die Zeile unterm Finger: hier wuerde abgelegt — eine Hebung, kein
   Urteil (sie sagt nicht, ob es passt) */
.zuordZeile.dropZiel{background:rgb(236 233 226 / .08);
  box-shadow:inset 2px 0 0 rgb(236 233 226 / .45)}
/* die Zone, die sitzt: eine ruhige Kante, keine Farbe */
.zuordZeile.zoneFest{box-shadow:inset 2px 0 0 rgb(169 181 189 / .5);
  background:rgb(169 181 189 / .05)}
.zuordZeile.zoneKopf{border-top-left-radius:6px;border-top-right-radius:6px}
.zuordZeile.zoneEnde{border-bottom-left-radius:6px;border-bottom-right-radius:6px;
  margin-bottom:5px}
/* rastet: die Marke schnappt mit Ueberschwung ein … */
.zuordZeile .etikettMarke.schnappt{transform-origin:left center;
  animation:marke-schnappt .38s cubic-bezier(.2,1.5,.4,1) 1}
@keyframes marke-schnappt{0%{transform:scale(1.28)}100%{transform:scale(1)}}
/* … und die ganze Zone leuchtet einmal auf und beruhigt sich auf
   ihren zoneFest-Grund */
.zuordZeile.rastet{animation:zone-rastet .55s ease 1}
@keyframes zone-rastet{0%{background:rgb(169 181 189 / .24)}
  100%{background:rgb(169 181 189 / .05)}}
/* prallt ab: der kurze Kopfschuettler der Zeile, sonst nichts */
.zuordZeile.prallt{animation:handy-ruckt .22s ease 1}
/* Hilfe ohne Farbe: die richtige Zeile glimmt kurz heller */
.zuordZeile.glimm{animation:zeile-glimm .65s ease}
@keyframes zeile-glimm{0%,100%{background:transparent}
  45%{background:rgb(236 233 226 / .14)}}
.etiWahl{display:flex;flex-wrap:wrap;gap:6px;
  padding:7px 16px 10px 20px;background:#16161a}
/* die Waisen bleiben, der Rest verblasst und loest sich auf */
.zuordZeile.geist{opacity:.42;filter:blur(.4px);
  transition:opacity .9s ease, filter .9s ease}
.zuordZeile.aufgeloest{opacity:0 !important;filter:blur(4px) !important;
  transition:opacity 1.1s ease, filter 1.1s ease}
.zuordliste .etikettMarke.luecke{display:block;width:max-content;
  margin:6px 0 6px 20px;padding:2px 8px;
  border:1px solid #3c3c42;border-radius:5px;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .92);
  letter-spacing:.14em;color:#ece9e2;background:#1b1b20;
  min-height:1.2em}
@media (prefers-reduced-motion: reduce){
  .zuordZeile.glimm,.zuordZeile.prallt,.zuordZeile.rastet,
  .zuordZeile .etikettMarke.schnappt{animation:none}
  .zuordZeile.geist,.zuordZeile.aufgeloest{transition:none}
  .etiGeist.flug{transition:none}
  .f2y-explorer .etiketten{transition:none}
}

/* ---------- die Ansicht: der Drei-Tasten-Griff, der Dialog, das
   Dokument ---------- */
.f2y-explorer .griffreihe{flex:0 0 auto;display:flex;gap:14px;
  align-items:center;justify-content:center}
.kappe{appearance:none;position:relative;
  width:58px;height:58px;border-radius:12px;
  background:#141417;border:1px solid #303036;
  color:#d6d3cc;font-size:1.35rem;line-height:1;cursor:pointer;
  box-shadow:0 3px 0 #0a0a0c;
  transition:transform .12s ease, box-shadow .12s ease,
    border-color .2s ease, background-color .2s ease}
.kappe.pulst{animation:ruf-atem 3.4s ease-in-out infinite}
.kappe.gedrueckt{transform:translateY(2px);box-shadow:0 1px 0 #0a0a0c;
  background:#222227;border-color:#4a4a52}
.kappe.blitzt{border-color:#ece9e2}
/* dieselbe Rechnung wie am Duebel: -34 stammt aus der Zeit der 31er
   Marke (3 px Luft ueber der Kappe), mit 48 lag sie 14 px drauf. */
.kappe .griff-tipp{--kl:48px;left:50%;top:-51px;transform:translateX(-50%)}
@media (prefers-reduced-motion: reduce){
  .kappe.pulst{animation:none;border-color:#5a5a62}
}

/* der Systemdialog: Geraetesprache, zwei gleichgewichtige Knoepfe —
   kein Puls, kein Klecks, kein Primaer-Highlight */
.sysdialog{position:absolute;inset:0;z-index:5;
  background:rgb(0 0 0 / .55);
  display:flex;align-items:center;justify-content:center;padding:18px}
.sysdialog-fenster{width:min(86%, 300px);
  background:#1a1a1e;border:1px solid #33333a;border-radius:10px;
  padding:16px 16px 12px;text-align:center;
  font-family:var(--werkzeug, system-ui)}
.sysdialog-titel{font-weight:700;font-size:.9rem;color:#e2dfd8;
  overflow-wrap:anywhere;margin-bottom:8px}
.sysdialog-text{font-size:.88rem;line-height:1.45;color:#b9b5ac;
  margin-bottom:14px}
.sysdialog-knoepfe{display:flex;gap:8px}
.sysdialog-knoepfe button{flex:1;appearance:none;
  background:#232328;border:1px solid #3a3a42;border-radius:7px;
  padding:8px 4px;color:#d6d3cc;font-size:.88rem;cursor:pointer;
  font-family:inherit}

/* das Dokument: zwei Zeilen scharf, der Rest gedimmte Wisch-Balken */
.f2y-explorer .dokublock{flex:0 1 auto;overflow-y:auto;
  padding:14px 18px 16px;border-top:1px solid #1d1d21}
.f2y-explorer .dokuzeile{font-family:var(--werkzeug, system-ui);
  font-size:.95rem;line-height:1.5;color:#e2dfd8;margin:.5rem 0}
.f2y-explorer .dokuwisch{display:block;height:9px;border-radius:4px;
  background:#232327;margin:0 0 7px}

/* =====================================================================
   DIE ABENDKETTE (29.08.26): Streichen, Fabi online, Pizza, der
   Oktopus (k3s2 bis k3s6 aus fine, in die Grammatik dieses Spiels
   uebersetzt).
   ===================================================================== */

/* ---------- Streichen: eine Wand nach der anderen ----------
   Die Wand ist eine Zeichnung der Buehne (#050505/#999 wie die
   Duebelloecher); die Farbe ist das Tinten-Weiss der Spachtelmasse,
   die Geraete-Graus bleiben im Handy (design.html, Grundfarben). */
.f2y-streichen{position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .6s ease}
.f2y-streichen.an{opacity:1}
.f2y-streichen .streichwand{position:relative;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  opacity:0;transition:opacity .45s ease;
  touch-action:none;cursor:pointer}
.f2y-streichen .streichwand.da{opacity:1}
.f2y-streichen .streichwand svg{display:block;height:auto}
.f2y-streichen .streichwand .objektlabel{margin-top:0}
@media (prefers-reduced-motion: reduce){
  .f2y-streichen,.f2y-streichen .streichwand{transition:none}
}

/* ---------- Fabi online: der Status-Kopf lebt kurz ----------
   dieselbe f2y-status-Bauart wie am Stein; 'lebt' ist der walblaue
   Punkt vor der Zeile — er ist JETZT da (fines fabilebt) */
.f2y-status .nzeit.lebt{color:#04adbf}
.f2y-status .nzeit.lebt::before{content:'';display:inline-block;
  width:7px;height:7px;border-radius:50%;background:#04adbf;
  box-shadow:0 0 6px 1px rgba(4,173,191,.55);
  margin-right:.5em;vertical-align:.05em}
/* "online" im Fluss: kursiv, die langsame Einblendung macht game.js */
.satz .onlineHall{font-style:italic}
/* der Klecks unterm Panel haengt auf Knopfhoehe (design.html) und
   laege sonst auf der letzten Blase des unten angeschlagenen
   Verlaufs: der Log bekommt Luft nach unten */
#fo-log{padding-bottom:56px}

/* ---------- Pizza: der Konfigurator als App im Geraet ----------
   App-Kopf wie ein Fensterkopf des Geraets: Titel, darunter die
   Zeile der App (dieselbe Leiter wie Name + Status im Chatkopf) */
.h-kopf.app{flex-direction:column;align-items:flex-start;gap:2px}
.h-kopf.app .unter{font-family:var(--werkzeug);font-size:11px;
  color:#8c8c92;line-height:1.3}
.pizzalog{display:flex;flex-direction:column;align-items:center;
  overflow-y:auto}
.pizzalog.mittig{justify-content:center}
.pizzalog .zeittrenner{align-self:center}
.pizzabuehne{display:flex;align-items:center;justify-content:center;
  min-height:176px;padding:10px 0 4px}
.pizzasvg{display:block;transition:width .3s ease, height .3s ease}
.belagreihe{display:flex;flex-wrap:wrap;gap:8px;
  justify-content:center;padding:8px 10px;max-width:100%}
.belag{appearance:none;background:#25252a;border:1px solid #3a3a3a;
  border-radius:9px;padding:8px 10px 6px;min-width:64px;
  display:flex;flex-direction:column;align-items:center;gap:4px;
  color:#75757b;cursor:pointer;font-family:var(--werkzeug);
  transition:color .2s ease, border-color .2s ease}
.belag span{font-size:11px;line-height:1.2}
.belag svg{display:block}
.belag.an{color:#e2e2e6;border-color:#8c8c92}
/* Bestellen traegt das Gelb erst, wenn bestellt werden KANN — der
   Sendenknopf-Satz aus design.html, auf die App uebertragen */
.pizzafuss{display:flex;align-items:center;justify-content:center;
  padding:10px 14px}
.pizzafuss .bestellknopf{appearance:none;flex:1;max-width:280px;
  background:#25252a;border:1px solid #3a3a3a;border-radius:10px;
  padding:10px 12px;color:#75757b;font-family:var(--werkzeug);
  font-size:14px;cursor:pointer;
  transition:background .25s ease, color .25s ease}
/* moewenblau statt Butter (30.08.26): auch das ist ein Knopf, der
   sagt "jetzt du". Seine Ruhe war schon dunkel, er braucht darum
   keinen gestrichelten Rand — er hat eine eigene Kante. */
.pizzafuss .bestellknopf:not(:disabled){
  background:rgb(var(--klecks-rgb));border-color:transparent;
  color:var(--tinte-dunkel)}
.pizzafuss .bestellknopf:disabled{cursor:default}

/* ---------- der Oktopus, gross und allein ---------- */
.f2y-oktopus{position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  opacity:0;transition:opacity .6s ease}
.f2y-oktopus.an{opacity:1}
.f2y-oktopus .oktoding{display:flex;flex-direction:column;
  align-items:center;gap:10px;padding:14px}
.f2y-oktopus .oktoding svg{display:block;
  width:calc(150px * var(--e, 1));height:auto}
@media (prefers-reduced-motion: reduce){
  .f2y-oktopus{transition:none}
}

/* =====================================================================
   DIE RUECKBLENDEN-KETTE (30.08.26): das Auffalten ins Weiss, das
   Hotel, der Strobo mit dem Heimweg-Film, die zugedeckte Seite
   (k3s7 bis k3s9b aus fine, in die Grammatik dieses Spiels
   uebersetzt).
   ===================================================================== */

/* ---------- das Auffalten: der wachsende Bogen ----------
   Der Bogen liegt in einem fixed-Layer UEBER der Buehne (er waechst
   ueber den Bildschirm hinaus). Es gibt nur noch Ziehen (Hanna,
   30.08.26): eine Regiezeile im Fluss, dann ruft der walZug-Klecks;
   die Zeile geht nach Zug 2 — bevor das wachsende Papier sie
   erreichen koennte. */
#papierlayer{position:fixed;inset:0;z-index:300;
  display:flex;align-items:center;justify-content:center;
  pointer-events:none}   /* nur der Bogen selbst faengt Zuege */
#oktobogen{position:relative;pointer-events:auto;
  width:min(190px,56vw);height:min(130px,32vh);
  transition:width .7s ease, height .7s ease;
  cursor:grab;touch-action:none;text-align:center}
#oktobogen:active{cursor:grabbing}
#oktobogen.offen1{width:min(250px,72vw);height:min(210px,36vh)}
#oktobogen.offen2{width:min(300px,84vw);height:min(300px,40vh)}
#oktobogen.offen3{width:min(340px,90vw);height:min(360px,44vh)}
#oktobogen.als-svg{border-color:transparent;color:transparent}
/* der Ruf-Klecks behaelt seine Normgroesse, auch wenn der Bogen
   skaliert: die Gegenskalierung liest --sk aus skala() */
#oktobogen .wal-zug{transform:scale(calc(1 / var(--sk, 1)));
  transform-origin:center}
/* der Weiss-Deckel: das Papier hat alles gefuellt; er bleibt stehen
   und hebt sich erst im Hotel (z 700: ueber Klecks und Regie, unter
   der Werkbank) */
#weissdeckel{position:fixed;inset:0;z-index:700;background:#fff;
  opacity:0;pointer-events:none}
@media (prefers-reduced-motion: reduce){
  #oktobogen{transition:none}
}

/* ---------- das Hotel: die helle Welt ----------
   Grund #ececec, nicht #fff — Weiss bleibt Ereignis. Die Lakenfalten
   sind die Knicke des Oktopus-Bogens auf dem Viewport. */
#lakenlayer{position:fixed;inset:0;z-index:0;pointer-events:none}
#lakenlayer svg{position:absolute;inset:0;width:100%;height:100%}
#lakenlayer .falte{fill:none;stroke-linecap:round;
  transition:stroke-width 1.4s ease, opacity 1.4s ease, stroke 1.4s ease, filter 1.4s ease}
/* der Lichtspalt: schwere Vorhaenge, ein heller Streifen */
#lakenlayer .lichtspalt{position:absolute;top:0;bottom:0;left:60%;width:14%;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.8), transparent);
  opacity:0;transition:opacity 1.4s ease}
#lakenlayer .lichtspalt.da{opacity:1}
body.hotelhell{background:#ececec}
body.hotelhell #buehne, body.hotelhell #fluss, body.hotelhell #fuss{
  position:relative;z-index:2}
body.hotelhell .satz{color:#1a1a1a;text-shadow:none}
body.hotelhell .satz.regie{color:#6a6a6a}
/* die Wahl in der hellen Welt: derselbe gestrichelte Kasten, nur mit
   dunkler Tinte und dunklem Rand */
body.hotelhell .wahl{color:#1a1a1a}
body.hotelhell .wahl .w-rand rect{stroke:rgb(0 0 0 / .38)}
body.hotelhell .wahl.gewaehlt{color:var(--tinte-dunkel)}
/* die Werkbank bleibt lesbar */
body.hotelhell #topbar{color:#4a4a4a}
body.hotelhell #topbar button{color:#4a4a4a;border-color:#bbb}

/* ---------- der Strobo ----------
   Eigenes Overlay ueber allem ausser der Werkbank (Testleiste 900).
   Das Schwarz ist hier echtes Club-Dunkel (#050505), kein Grund. */
#stroboszene{position:fixed;inset:0;z-index:640;
  background:#050505;overflow:hidden;cursor:pointer;
  user-select:none;-webkit-user-select:none;
  touch-action:manipulation;-webkit-tap-highlight-color:transparent}
/* Basspuls: radiale Vignette, rein visuell */
#strobo-puls{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse at center, transparent 42%, #000 100%);
  opacity:.04;animation:stroboPuls 500ms ease-in-out infinite}
@keyframes stroboPuls{0%,100%{opacity:.04}50%{opacity:.09}}
/* Blitzflaeche + Caption: die Flaeche schaltet hart, die Caption
   bleibt als Negativ-Nachbild auf dem Dunkel stehen */
#strobo-blitz{position:absolute;inset:0;pointer-events:none;
  display:flex;align-items:center;justify-content:center}
#strobo-blitz .flaeche{position:absolute;inset:0;background:#f2f2f2;opacity:0}
#strobo-blitz .caption{position:relative;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * 1.4);
  line-height:var(--zeile-barlow);
  letter-spacing:.16em;text-transform:uppercase;color:#0a0a0a;
  text-align:center;padding:0 22px;max-width:90%;opacity:0}
/* Zeilen: EIN ORT fuers Auge (Hanna, 30.08.26) — alles wohnt von
   Anfang an in der Mitte, wo auch die Blitz-Captions stehen; Zeile
   und Nachbild wechseln sich dort ab (flash haelt die Zeile weg,
   solange die Caption steht). */
#strobo-zeile{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(var(--spalte), 86%);text-align:center;pointer-events:none}
#strobo-zeile .sz{line-height:var(--zeile);font-size:var(--hanken);
  font-family:var(--s-lesen);
  opacity:0;transition:opacity .15s ease-out}
#strobo-zeile .sz.da{opacity:1}
#strobo-zeile .ich{color:#b2b2b2;font-style:italic}
#strobo-zeile .du{color:#e9e9e9}
/* die Wahl: die Kaesten dieses Spiels, im Overlay */
#strobo-zeile .strobowahl{display:flex;flex-direction:column;gap:11px;
  align-items:center;margin-top:6px;pointer-events:auto;
  opacity:0;transition:opacity .25s ease}
#strobo-zeile .strobowahl.da{opacity:1}
/* Intrusion: Fabis Fragment, um 180 Grad gedreht, Walblau-Familie */
#strobo-intrusion{position:absolute;inset:0;pointer-events:none;
  display:flex;align-items:center;justify-content:center;
  opacity:0;overflow:hidden}
#strobo-intrusion .frag{transform:rotate(180deg);
  font-family:var(--werkzeug, system-ui);
  color:#d3edf1;background:#062e33;border-radius:16px;
  padding:9px 15px;font-size:calc(15px * var(--ts));
  white-space:nowrap;overflow:hidden}
/* die Scheinwerfer (Hanna, 30.08.26): Lichtkegel von oben in den
   vier Spielfarben, additiv auf dem Club-Dunkel (screen), schneller
   Takt, auch mal kurz ueberlappt */
#strobo-lichter{position:absolute;inset:0;pointer-events:none;overflow:hidden}
#strobo-lichter .slicht{position:absolute;top:-6%;width:38%;height:118%;
  transform:translateX(-50%) rotate(var(--rot,0deg));transform-origin:50% 0;
  background:linear-gradient(to bottom, var(--lf) 0%, transparent 78%);
  clip-path:polygon(43% 0, 57% 0, 100% 100%, 0% 100%);
  mix-blend-mode:screen;
  opacity:0;transition:opacity .09s ease}
#strobo-lichter .slicht.an{opacity:.68}
#stroboszene.reduziert #strobo-lichter .slicht{transition:opacity .35s ease}
#stroboszene.reduziert #strobo-lichter .slicht.an{opacity:.4}
/* reduziert: kein Hartschnitt, weichere Flaeche */
#stroboszene.reduziert #strobo-blitz .flaeche{background:#d8d8d8;
  transition:opacity .3s ease}
/* Halten friert den Moment ein: der Puls pausiert, die Zeile schaerft
   sich — keine Bewegung, reduziert-tauglich per se */
#stroboszene.haelt #strobo-puls{animation-play-state:paused}
#stroboszene.haelt #strobo-zeile .sz{filter:brightness(1.18);transition:filter .25s}

/* ---- der Heimweg-Film: derselbe Ort wie der ganze Abend (die
   Mitte), nur das Register wechselt — aufrecht, Kursiv gehoert dem
   Kipp. Die Kamerafahrt ist GESTRICHEN (Hanna, 30.08.26): der
   Registerwechsel Bar -> Film ist das Sterben von Puls und Licht
   (game.js, Uebergang). ---- */
#stroboszene.film #strobo-zeile .sz{transition:opacity .25s ease}
#stroboszene.film #strobo-zeile .ich{font-style:normal}
/* Insert-Karten: kleine CAPS-Karten, die Zwischentitel des Films */
#stroboszene.film .sz.insert{display:block;width:max-content;max-width:100%;
  margin:0 auto;padding:8px 17px;border:1px solid #262626;
  font-family:var(--s-regie);font-size:var(--barlow);
  line-height:var(--zeile-barlow);
  letter-spacing:.22em;text-transform:uppercase;color:#c9c9c9}
#stroboszene.film .jschlag{opacity:0;transition:opacity .2s ease}
#stroboszene.film .jschlag.da{opacity:1}
#stroboszene.film .sz.frage{font-size:calc(var(--hanken) * 1.3);
  font-weight:500;color:#e9e9e9}
#stroboszene.film .sz.frage .fwort{opacity:0;transition:opacity .2s ease}
#stroboszene.film .sz.frage .fwort.da{opacity:1}
#stroboszene.film .sz.frage.atmet{animation:frageAtmen 2s ease-in-out infinite}
@keyframes frageAtmen{0%,100%{opacity:1}50%{opacity:.86}}
#stroboszene.film .kipp.an{font-style:italic}
#stroboszene.film .nachschlag{opacity:0;transition:opacity .25s ease}
#stroboszene.film .nachschlag.da{opacity:1}
#stroboszene.film .streich{position:relative;white-space:nowrap}
#stroboszene.film .streich::after{content:'';position:absolute;left:0;
  top:.58em;height:1px;width:0;background:currentColor}
#stroboszene.film .streich.durch::after{width:100%;transition:width .4s linear}
#stroboszene.film .streich.sofort::after{transition:none}
/* die Geraete-Zeile + der Flip: das einzige Walblau des Films */
#stroboszene.film .filmgeraet{display:flex;flex-direction:column;
  align-items:center;gap:9px}
#stroboszene.film .gflip{perspective:600px}
#stroboszene.film .gzeile{font-family:var(--werkzeug, system-ui);
  color:#d3edf1;background:#062e33;border-radius:16px;
  padding:9px 15px;font-size:calc(15px * var(--ts));max-width:100%;
  filter:drop-shadow(0 0 18px rgba(4,173,191,.25));
  transition:transform .6s ease, color .6s, background .6s, filter .6s}
#stroboszene.film .gzeile.geflippt{transform:rotateX(180deg);
  color:#1a1a1a;background:#101010;filter:none}
#stroboszene.film .gzeile.ohnedreh{transition:color .6s, background .6s, filter .6s;transform:none}
#stroboszene.film .gantwort{font-family:var(--werkzeug, system-ui);
  color:#6a6a6a;font-size:calc(13.5px * var(--ts));
  opacity:0;transition:opacity .25s ease}
#stroboszene.film .gantwort.an{opacity:1}
#stroboszene.film .gantwort.getippt{color:#bdbdbd}
#stroboszene.film .gantwort.getippt .gcursor{opacity:1;animation:none}
#stroboszene.film .gantwort .gcursor{display:inline-block;width:1px;
  height:1em;margin-left:2px;vertical-align:-2px;background:#04adbf;opacity:0}
#stroboszene.film .gantwort.an .gcursor{animation:stroboCursor 1.05s steps(1) 2}
@keyframes stroboCursor{0%,50%{opacity:1}50.01%,100%{opacity:0}}
#stroboszene.film .gregie{font-family:var(--s-regie);color:#7c7c7c;
  font-size:calc(var(--barlow) * .85);letter-spacing:.14em;
  text-transform:uppercase;opacity:0;transition:opacity .25s ease}
#stroboszene.film .gregie.an{opacity:1}
#stroboszene.film .gso{font-size:calc(var(--hanken) * .9);color:#9a9a9a;
  opacity:0;transition:opacity .25s ease}
#stroboszene.film .gso.an{opacity:1}

/* ---------- die zugedeckte Seite ---------- */
.f2y-zugedeckt{position:absolute;inset:0;
  display:flex;flex-direction:column;align-items:center;
  justify-content:flex-start;padding:10px 0 0;
  opacity:0;transition:opacity .6s ease}
.f2y-zugedeckt.an{opacity:1}
/* die gestrichenen Zeilen: Tipp-Ex, literal weiss — ihr Satz schreibt
   sich auf die Uebermalung, in ihrer Handschrift */
.f2y-zugedeckt .morgenblock{flex:0 0 auto;max-width:var(--spalte);
  width:calc(100% - 52px);margin:0 0 6px;line-height:1.5;
  font-size:calc(var(--hanken) * .9)}
.gestrichen{position:relative;display:inline-block;max-width:100%;
  margin:0 0 .95em;cursor:pointer;color:var(--tinte)}
.gestrichen .wort{color:var(--tinte)}
.gestrichen .balken{position:absolute;left:-.35em;right:-.35em;
  top:calc(-.22em - var(--zu, 0em));
  height:calc(100% + .44em + var(--zu, 0em) * 2);
  background:#ffffff;border:1px solid #d8d4c8;
  transform:rotate(-.5deg);pointer-events:none;z-index:2;
  transition:height .35s ease, top .35s ease, transform .35s ease}
.gestrichen .drauf{position:absolute;left:.2em;right:.2em;z-index:3;
  display:flex;align-items:center;height:1.5em;
  top:calc(-.1em - var(--zu, 0em));
  font-family:var(--s-fine);font-size:1.05em;color:#2a2a28;
  transform:rotate(-.8deg);opacity:0;pointer-events:none;
  transition:opacity .4s ease}
.gestrichen .drauf.da{opacity:1}
.gestrichen.zittert{animation:morgenzitt .16s linear infinite}
@keyframes morgenzitt{0%{transform:translateX(0)}25%{transform:translateX(-1.2px)}
  75%{transform:translateX(1.2px)}100%{transform:translateX(0)}}
/* der Wurf-Stapel: helle Zettel, dunkle Tinte, Behoerden-Stempel */
.f2y-zugedeckt .kausstapel{position:relative;flex:1 1 auto;
  width:min(var(--spalte), 94%);min-height:150px}
.kkarte{position:absolute;left:50%;top:14px;box-sizing:border-box;
  width:min(300px, 88%);min-height:96px;
  padding:12px 14px 13px;display:flex;flex-direction:column;gap:7px;
  color:#1a1a1a;border:1px solid #cfcfcf;border-radius:2px;
  background:
    repeating-linear-gradient(115deg, rgba(0,0,0,.03) 0 1.5px, transparent 1.5px 5px),
    #e9e9e9;
  box-shadow:0 2px 5px rgba(0,0,0,.4), 0 12px 26px rgba(0,0,0,.35)}
.kkarte::before{content:'';position:absolute;top:0;right:0;
  border-width:0 15px 15px 0;border-style:solid;
  border-color:#c4c4c4 #c4c4c4 transparent transparent;
  filter:drop-shadow(-1px 1px 1px rgba(0,0,0,.45))}
.kkarte .kacheltext{margin:0;color:#1a1a1a;
  font-size:calc(var(--hanken) * .9);line-height:1.45}
.kkarte .stempel{align-self:flex-start;margin-top:auto;
  transform:rotate(-3deg) scale(1.35)}
.kkarte .stempel.knall{transform:rotate(-3deg) scale(1)}
/* der Stempel: Behoerdenstimme — Versalien, gerahmt, leicht verdreht,
   Knall; der Abdruck ist von Hand geknallt (Papierfrass im ::after) */
.stempel{position:relative;
  border:2px solid #1a1a1a;color:#1a1a1a;
  padding:3px 8px;text-transform:uppercase;font-weight:600;
  font-family:var(--s-regie);
  font-size:calc(.78rem * var(--ts));letter-spacing:.1em;
  text-shadow:.7px .5px 0 rgba(26,26,26,.28);
  border-radius:2px 5px 3px 6px / 5px 2px 6px 3px;
  transform:rotate(-2deg) scale(1.4);opacity:0}
.stempel::after{content:'';position:absolute;inset:0;pointer-events:none;
  border-radius:inherit;
  background:
    radial-gradient(ellipse 60% 90% at 72% 78%, rgba(233,233,233,.34), transparent 60%),
    repeating-radial-gradient(ellipse 130% 100% at 28% 18%, transparent 0 3px, rgba(233,233,233,.12) 3px 4px, transparent 4px 7px)}
.stempel.knall{transform:rotate(-2deg) scale(1);opacity:1;
  transition:transform .12s cubic-bezier(.2,1.4,.4,1), opacity .12s}
.stempel.ruhigst{transform:rotate(-2deg) scale(1)}
/* das Verblassen: alles ausser den Stempeln geht */
.f2y-zugedeckt .szeneVerblasst{opacity:0;transition:opacity 1.2s ease;
  pointer-events:none}
/* die Stempelspalte: der Kontoauszug fremder Entscheidungen — jeder
   Zettel behaelt sein Stueck Kachel-Papier, hingeworfen gestapelt */
.stempelspalte{display:flex;flex-direction:column;gap:6px;
  align-items:center;margin:8px 0 4px;padding:3px 0}
.stempel.inspalte{position:static;margin:0;background:#e9e9e9;
  align-self:center;
  box-shadow:0 2px 9px rgba(0,0,0,.55), 0 1px 2px rgba(0,0,0,.65);
  transition:none}
/* der Kippsatz: freistehend, mittig — traegt am Ende den MIR-Stempel */
.f2y-zugedeckt .kippsatz{position:relative;flex:0 0 auto;
  text-align:center;font-size:var(--hanken);color:#c8c8c8;
  font-style:italic;margin:14px auto 10px;max-width:var(--spalte)}
.stempel.aufzeile{position:absolute;left:50%;top:-1.25em;margin:0;
  background:#e9e9e9;white-space:nowrap;
  box-shadow:0 2px 9px rgba(0,0,0,.55), 0 1px 2px rgba(0,0,0,.65);
  transform:translateX(-50%) rotate(-2deg) scale(1.4)}
.stempel.aufzeile.knall{transform:translateX(-50%) rotate(-2deg) scale(1)}
.stempel.aufzeile.ruhigst{transform:translateX(-50%) rotate(-2deg) scale(1)}
/* das Finale-Paar: beide zu, beschriftet, pochen, zerfallen — nie auf */
.f2y-zugedeckt .kachelpaar{display:flex;gap:12px;justify-content:center;
  align-items:stretch;margin:6px auto;width:min(var(--spalte), 92%);
  transform-origin:center;
  transition:transform .6s ease-in-out, opacity .6s ease-in-out}
.f2y-zugedeckt .kachel{flex:1 1 0;min-height:84px;box-sizing:border-box;
  position:relative;border-radius:2px;
  display:flex;align-items:center;justify-content:center;
  --rot:0deg;
  background:
    repeating-linear-gradient(115deg, rgba(0,0,0,.03) 0 1.5px, transparent 1.5px 5px),
    #e9e9e9;
  border:1px solid #cfcfcf;
  box-shadow:0 2px 5px rgba(0,0,0,.3), 0 10px 22px rgba(0,0,0,.25);
  transform:rotate(var(--rot));transition:transform .28s ease-out}
.f2y-zugedeckt .kachel::before{content:'';position:absolute;top:0;right:0;
  border-width:0 14px 14px 0;border-style:solid;
  border-color:#c4c4c4 #c4c4c4 transparent transparent;
  filter:drop-shadow(-1px 1px 1px rgba(0,0,0,.3))}
.f2y-zugedeckt .kachel.links{--rot:-1.3deg}
.f2y-zugedeckt .kachel.rechts{--rot:1.1deg}
.f2y-zugedeckt .kachel.lockt{animation:finlockt 2.6s ease-in-out infinite}
.f2y-zugedeckt .kachel.rechts.lockt{animation-duration:3.1s;animation-delay:.5s}
@keyframes finlockt{
  0%,100%{transform:rotate(var(--rot))}
  25%{transform:rotate(calc(var(--rot) - 1.5deg)) translateY(-1.5px)}
  50%{transform:rotate(calc(var(--rot) + .4deg))}
  75%{transform:rotate(calc(var(--rot) - .9deg)) translateY(-1px)}}
.f2y-zugedeckt .kachel.kzerr{animation:finzerr .28s cubic-bezier(.34,.8,.42,1)}
@keyframes finzerr{
  0%{transform:rotate(var(--rot))}
  28%{transform:rotate(var(--rot)) translateY(-6px) scale(1.03)}
  48%{transform:rotate(var(--rot)) translateY(-6px) scale(1.03)}
  72%{transform:rotate(calc(var(--rot) - 1.4deg)) translateY(3px)}
  100%{transform:rotate(var(--rot))}}
.f2y-zugedeckt .fintext{color:#4a4a4a;font-size:calc(var(--hanken) * .9);
  letter-spacing:.02em;padding:8px}
.f2y-zugedeckt .finbst{display:inline-block;
  transition:transform 3s ease-in, opacity 3s ease-in}
.f2y-zugedeckt .finbst.rieselt{transform:translateY(130px);opacity:0}
.f2y-zugedeckt .kachelpaar.zerfall .kachel{filter:blur(7px);opacity:0;
  transition:filter 1.5s ease-in, opacity 1.5s ease-in}
@media (prefers-reduced-motion: reduce){
  .f2y-zugedeckt,.gestrichen .balken,.gestrichen .drauf{transition:none}
  .gestrichen.zittert,.f2y-zugedeckt .kachel.lockt,
  .f2y-zugedeckt .kachel.kzerr{animation:none}
  #strobo-puls,#stroboszene.film .sz.frage.atmet{animation:none}
}

/* =====================================================================
   DAS ZWISCHENSPIEL (30.08.26): die Trennung, das Herzchen, der
   Umzugstag (k3s10, k3s12, zws1 bis zws5 aus fine, in die Grammatik
   dieses Spiels uebersetzt).
   ===================================================================== */

/* ---------- die verblassende Zeile (k3s10.l24) ----------
   Woerter geben sich einzeln ab, die Luecken bleiben stehen; das
   letzte Wort bleibt und wird DUNKLER statt blasser. */
.satz .vwort{transition:opacity .5s ease}
.satz .vwort.vweg{opacity:0}
.satz .vwort.vdunkel{color:#7c7a74;transition:color 1.2s ease}

/* ---------- die Nachricht als Banner ----------
   Das ist das GERAET, nicht die Buehne: Geraete-Leiter (geraet.css)
   und Systemschrift, wie eine Mitteilung oben am Handy. Faehrt oben
   ein, bleibt gut fuenf Sekunden, faehrt aus. */
.f2y-banner{position:fixed;left:50%;top:calc(10px + env(safe-area-inset-top, 0px));
  z-index:700;width:min(360px, calc(100vw - 24px));
  transform:translate(-50%, -130%);opacity:0;
  background:#161619;border-radius:14px;padding:9px 14px 10px;
  box-shadow:0 10px 26px rgba(0,0,0,.55), 0 2px 5px rgba(0,0,0,.3);
  font-family:var(--werkzeug);
  transition:transform .45s cubic-bezier(.25,.8,.3,1), opacity .45s ease;
  pointer-events:none}
.f2y-banner.da{transform:translate(-50%, 0);opacity:1}
.f2y-banner .fb-wer{font-size:10.5px;letter-spacing:.04em;color:#9a9aa0;
  margin-bottom:2px}
.f2y-banner .fb-wer:empty{display:none}
.f2y-banner .fb-text{font-size:13px;line-height:1.4;color:#e2e2e6}

/* ---------- die Quinn-Stelle: das Bild im Gegenlicht ---------- */
.f2y-quinnstelle{display:flex;justify-content:center;padding:26px 0 10px;
  opacity:0;transition:opacity .6s ease}
.f2y-quinnstelle.an{opacity:1}
.f2y-quinnstelle img{display:block;width:min(150px, 40vw);height:auto}

/* ---------- das Herzchen (k3s12) ----------
   Der Bogen liegt offen (Stufe 3, dunkles Papier — fines weisses
   Laken kommt nicht mit: Weiss ist hier Ereignis, keine Flaeche).
   Das Herzchen sitzt winzig oben links, blendet ein und POCHT
   minimalst; das Easter Egg fuellt es walblau (Fabis Farbe). */
.f2y-herzchen{display:flex;justify-content:center;padding:14px 0 8px;
  opacity:0;transition:opacity .6s ease}
.f2y-herzchen.an{opacity:1}
#herzbogen{position:relative;width:min(340px, 90vw);height:min(360px, 44vh)}
.bogenherz{position:absolute;left:7%;top:6%;width:22px;height:20px;
  z-index:3;cursor:default;opacity:0;transition:opacity .8s ease}
.bogenherz svg{display:block;width:100%;height:100%;overflow:visible}
.bogenherz svg path{fill:none;stroke:#8f8f8f;stroke-width:1.2;
  stroke-linecap:round;stroke-linejoin:round;
  transition:fill 1.2s ease, stroke 1.2s ease}
.bogenherz.entwickelt{opacity:1;animation:herz-pocht 2.4s ease-in-out infinite}
@keyframes herz-pocht{0%,100%{transform:scale(1)}50%{transform:scale(1.09)}}
.bogenherz.gefuellt svg path{fill:var(--walblau);stroke:var(--walblau)}

/* ---------- der Transporter (zws3): das Packspiel ----------
   Farben: Flaechen sind Buehne, Konturen die Zeichnungs-Graus der
   Objekte (geraet.js), jede duenne Kante ist Weiss mit wenig
   Deckkraft — keine neue Farbe (Farbtafel). Der Landeplatz-Geist
   und der Fallschacht sind Moewe: das ist die Welt, die zeigt, wo
   es landet, nicht der Daumen. */
.f2y-transporter{opacity:0;transition:opacity .5s ease}
.f2y-transporter.an{opacity:1}
#ov-pack{position:fixed;inset:0;z-index:520;background:var(--grund);
  opacity:0;transition:opacity .35s ease;overflow:hidden auto}
#ov-pack.aktiv{opacity:1}
.packbuehne{position:relative;width:100%}
#ov-pack .packbuehne{height:100%}
/* hochkant steht nur die Dreh-Anweisung (wie die Karte im Flur) */
.packbuehne.handy .pack-dreh{position:absolute;inset:0;z-index:6;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:14px;background:var(--grund);text-align:center;padding:0 30px}
.packbuehne.handy.liegt .pack-dreh{display:none}
.packbuehne.handy.zurueck.liegt .pack-dreh{display:flex;background:none;
  position:absolute;inset:auto 12px 8px auto;flex-direction:row;gap:8px;
  z-index:8}
.pack-dreh .kd-handy{display:block;width:34px;height:60px;border:2px solid #8a8a8a;
  border-radius:7px;position:relative}
.pack-dreh .kd-handy::after{content:'';position:absolute;left:50%;bottom:5px;
  width:5px;height:5px;margin-left:-2.5px;border-radius:50%;background:#8a8a8a}
.pack-dreh .kd-wort{font-family:var(--s-regie);font-size:calc(var(--barlow) * .8);
  letter-spacing:.14em;text-transform:uppercase;color:var(--regie)}
.pack-dreh .kd-rechner{font-family:var(--s-regie);font-size:calc(var(--barlow) * .62);
  letter-spacing:.14em;text-transform:uppercase;color:#6f6f6f;line-height:1.55}
.packbuehne.handy .pack-feld{display:none}
.packbuehne.handy.liegt .pack-feld{display:flex}
/* das Feld ist eine Saeule: der Wagen, darunter der Gehweg */
.pack-feld{position:relative;display:flex;flex-direction:column;padding:8px 0 4px}
#ov-pack .pack-feld{height:100%;box-sizing:border-box;
  padding:8px 10px calc(4px + env(safe-area-inset-bottom, 0px))}
/* der Laderaum */
#laderaum{position:relative;margin:6px auto 22px;
  border:1px solid rgb(255 255 255 / .14);border-top-color:rgb(255 255 255 / .08);
  background:rgb(255 255 255 / .02)}
#ov-pack .liegt #laderaum{margin:4px auto auto}
#laderaum .lreifen{position:absolute;left:12%;right:12%;bottom:-16px;
  display:flex;justify-content:space-between;pointer-events:none}
#laderaum .lreifen span{width:26px;height:26px;border-radius:50%;
  border:1.4px solid #5f5f5f;background:var(--buehne);
  box-shadow:inset 0 0 0 4px rgb(255 255 255 / .05)}
#laderaum.traegt{border-color:rgb(255 255 255 / .22)}
#laderaum.lruettelt{animation:lruettel .12s linear infinite}
@keyframes lruettel{0%{transform:translateX(0)}25%{transform:translateX(-2px)}
  75%{transform:translateX(2px)}100%{transform:translateX(0)}}
#laderaum.lnein{animation:lnein .26s ease}
@keyframes lnein{0%,100%{transform:translateX(0)}30%{transform:translateX(-3px)}
  60%{transform:translateX(3px)}}
/* die hintere Schicht: fertig gepackt, Bild, kein Spiel — eine
   Stufe dunkler, damit vorn Figur und hinten Grund ist */
.rueckwand{position:absolute;inset:0;transform-origin:center bottom;
  opacity:.3;pointer-events:none}
.rwkiste{position:absolute;box-sizing:border-box;
  border:1px solid rgb(255 255 255 / .1);background:var(--buehne)}
.rwkiste .band{position:absolute;background:rgb(255 255 255 / .05)}
.rwkiste .band.quer{left:0;right:0;top:44%;height:12%}
.rwkiste .band.hoch{top:0;bottom:0;left:44%;width:12%}
.rwkiste .naht{position:absolute;background:rgb(255 255 255 / .07)}
.rwkiste .naht.hoch{top:0;bottom:0;left:50%;width:1px}
.rwkiste .naht.quer{left:0;right:0;top:50%;height:1px}
/* die vordere Ebene und die Teile */
.lschicht{position:absolute;inset:0}
.lteil,.lteilplatz{position:relative}
.lteil{cursor:pointer;touch-action:none}
.lteil.zurueck{animation:lzurueck .9s ease}
@keyframes lzurueck{0%{opacity:.2}40%{opacity:1}100%{opacity:1}}
.lteil.nein{animation:lnein .26s ease}
.lteil.nichtweg{opacity:.35}
.lteilplatz{position:absolute}
.lteilplatz.einrasten{animation:leinrast .22s cubic-bezier(.2,1.3,.4,1)}
@keyframes leinrast{0%{transform:scale(1.06)}100%{transform:scale(1)}}
.lteilplatz.faellt{animation:lfaellt .5s ease-in forwards}
@keyframes lfaellt{to{transform:translateY(26px);opacity:0}}
.lzelle{position:absolute;box-sizing:border-box;background:var(--buehne);
  border:1px solid rgb(255 255 255 / .16)}
.geformt .lbild{position:absolute;inset:0;display:flex;
  align-items:flex-end;justify-content:center;pointer-events:none}
.geformt .lbild svg{width:100%;height:100%;display:block}
.geformt .lbild .drehrahmen{position:absolute;left:50%;top:50%}
.geformt .lbild .drehrahmen svg{width:100%;height:100%}
.geformt.mitbild .lzelle{border-color:rgb(255 255 255 / .05);background:none}
/* die Aufschrift: Fines Edding — nur noch auf Kartons */
.lbl{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;text-align:center;pointer-events:none;
  font-family:var(--s-fine);line-height:1.15;letter-spacing:.04em;
  color:rgb(236 233 226 / .78)}
.aufgehoben{filter:brightness(1.18);pointer-events:none}
/* der Drehknopf: Butter-Kreis in der linken Flanke, ueber dem
   Zettel — steht nur, solange etwas in der Hand ist. So dreht der
   zweite Daumen, waehrend der erste traegt. */
#ldrehknopf{position:absolute;z-index:7;
  left:calc((100% - var(--wagen, 440px)) / 4);top:42%;
  transform:translate(-50%,-50%);
  width:56px;height:56px;border-radius:50%;
  /* moewenblau seit dem 30.08.26: er steht nur da, wenn man ihn
     drehen soll, also ist er die Farbe des Daumens. */
  background:rgb(var(--klecks-rgb));color:var(--tinte-dunkel);
  display:flex;align-items:center;justify-content:center;
  font-size:27px;line-height:1;
  box-shadow:0 1px 8px rgb(0 0 0 / .45);
  opacity:0;pointer-events:none;transition:opacity .2s ease}
#ldrehknopf::after{content:'';position:absolute;inset:-12px;border-radius:50%}
#laderaum.traegt ~ #ldrehknopf{opacity:1;pointer-events:auto}
/* das Griff-Wort: sagt beim Anfassen einmal, was man haelt */
#lgriff{font-family:var(--s-regie);font-size:calc(var(--barlow) * .85);
  letter-spacing:.14em;text-transform:uppercase;color:var(--tinte-dunkel);
  background:var(--tinte);border-radius:4px;padding:2px 10px;
  box-shadow:0 2px 7px rgb(0 0 0 / .4);
  opacity:0;transition:opacity .3s ease}
#lgriff.da{opacity:1}
/* das Teil, um das die Rueckfrage geht */
.lteil.zurwahl{filter:brightness(1.4)}
/* Landeplatz-Geist und Fallschacht: die Welt zeigt, wo es landet */
.lgeist{position:absolute;pointer-events:none;z-index:3}
.lgeist span{position:absolute;box-sizing:border-box;
  background:rgb(var(--moewe-rgb) / .14)}
.lspalte{position:absolute;pointer-events:none;z-index:2;
  background:linear-gradient(to bottom, rgb(var(--moewe-rgb) / 0), rgb(var(--moewe-rgb) / .07))}
/* Regie, Stimme und die Wahl-Kaesten liegen ueber dem oberen Rand
   des Wagens — unten gehoert alles dem Gehweg */
.pack-zeile{position:absolute;left:50%;top:6px;transform:translateX(-50%);
  width:min(94%, 36em);display:flex;flex-direction:column;align-items:center;
  gap:6px;z-index:5;pointer-events:none;text-align:center}
#lhinweis{font-family:var(--s-regie);font-size:var(--barlow);line-height:var(--zeile-barlow);
  letter-spacing:.14em;text-transform:uppercase;color:var(--tinte-dunkel);
  background:var(--tinte);border-radius:4px;padding:3px 10px;
  box-shadow:0 2px 7px rgb(0 0 0 / .4)}
#lhinweis:empty{display:none}
#lstimme{font-size:var(--hanken);line-height:var(--zeile);color:var(--tinte);
  background:rgb(14 14 16 / .84);border-radius:7px;padding:2px 10px;
  opacity:0;transition:opacity .4s ease}
#lstimme.da{opacity:1}
/* die Aktions-Kaesten sind echte Wahl-Kaesten (Leseschrift, was
   nicht passt, bricht um) — sie stehen in der freien Flanke rechts
   neben dem Wagen, nie ueber der Ladung */
.pack-knoepfe{position:absolute;z-index:5;right:8px;top:6px;
  bottom:calc(var(--gehweg, 72px) + 26px);
  width:calc((100% - var(--wagen, 440px)) / 2 - 18px);min-width:84px;
  display:flex;flex-direction:column;gap:8px;justify-content:center;
  align-items:stretch;pointer-events:none}
.pack-knoepfe .pk-kasten{display:none;pointer-events:auto}
.pack-knoepfe .pk-kasten.an{display:block}
/* die Anleitung: einmal vorweg als grosser Zettel, danach faltet
   sie sich nach unten links */
#lanleitung{position:absolute;z-index:9;left:50%;top:50%;
  width:min(30em, 88%);box-sizing:border-box;padding:16px 18px 12px;
  background:var(--tinte);
  transform:translate(-50%,-50%) rotate(-1.2deg);
  box-shadow:0 10px 30px rgb(0 0 0 / .55), 0 2px 6px rgb(0 0 0 / .35);
  transition:transform .38s ease, opacity .3s ease}
.packbuehne:not(.anleitung) #lanleitung{opacity:0;pointer-events:none;
  transform:translate(-110%, 62%) scale(.1) rotate(-4deg)}
.la-text{font-family:var(--s-regie);font-size:var(--barlow);line-height:var(--zeile-barlow);
  letter-spacing:.14em;text-transform:uppercase;color:var(--tinte-dunkel)}
.la-weiter{margin-top:10px;text-align:right;font-family:var(--s-regie);
  font-size:calc(var(--barlow) * .82);letter-spacing:.14em;text-transform:uppercase;
  color:var(--tinte-dunkel);opacity:.6}
/* der Zettel unten links: immer da, immer antippbar */
#lzettel{position:absolute;left:10px;bottom:calc(6px + env(safe-area-inset-bottom, 0px));
  z-index:8;display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:4px 7px;color:var(--regie);opacity:.85;transition:opacity .25s ease}
#lzettel svg{width:30px;height:33px;transform:rotate(-4deg)}
#lzettel .lz-wort{font-family:var(--s-regie);font-size:calc(var(--barlow) * .68);
  letter-spacing:.14em;text-transform:uppercase}
#laderaum.traegt ~ #lzettel{opacity:0;pointer-events:none}
.packbuehne.anleitung #lzettel{opacity:0;pointer-events:none}
/* der Gehweg: eine seitlich rollende Reihe — Vorrat und Bordstein
   sind derselbe Ort */
#gehweg{position:relative;flex:none;height:var(--gehweg, 72px);
  display:flex;align-items:flex-end;gap:12px;
  padding:6px 14px 8px 92px;box-sizing:content-box;
  overflow:auto hidden;scrollbar-width:thin;touch-action:pan-x;
  border-top:1px solid rgb(255 255 255 / .18)}
#lpool{display:flex;align-items:flex-end;gap:12px;flex:none}
#gehweg .lteil{position:relative;flex:none}
#gehweg .lteil::after{content:'';position:absolute;inset:-8px calc(-1 * var(--griff, 8px))}
#lpool.entscheidung .lteil{outline:none}
/* der Bordstein-Abschnitt: was hier steht, bleibt hier */
#strasse{display:none;position:relative;flex:none;align-items:flex-end;gap:12px;
  padding:14px 14px 0 2px;margin-right:2px;
  border-right:1px dashed rgb(255 255 255 / .25)}
#strasse.bewohnt{display:flex}
#strasse .strasse-wort{position:absolute;left:2px;top:0;white-space:nowrap;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .68);
  letter-spacing:.14em;text-transform:uppercase;color:var(--regie);opacity:.6}
#strasse .strasse-reihe{display:flex;gap:12px;align-items:flex-end}
.abgestellt{display:flex;flex-direction:column;align-items:center;gap:2px;
  opacity:0;transition:opacity .5s ease, filter .4s ease}
.abgestellt.da{opacity:.8}
.abgestellt.gesehen{opacity:1;filter:brightness(1.2)}
.abgestellt .abgestellt-bild{position:relative}
.abgestellt .lteilplatz{position:relative;left:0;top:0}
.abgestellt .beschriftung{font-family:var(--s-fine);font-size:calc(var(--patrick) * .8);
  color:rgb(236 233 226 / .6)}

/* ---------- Wieczorek (zwS3c) ---------- */
.f2y-wieczorek{position:relative}
.wie-ding{display:flex;justify-content:center;padding:14px 0 4px;
  opacity:0;transition:opacity .5s ease}
.wie-ding.an{opacity:1}
.wie-ding .blackbox{position:relative}
.wie-ding .tipp-hier{left:50%;top:38%;margin-left:calc(var(--kl) / -2)}
.wie-tippding .blackbox{cursor:pointer}
/* der Zettel im Geschenk: Zettelpapier (Farbtafel), Kugelschreiber —
   Leseschrift, denn die drei Handschriften sind vergeben
   (⟦OFFEN, Laura⟧, ob Wieczorek eine eigene bekommt) */
.wie-zettel{background:#e9e6df;color:#26241f;border-radius:2px;
  padding:12px 18px;max-width:250px;transform:rotate(-3deg);
  font-family:var(--s-lesen);font-size:calc(var(--hanken) * .88);line-height:1.45;
  box-shadow:0 10px 26px rgba(0,0,0,.55), 0 2px 5px rgba(0,0,0,.3)}
.wie-hand .blackbox{min-width:170px;min-height:64px;cursor:pointer;
  touch-action:none;display:flex;align-items:center;justify-content:center}
.wie-flur .blackbox{width:min(100%, 30rem)}
.wie-flur svg{width:100%;height:auto;display:block}
/* der Namensbalken: uebermalt in Tinte, wackelt, geht NIE auf */
.namensbalken{display:inline-block;width:5.2em;height:.82em;
  vertical-align:-.06em;background:var(--tinte);border-radius:2px;
  cursor:pointer}
.namensbalken.ruckelt{animation:nbruckel .3s ease}
@keyframes nbruckel{0%,100%{transform:translateX(0) rotate(0)}
  30%{transform:translateX(-2px) rotate(-1deg)}
  65%{transform:translateX(2px) rotate(.8deg)}}

/* ---------- der Schluessel (zws4) ---------- */
.f2y-schluessel{display:flex;flex-direction:column;align-items:center;
  gap:16px;padding:14px 0 6px;opacity:0;transition:opacity .5s ease}
.f2y-schluessel.an{opacity:1}
.f2y-schluessel .blackbox{position:relative;cursor:pointer}
/* es ruft: der Stups — Atem auf dem Ding, Stups auf der Zeichnung
   (getrennte Elemente, design.html Baustein 5) */
.es-ruft{animation:ruf-atem 3.4s ease-in-out infinite}
.es-ruft svg{animation:ruf-stups 4.6s ease-in-out infinite}
/* der Umschlag: Zettelpapier, die Aufschrift in der Spielhand */
.f2y-umschlag{position:relative;width:min(300px, 78vw);box-sizing:border-box;
  aspect-ratio:1.62;background:#e9e6df;border-radius:2px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;text-align:center;
  box-shadow:0 12px 26px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);
  opacity:0;transition:opacity .5s ease, transform .45s ease, max-height .45s ease}
.f2y-umschlag.an{opacity:1}
.f2y-umschlag .bu-schrift{font-family:var(--s-hand);font-weight:600;
  font-size:var(--caveat-hand);line-height:1.2;color:#26241f;
  transform:rotate(-1.2deg)}
.f2y-umschlag .bu-klein{opacity:.72}
.f2y-umschlag .bu-falz{position:absolute;left:6%;right:6%;top:50%;height:1px;
  background:#c9c3b5;opacity:0;transition:opacity .4s ease}
.f2y-umschlag.bu-gross{transform:scale(1.12)}
.f2y-umschlag.bu-geknickt .bu-falz{opacity:1}
.f2y-umschlag.bu-gefaltet{transform:scaleY(.5) translateY(50%);
  overflow:hidden}
.f2y-umschlag.bu-gefaltet .bu-schrift{opacity:.4;transition:opacity .3s}
.f2y-umschlag.bu-fort{opacity:0;transform:scaleY(.5) translateY(160%)}

/* ---------- der Kuechenboden (zws5): der Ableger ---------- */
.f2y-ableger{display:flex;justify-content:center;padding:14px 0 4px;
  opacity:0;transition:opacity .5s ease}
.f2y-ableger.an{opacity:1}

@media (prefers-reduced-motion: reduce){
  .satz .vwort,.f2y-banner,.bogenherz,.f2y-quinnstelle,.f2y-herzchen,
  .wie-ding,.f2y-schluessel,.f2y-umschlag,.f2y-ableger,
  .f2y-transporter,.abgestellt,#lanleitung,#lzettel,#ldrehknopf,#lgriff{transition:none}
  .bogenherz.entwickelt,.es-ruft,.es-ruft svg,.namensbalken.ruckelt,
  #laderaum.lruettelt,.lteilplatz.einrasten,.lteil.zurueck{animation:none}
}

/* =====================================================================
   KAPITEL-4-REST UND DER K5-ANFANG (30.08.26): der Ankunftsabend,
   das Klingelschild, der Sonntag ohne Quinn, das Auspacken (k4s1,
   k4s3, quinnweg, k4s5 aus fine, in die Grammatik dieses Spiels
   uebersetzt).
   ===================================================================== */

/* ---------- die Sinkzeile: der Satz haelt sich nicht mehr ----------
   Er sinkt ein paar Pixel, wird enger und blasser — und bleibt so
   haengen (fines Probe "Sinken", ~3,5 s). Nur Lage, Laufweite und
   Deckkraft; keine Farbe (die Opazitaet traegt allein). */
.satz.sinkt{transform:translateY(11px);letter-spacing:-.012em;opacity:.55;
  transition:transform 3.5s ease, letter-spacing 3.5s ease, opacity 3.5s ease}
/* geht die gesunkene Zeile, gilt wieder der schnelle Takt — sonst
   risse zeile() sie mitten im 3,5s-Fading heraus (Befund 30.08.26) */
.satz.sinkt.weg{transition:opacity var(--takt-zeile-weg, .45s) ease}

/* ---------- die Briefkastenwand (k4s3) ----------
   Zwoelf Kaesten, Raster 3x4 (schmal: 2 Spalten). Die Zeichnung ist
   die Handzug-Flaeche in Buehnenfarbe mit den Zeichnungs-Graus; die
   Schilder sind kleine Papier-Artefakte: geschwaerzt (Tinte-Balken),
   gedruckt (aufgedeckt — Geraete-Konvention, Systemschrift wie jedes
   gedruckte Artefakt), gepraegt (Dymo — Regie-Register, versal) oder
   IHRES: beschriftet in Patrick Hand, denn sie schreibt es selbst. */
.f2y-klingelschild{opacity:0;transition:opacity .5s ease}
.f2y-klingelschild.an{opacity:1}
.bkwand{display:grid;grid-template-columns:repeat(3, 1fr);gap:10px 12px;
  max-width:min(var(--spalte), 94%);margin:16px auto 6px;
  padding:14px 12px;border:1px solid rgb(255 255 255 / .1)}
@media (max-width: 359px){ .bkwand{grid-template-columns:repeat(2, 1fr)} }
.briefkasten{position:relative;cursor:pointer}
.briefkasten .bkbild{display:block;width:100%;height:auto}
.bkschild{position:absolute;left:14%;right:14%;top:38%;height:30%;
  display:flex;align-items:center;justify-content:center;overflow:hidden;
  background:#e9e6df;border-radius:1px;color:#26241f;
  box-shadow:0 1px 2px rgba(0,0,0,.4)}
.bkschild.leer{background:#fbf7ee}   /* IHRES: Fines Papier (Farbtafel) */
.bkschild .bkschwarz{display:block;height:52%;background:#26241f;
  border-radius:1px;opacity:.92}   /* die Zettel-Tinte: der Balken muss
  auf dem hellen Papier DUNKEL sein (Befund 30.08.26 — var(--tinte)
  war heller Balken auf hellem Schild, unsichtbar) */
/* aufgedeckt: der gedruckte Zettel-Name (Artefakt, nicht Erzaehlung) */
.bkschild.aufgedeckt{font-family:var(--s-regie);
  font-size:calc(var(--barlow) * .62);letter-spacing:.08em;
  text-transform:uppercase}   /* gedruckte Namen im Regie-Register,
  skaliert wie der Stempel-Text — Systemschrift bleibt der Werkbank */
/* das gepraegte Dymo-Band: dunkel, helle Praegeschrift, versal */
.bkschild.dymo{background:#26241f;color:#e9e6df;
  font-family:var(--s-regie);font-size:calc(var(--barlow) * .62);
  letter-spacing:.12em;text-transform:uppercase}   /* das gepraegte
  Band traegt den Zettel-Zweiklang vertauscht (Farbtafel) */
/* die Eingabe: ihr Schild, ihre Hand */
.bkschild.eingabe{overflow:visible;background:#fbf7ee}
.bkschild.eingabe .bkform{position:absolute;left:-8%;right:-8%;top:-4px;
  display:flex;flex-direction:column;gap:6px;z-index:4}
.bkschild.eingabe input{box-sizing:border-box;width:100%;
  background:#fbf7ee;color:#1f1d1a;border:0;border-radius:1px;
  padding:5px 8px;font-family:var(--s-fine);font-size:var(--patrick);
  line-height:1.45;box-shadow:0 2px 6px rgba(0,0,0,.45)}
.bkschild.eingabe input::placeholder{color:#1f1d1a;opacity:.5}
.bkschild.eingabe .bkform .wahl{align-self:center;
  font-size:calc(var(--barlow) * .8);font-family:var(--s-regie);
  letter-spacing:.14em;text-transform:uppercase;line-height:1.4;
  color:var(--tinte)}   /* EINTRAGEN ist eine Entscheidung: derselbe
  gestrichelte Kasten wie jede Wahl (Befund 30.08.26 — vorher ein
  erfundener Pill-Knopf) */
.bkschild.beschriftet{font-family:var(--s-fine);font-size:var(--patrick);
  line-height:1.1;transform:rotate(-.8deg)}
/* die Tipp-Einladung auf ihrem leeren Schild (Baustein 4) */
.bk-tipp{left:50%;top:52%;margin-left:calc(var(--kl) / -2);margin-top:calc(var(--kl) / -2)}
/* der Sticker auf der Tuer: klein, sichtbar schief (Drehung aus JS) */
.bktuer-sticker{position:absolute;left:56%;top:66%;width:26%;
  transform:rotate(var(--stickerdreh, 0deg));
  opacity:0;transition:opacity .5s ease;pointer-events:none}
.bktuer-sticker.drauf{opacity:1}
.bktuer-sticker svg{display:block;width:100%;height:auto}
/* die zwei Sticker als Bilder — gewaehlt wird mit den Kaesten */
.st-reihe{display:flex;justify-content:center;gap:26px;flex-wrap:wrap;
  padding:12px 0 4px;opacity:0;transition:opacity .5s ease}
.st-reihe.an{opacity:1}
.st-reihe .blackbox{width:120px;height:104px}

/* ---------- das Freilassen (k4s5): die Glaeser, noch einmal ---------- */
.f2y-freilassen{position:relative;max-width:min(400px, 94%);
  margin:10px auto;opacity:0;transition:opacity .9s ease}
.f2y-freilassen.an{opacity:1}
/* "Rostock" in ihrer Hand auf dem pinken Glas */
.tr-rostock{position:absolute;left:50%;top:26%;
  transform:translateX(-50%) rotate(-2deg);
  font-family:var(--s-fine);font-size:var(--patrick);line-height:1.1;
  color:var(--tinte);opacity:0;transition:opacity 1.4s ease;
  pointer-events:none;white-space:nowrap}
.tr-rostock.da{opacity:.92}
/* die freigelassenen Punkte: sie steigen aus der Oeffnung und
   verloeschen (ein Weg, kein Hin und Her) */
.tr-fly.tr-frei{animation:tr-freilassen 2.6s ease-out forwards}
@keyframes tr-freilassen{
  0%{transform:translateY(0);opacity:1}
  70%{opacity:.85}
  100%{transform:translateY(calc(-1 * var(--freiweg, 64px)));opacity:0}}

@media (prefers-reduced-motion: reduce){
  .satz.sinkt{transition:none}
  .f2y-klingelschild,.st-reihe,.bktuer-sticker,.f2y-freilassen,
  .tr-rostock{transition:none}
  .tr-fly.tr-frei{animation:none;opacity:0}
}

/* =====================================================================
   DER K5-REST UND DIE ANKUNFT (30.08.26): das Ticket, das Warten,
   Nordholz (k4s6, k4s7, anks1 aus fine, in die Grammatik dieses
   Spiels uebersetzt).
   ===================================================================== */

/* ---------- das Ticket (k4s6) ----------
   Der Browser ist GERAET: Systemschrift und Geraete-Leiter, wie der
   Messenger. Die Denkzeile unterm Inhalt ist ihre Stimme im Kopf —
   Leseschrift, aber im Geraete-Rahmen gedaempft. */
.f2y-ticket{display:flex;flex-direction:column;align-items:center;
  padding:14px 0 6px;opacity:0;transition:opacity .5s ease}
.f2y-ticket.an{opacity:1}
.tk-kiste{position:relative;cursor:pointer;transition:transform .6s ease}
.tk-kiste.tk-zoom{transform:scale(1.15)}
.tk-kiste .tipp-hier{left:50%;top:44%;margin-left:calc(var(--kl) / -2)}
.tk-kopf{display:flex;align-items:center;justify-content:space-between;
  gap:10px;padding:10px 16px 8px;font-family:var(--werkzeug);
  font-size:14px;font-weight:600;color:#e2e2e6}
.tk-gknopf{font-family:var(--werkzeug);font-size:11.5px;color:#9a9aa0;
  padding:6px 10px;border:1px solid #3a3a3a;border-radius:13px}
.wtabs{display:flex;gap:8px;padding:0 16px 8px}
.wtabs button{flex:1;padding:7px 0;font-family:var(--werkzeug);
  font-size:12px;letter-spacing:.08em;color:#9a9aa0;
  border:1px solid #3a3a3a;border-radius:9px}
.wtabs button.an{color:#e2e2e6;background:#25252a;border-color:#25252a}
.wtabs.tk-ein,.tk-karte.tk-ein,.tk-angebot.tk-ein{animation:tkEin .2s ease}
@keyframes tkEin{from{opacity:0}to{opacity:1}}
.tk-inhalt{flex:1 1 auto;min-height:0;overflow-y:auto;
  padding:6px 16px 10px;font-family:var(--werkzeug);color:#e2e2e6}
.tk-suchfeld{display:flex;align-items:center;gap:7px;
  background:var(--grund);border-radius:15px;padding:8px 13px;
  font-size:13px;color:var(--tinte)}
.tk-lupe{color:#75757b}
.tk-caret{display:inline-block;width:1.5px;height:1.05em;
  background:var(--tinte);opacity:.8;animation:w-blinkt 1.1s steps(1,end) infinite}
@keyframes w-blinkt{0%,49%{opacity:.8}50%,100%{opacity:0}}
.tk-karte{margin-top:12px;background:#25252a;border-radius:11px;
  padding:11px 14px;font-size:13px;line-height:1.45}
.tk-titel{letter-spacing:.04em}
.tk-sub{color:#8c8c92;font-size:11.5px}
.wro-tag{margin:4px 0 8px;font-size:10.5px;letter-spacing:.14em;
  color:#75757b}
.wro-zeile{padding:8px 2px;border-bottom:1px solid rgb(255 255 255 / .06);
  font-size:13px;letter-spacing:.05em;display:flex;flex-direction:column;gap:2px}
.wro-zeile.tk-fest{background:#25252a}   /* die Geraete-Blase (Leiter) — kein neuer Grauwert */
.tk-angebot{margin-top:12px;background:#25252a;border-radius:11px;
  padding:13px 14px;font-size:13px;line-height:1.5;text-align:center}
.tk-preis{display:inline-block;margin:6px 0;font-size:19px}
.tk-korbknopf,.tk-weiter button,.tk-kasse button{margin-top:8px;
  padding:9px 16px;border-radius:9px;background:#2b2b31;color:#e2e2e6;
  font-family:var(--werkzeug);font-size:13px}
.tk-korbknopf:disabled{opacity:.4}
.tk-weiter{text-align:center;padding-top:8px}
.tk-kasse{margin-top:14px;display:flex;flex-direction:column;gap:9px;
  text-align:center}
.tk-posten{display:flex;justify-content:space-between;
  background:#25252a;border-radius:9px;padding:9px 13px;font-size:13px}
.tk-label{color:#8c8c92;letter-spacing:.08em}
.tk-statuszeile{min-height:52px;display:flex;flex-direction:column;
  gap:8px;align-items:center}
.tk-status{font-size:13px;letter-spacing:.1em;color:#e2e2e6}
.tk-storno{padding:7px 13px;border:1px solid #3a3a3a;border-radius:9px;
  color:#9a9aa0;font-family:var(--werkzeug);font-size:12px;
  font-variant-numeric:tabular-nums}
.tk-fertig{margin-top:16px;display:flex;flex-direction:column;
  align-items:center;gap:12px;text-align:center}
.tk-danke{font-size:13.5px}
.tk-denk{flex:0 0 auto;min-height:40px;padding:8px 18px 12px;
  font-family:var(--s-lesen);font-size:var(--hanken);
  line-height:var(--zeile);color:rgb(236 233 226 / .8);text-align:center;
  font-style:italic}   /* die Leseschrift in IHRER einen Groesse —
  je Schrift eine Groesse gilt auch unterm Geraet */

/* ---------- das Warten (k4s7): die Tage ----------
   Der Halter nimmt die ganze Buehne und stellt den Tag in ihre
   MITTE (wie die Nacht, .f2y-nacht) — oben an der Kante geklebt sah
   der Tag aus wie ein Rest, nicht wie das eine Ding im Bild.
   Alle Tage liegen dabei in DERSELBEN Rasterzelle: der alte tritt an
   Ort und Stelle ab, der neue kommt an Ort und Stelle. Sonst stuende
   der neue Tag die halbe Sekunde des Austritts unter dem alten und
   spraenge beim Aufraeumen nach oben. */
.f2y-warten{position:absolute;inset:0;display:grid;
  place-content:center;place-items:center;
  opacity:0;transition:opacity .5s ease}
.f2y-warten.an{opacity:1}
.wt-tag{grid-area:1/1;
  display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:8px 0 4px;opacity:0;transition:opacity .6s ease}
.wt-tag.an{opacity:1}
/* Quinns Rueckkehr steht im Warten mit den Dingen auf einer Stufe:
   derselbe Zuschlag wie ihre vier Handgriffe (game.js, ZUSCHLAG) */
.f2y-warten .f2y-quinnstelle img{width:min(172px, 46vw)}
.wt-titel{font-family:var(--s-regie);font-size:var(--barlow);
  line-height:var(--zeile-barlow);letter-spacing:.14em;
  text-transform:uppercase;color:var(--regie)}
.wt-ding{position:relative;cursor:pointer}
.wt-ding .tipp-hier{left:50%;top:42%;margin-left:calc(var(--kl) / -2)}
.wt-wasser{position:absolute;left:50%;top:-4px;transform:translateX(-50%)}
.wt-zelt svg{display:block}
.wwetter{display:flex;flex-direction:column;align-items:center;gap:4px;
  margin-top:16px;font-size:12px;letter-spacing:.1em;color:#8c8c92}
.wwetter .grad{font-size:30px;color:#e2e2e6;letter-spacing:0}
.wwetter .lage{font-size:12px;color:#c2c2c8;letter-spacing:.04em}
.tk-inhalt .tk-gknopf{display:block;margin:16px auto 0}
.wspinner{width:22px;height:22px;margin:26px auto 0;border-radius:50%;
  border:2px solid #3a3a3a;border-top-color:#c2c2c8;
  animation:wdreht .8s linear infinite}
@keyframes wdreht{to{transform:rotate(360deg)}}

/* ---------- Nordholz (anks1): das Baendchen und Foto 1 ---------- */
.f2y-nordholz{display:flex;flex-direction:column;align-items:center;
  gap:10px;padding:10px 0 4px;opacity:0;transition:opacity .5s ease}
.f2y-nordholz.an{opacity:1}
.bd-reihe{position:relative;display:flex;align-items:center;
  justify-content:center;gap:28px;flex-wrap:wrap;padding:6px 0}
.bd-arm,.bd-band{position:relative}
.bd-band{cursor:grab;touch-action:none}
.bd-band:active{cursor:grabbing}
.bd-klon{position:absolute;z-index:5;pointer-events:none}
/* die Zieh-Einladung (Baustein 3): der kleine Klecks setzt an und
   zieht Richtung Arm — ein Weg, kein Hin und Her */
.bd-zug{position:absolute;left:18%;top:30%;--kl:48px;z-index:4;
  pointer-events:none;transition:opacity .25s}
.bd-zug.still{opacity:0}
.bd-zug .klecks{animation:bd-zieht 2.9s cubic-bezier(.35,0,.3,1) infinite}
@keyframes bd-zieht{
  0%{transform:translateX(14px);opacity:0}
  16%{transform:translateX(8px);opacity:.9}
  74%{transform:translateX(-30px);opacity:.9}
  100%{transform:translateX(-46px);opacity:0}}
.bd-kurbel{width:min(300px, 84vw)}
.bd-feld{display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:6px 0;opacity:0;transition:opacity .5s ease}
.bd-feld.an{opacity:1}
.bd-feld .bkform{display:flex;flex-wrap:wrap;gap:10px;
  align-items:center;justify-content:center}
.bd-feld input{box-sizing:border-box;width:min(300px, 76vw);
  background:#fbf7ee;color:#1f1d1a;border:0;border-radius:1px;
  padding:7px 11px;font-family:var(--s-fine);font-size:var(--patrick);
  line-height:1.45;box-shadow:0 2px 6px rgba(0,0,0,.45)}
.bd-feld input::placeholder{color:#1f1d1a;opacity:.5}
.bd-feld .wahl{font-size:calc(var(--barlow) * .8);
  font-family:var(--s-regie);letter-spacing:.14em;
  text-transform:uppercase;line-height:1.4;color:var(--tinte)}

@media (prefers-reduced-motion: reduce){
  .f2y-ticket,.tk-kiste,.wtabs.tk-ein,.tk-karte.tk-ein,
  .tk-angebot.tk-ein,.f2y-warten,.wt-tag,.f2y-nordholz,.bd-feld{transition:none;animation:none}
  .tk-caret,.wspinner,.bd-zug .klecks{animation:none}
}
