/* ==========================================================================
   reise.css — „Die Reise eines Belegs"

   Zwei Fassungen, ein Markup:

   BASIS (außerhalb der Media Query) = alle Kapitel untereinander im normalen
   Fluss, jedes im Endzustand, jeder Bildschirm in seinem eigenen Rahmen. Das
   ist, was ohne JavaScript, in alten Browsern und bei reduzierter Bewegung
   erscheint — eine vollwertige, lesbare Liste.

   PLAYER (prefers-reduced-motion: no-preference + [data-reise-mode="player"])
   = eine Bühne fester Höhe, alle Kapitel in derselben Rasterzelle, davor ein
   persistentes Gehäuse. Der Kapitelwechsel ist ein diskreter Zustandswechsel;
   innerhalb eines Kapitels läuft --sp von 0 nach 1. js/reise.js liefert --sp je
   Kapitel, die Lage des Gehäuses als --tel-x/--tel-y und die data-Attribute für
   Zustand und aktiven Beat.

   Die Sektion war bis August 2026 scroll-gekoppelt. Warum sie es nicht mehr
   ist, steht in §9 von .claude/rules/frontend-design.md — wer zurück will,
   liest das zuerst.

   KAPITEL STATT EINZELSZENEN: Ein Kapitel enthält mehrere Beats. Innerhalb eines
   Kapitels bleiben die Requisiten stehen — dieselbe Rechnung, dasselbe Gerät —
   und nur die Beschriftung wechselt. So bleibt sichtbar, dass es über die ganze
   Reise derselbe Beleg ist.

   Regeln für diese Datei:
     - Am Fortschritt hängen nur transform, opacity, stroke-dashoffset/-dasharray
       und offset-distance.
     - transition nur für Blenden (opacity/transform/visibility, bis 400 ms) und
       nie in einem Block, der den Fortschritt liest — dort liefe sie dem Tween
       hinterher.
     - Kein position: sticky. Kein !important; die Basis steht außerhalb der
       Media Query und gewinnt ohne Gewalt.
     - Kapitel und Captions werden nur durchsichtig, nie display:none.
     - Kein Requisit trägt `opacity: 0` als GRUNDWERT, wenn es zum Endzustand
       seines Kapitels gehört. Die Choreografie steht im Player-Zweig, die
       statische Fassung liest sie nicht — übrig bliebe ein Kapitel 1 ohne
       Sucher, ein Kapitel 3 ohne Quittung, ein Kapitel 6 ohne Belegkarten.
       Unsichtbar ANFANGEN dürfen sie trotzdem: Das erledigt ihre eigene
       --sp-Formel bei --sp 0. Den Grundwert behält nur, was am Ende unsichtbar
       ist — Scanrahmen, Schilder, Brieftaube, Fingertipp, Kopie.
     - Farben aus tokens.css, Belegkonstanten aus startseite.css.
   ========================================================================== */

@property --sp {
    syntax: "<number>";
    inherits: true;
    initial-value: 0;
}


/* Die Lage des Geräts. Sie steht am Player und nicht am Gehäuse, weil zwei
   Seiten sie lesen: das Gehäuse, das auf der Bühne steht, und der Bildschirm,
   der im Kapitel liegt und mitfahren muss. Ein Bildschirm, der stehen bleibt,
   während sein Rahmen wegfährt, ist der auffälligste Fehler dieser Sektion —
   und er entsteht bei JEDEM Kapitelwechsel, nicht nur bei den Sondereffekten. */
@property --tel-x {
    syntax: "<number>";
    inherits: true;
    initial-value: 0;
}

@property --tel-y {
    syntax: "<number>";
    inherits: true;
    initial-value: 0;
}

/* Die GRÖSSE des Geräts, getweent wie seine Lage — und aus demselben Grund am
   Player und nicht am Gehäuse: Bildschirm und Rahmen müssen dieselbe Zahl
   lesen, sonst sitzt der Inhalt in einem anders großen Telefon.

   Sie war die zweite Hälfte der Fokusregel, und die gilt nicht (FEATURE-0143):
   Das Handy bleibt groß, --lage-s steht in allen sieben Kapiteln auf 1; ein
   schrumpfendes Telefon lieferte vor allem hochkant nichts Erkennbares. Die Position folgt dem Fokus weiterhin: Wo etwas
   anderes die Hauptrolle hat — die Gebäude beim Einreichen, die Uhr beim
   Warten —, rückt das Gerät zur Seite, bleibt aber im Bild. Das ersetzt die
   frühere Liste von Sonderfällen, deren größter war, dass Kapitel 5 gar kein
   Gerät hatte und der Übergangstyp „warten" es aus dem Bild fahren musste.

   Das Tween-Werk trägt die Größe weiter — es steht nur überall dieselbe Zahl
   darin. Wer einen Maßstabswechsel wieder will, ändert eine Zahl je Kapitel,
   keinen Mechanismus. */
@property --tel-s {
    syntax: "<number>";
    inherits: true;
    initial-value: 1;
}

/* ===== Rahmen der Sektion ===== */

.reise {
    position: relative;
    /* Die Requisiten liegen absolut und ragen an mehreren Stellen bewusst über
       ihre Kunstfläche hinaus. Im Player fängt das die Bühne ab (overflow:
       clip); in der statischen Fassung gibt es keine Bühne, und dort schob das
       Kapitel 1 auf 390 px die Seite um 75 px seitwärts — eine Startseite, die
       sich am Handy quer schieben lässt.

       clip und nicht hidden: hidden erzeugte einen Scroll-Container, und clip
       darf senkrecht sichtbar bleiben. Waagerecht hat diese Sektion nichts zu
       verschenken, senkrecht schon (die Marke über der Spur). */
    overflow-x: clip;
    --rv: 1;
    /* Die Bühne ist ein Kasten fester Höhe, keine Scrollstrecke mehr. Sie lässt
       Platz für Kopfleiste, Einleitung, Spur und Steuerung — die Sektion soll
       auf einen Bildschirm passen, nicht auf acht.

       --reise-beat-len ist mit dem Scrubbing entfallen: Ein Beat hat keine
       Länge mehr, sondern eine Dauer, und die steht in reise.js. */
    --reise-stage-h: min(34rem, 62svh);

    /* ---- Der eine Anker ----------------------------------------------------
       Im Player steht die Kunstfläche IMMER an derselben Stelle der Bühne:
       ihre Mitte liegt --reise-kunst-mitte-x neben und --reise-kunst-mitte-y
       unter der Bühnenoberkante. Daran hängen beide Seiten desselben Telefons —
       das Gehäuse, das als Requisit auf der Bühne steht, und der Bildschirm,
       der im Kapitel liegt. Nur weil beide gegen DENSELBEN Anker rechnen,
       decken sie sich pixelgenau; läge das Gehäuse gegen die Bühnenmitte und
       der Bildschirm gegen ein Rasterfeld, ergäbe jede Breitenänderung einen
       anderen Versatz zwischen Rahmen und Inhalt.

       Vorher stand die Lage in left/right/top/margin-top und wurde je Szene
       noch einmal überschrieben. Getweent werden kann so etwas nicht: Am
       Fortschritt dürfen nur transform, opacity, stroke-* und offset-distance
       hängen (scripts/lint_template_idiom.py prüft das auch für --tel-x und
       --tel-y). Aus sechs Regelsätzen werden deshalb sechs Zahlenpaare. */
    --reise-kunst-breite: min(34rem, 46vw);
    --reise-kunst-halbhoch: calc(var(--reise-kunst-breite) * 0.375); /* 4:3 */
    /* ---- EINE MITTELACHSE, NICHT ZWEI ----
       Einleitung, Spur und Steuerung sind auf die Containermitte zentriert.
       Bild und Text zusammen lagen um 79 px daneben: rechts blieben 223 px
       Rand, links 65. Eine Kante, die von nichts aufgenommen wird, liest sich
       nicht als Asymmetrie, sondern als Versehen.

       Der Grund war eine geratene Zahl — −24 % der Bühnenbreite, und −23 % eine
       Stufe tiefer. Die Lage der Kunstfläche IST aber nicht frei: Sie folgt
       daraus, dass das Paar aus Bild und Text mittig stehen soll. Der Text hängt
       rechts an der Fläche, also muss die Fläche um die halbe Textspalte samt
       Abstand nach links. Das ist diese Zeile, und mehr ist es nicht.

       Sie stimmt damit auf jeder Breite und an jedem Breakpoint von selbst; die
       767er-Abfrage setzt sie auf 0, weil dort nichts nebeneinander steht. Zwei
       geratene Prozentzahlen sind ersatzlos entfallen. */
    --reise-kunst-mitte-x: calc(0px - (var(--reise-text-abstand)
                                       + var(--reise-text-breite)) / 2);
    --reise-kunst-mitte-y: 50%;

    /* Die Einheit der Lagezahlen. Waagerecht ist 1 „bündig am Rand der
       Kunstfläche", senkrecht ist 1 „halbe Kunstfläche" — zwei Einheiten, weil
       die Lagen es sind: seitlich stehen die Geräte am Rand, senkrecht sitzen
       sie ein paar Prozent unter der Mitte. */
    --tel-spanne-x: calc((var(--reise-kunst-breite) - var(--reise-geraet-breite)) / 2);
    --tel-spanne-y: var(--reise-kunst-halbhoch);

    /* Breiter als die früheren min(27rem, 32vw): Der Platz war da — er lag als
       223 px Rand rechts neben dem Text. Mit der zentrierten Achse fällt er zu
       gleichen Teilen an beide Seiten, und die Spalte darf ihn sich nehmen. */
    --reise-text-breite: min(31rem, 36vw);
    --reise-text-abstand: 2rem;
}

/* ---- Höhenbudget ----------------------------------------------------------
   Die Sektion muss auf einen Bildschirm passen; das ist der Kern dieses Umbaus
   und wird in code/tests/e2e/test_reise_player.py gemessen (höchstens 1,25
   Bildschirmhöhen). Die Höhe ist damit ein Budget wie jedes andere.

   Drei .container liegen in der Sektion (Einleitung, Player, Abschlussweg),
   und die Wave-Regel in cappuccino.css gibt jedem 4 rem Kopfabstand. Dreimal
   Luft schiebt die Bedienung unter die Falzkante, obwohl nur der erste Abstand
   eine Aufgabe hat. */
section.reise {
    padding-bottom: 4rem;
}

section.reise > .container {
    padding-top: 2rem;
}

section.reise > .container:first-child {
    padding-top: 2.5rem;
}

.reise-intro {
    max-width: 40rem;
    margin: 0 auto;
    text-align: center;
}

/* ---- Die sieben Sprungmarken ----------------------------------------------
   Sie liegen am KOPF des Players und alle sieben an derselben Stelle — das Ziel
   eines Kapitel-Links ist der Player, das Kapitel darin liest js/reise.js aus
   der Nummer. Vorher trugen die Stationen die IDs, und die stehen unter der
   Bühne: #beleg-reise-kapitel-5 scrollte auf den Knopf und schob die Bühne
   485 px über den Fensterrand.

   Absolut und ohne Maß, damit sie keine Zeile bilden: Der Zwischenraum im
   Markup ergäbe sonst eine Textzeile, und die Bühne rückte um deren Höhe nach
   unten. Der Abstand zur haftenden Kopfleiste steht als scroll-padding-top am
   <html> (cappuccino.css) und gilt für jede Sprungmarke im Haus — ein eigenes
   scroll-margin-top hier käme oben drauf und ließe die Bühne zu tief stehen. */
.reise-player {
    position: relative;
}

.reise-marken {
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
}

/* .reise-lead ist ersatzlos entfallen — siehe den Kommentar im Template. */

/* Zwei abgebaute Klassen aus dem Text der Sektion:

   .reise-interlude war die Atempause zwischen zwei Bühnen und ist mit der
   zweiten Bühne entfallen; sie war die Brücke dazwischen.

   Einen Schlusssatz (.reise-closing) gibt es nicht. Den Abstand zwischen
   Bühne und Abschlussweg trägt die Grundregel für section.reise > .container. */

/* ===== Kapitel und Beats: Basis ===== */

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

.reise-kapitel {
    /* Endzustand — die Basis zeigt jedes Kapitel fertig. */
    --sp: 1;
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    align-items: center;
    gap: 3rem;
    max-width: 70rem;
    margin: 5rem auto;
    padding: 0 1.5rem;
}

/* Wie viele Beats ein Kapitel hat, steht im Markup. Daran hängen die drei
   Fensterweiten weiter unten: Dieselbe Geste soll in einem Kapitel mit drei
   Beats nicht dreimal so schnell laufen wie in einem mit einem. */
.reise-kapitel[data-beats="1"] { --beats: 1; }
.reise-kapitel[data-beats="2"] { --beats: 2; }
.reise-kapitel[data-beats="3"] { --beats: 3; }

/* ---- Die sieben Gerätelagen -----------------------------------------------
   Wo das Telefon in diesem Kapitel steht und wie groß, als Zahlentripel gegen
   den Anker: --lage-x in Einheiten von --tel-spanne-x (1 = bündig am rechten
   Rand der Kunstfläche, -1 = am linken), --lage-y in Einheiten von
   --tel-spanne-y (0,12 = 6 % der Kunsthöhe unter der Mitte), --lage-s als
   Maßstab.

   Der Bildschirm im Kapitel liest sie statisch, js/reise.js liest sie aus und
   tweent das Gehäuse über --tel-x/--tel-y/--tel-s an dieselbe Stelle. Zwei
   Namen für dieselbe Lage, und das ist Absicht: --lage-* steht fest und darf
   deshalb in margin stehen, --tel-* bewegt sich und darf nur in transform
   stehen.

   DIE POSITION FOLGT DEM FOKUS, DIE GRÖSSE NICHT MEHR. Die Fokusregel stand
   ursprünglich in beiden Spalten (Position UND Maßstab); die dritte Spalte
   steht überall auf 1 (FEATURE-0143) — das Handy
   bleibt in den Schritten 6 bis 10 groß, weil der Wartezustand und die
   Abrechnung darauf lesbar bleiben sollen. Die Spalte selbst bleibt stehen:
   js/reise.js tweent sie weiter, und eine Lage ist ein Zahlentripel, auch wenn
   eine der Zahlen gerade überall gleich ist. Wo etwas anderes die Hauptrolle
   hat (die Gebäude beim Einreichen, die Uhr beim Warten), rückt das Gerät zur
   Seite — die Hauptrolle wird über die Position vergeben, nicht mehr über den
   Maßstab.

   Kapitel 5 stand hier bis August 2026 nicht: Es hatte keinen Bildschirm, also
   kein Gerät, und der Übergangstyp „warten" musste das Gehäuse eigens aus dem
   Bild messen und hinausfahren. Der Typ „warten" ist ersatzlos entfallen, und
   mit ihm zwei Messfunktionen in js/reise.js — die Uhr hat ihre Hauptrolle
   jetzt als große Kulisse HINTER dem Gerät. */
.reise-kapitel { --lage-x: 0; --lage-y: 0; --lage-s: 1; }
/* 0,88 statt 1 (Schritt 2, Desktop): Bündig am
   rechten Rand stand das Gerät zu dicht an der Textspalte. Ein Tick nach
   links gibt dem Abstand Luft; der Weg des Belegs hinter das Telefon rechnet
   über var(--lage-x) mit (siehe --vorn-x) und trifft weiterhin die Mitte.
   Hochkant setzt keine Abfrage Kapitel 1 um — dort gilt dieselbe Zahl. */
.reise-kapitel[data-kapitel="1"] { --lage-x:  0.88; --lage-y: 0;    --lage-s: 1; }
.reise-kapitel[data-kapitel="2"] { --lage-x:  0;   --lage-y: 0;    --lage-s: 1; }
/* Weiter rechts als früher: Die Zahlkarte liegt links daneben auf dem Tisch,
   und im Player steht sie 1,6 Sekunden lang neben dem Gerät statt einen Frame
   lang. Bei 0,2 überschnitten sich beide um rund 60 px. */
.reise-kapitel[data-kapitel="3"] { --lage-x:  0.6; --lage-y: 0.16; --lage-s: 1; }
/* Die Gebäude haben die Hauptrolle: Das Gerät rückt an den linken Rand,
   damit die Einreichung sichtbar irgendwohin fliegen kann. */
.reise-kapitel[data-kapitel="4"] { --lage-x: -1;   --lage-y: 0.12; --lage-s: 1; }
/* Warten: Die Uhr steht groß im Hintergrund, das Gerät davor. */
.reise-kapitel[data-kapitel="5"] { --lage-x:  0.62; --lage-y: 0.1;  --lage-s: 1; }
/* Dieselbe Lage wie Kapitel 7, und das ist der ganze Übergang „bleibt":
   Beide zeigen denselben Bildschirm, also gibt es keinen Weg zu gehen. Stünde
   hier eine andere Zahl, ruckte oder zappelte das Telefon zwischen zwei
   Bildern, die sich sonst nicht unterscheiden.

   Rechts statt links (Schritt 8): Der Kostenträger steht
   LINKS NEBEN dem Gerät, und die Abrechnung fliegt von dort sichtbar hinein.
   Das Gerät nimmt deshalb die rechte Seite — dieselbe Stellung wie in
   Kapitel 5, sein Bildschirm wechselt beim Ankommen nur den Inhalt. */
.reise-kapitel[data-kapitel="6"] { --lage-x:  0.62; --lage-y: 0;    --lage-s: 1; }
.reise-kapitel[data-kapitel="7"] { --lage-x:  0.62; --lage-y: 0;    --lage-s: 1; }

/* Kapitel 6 und 7 spiegeln dazu den Anker der linken Bühnenhälfte: --ziel-x
   steht sonst an der rechten Kante der Kunstfläche (Kapitel 4). Es ist EIN
   Anker für alles, was dort nacheinander steht — das Gebäude, die Belegkarten
   an seiner Stelle, in Kapitel 7 der frei stehende Entwurf — und der Flug
   liest ihn auch: Die Abrechnung landet damit ohne eigene Regel am Gerät. */
.reise-kapitel[data-kapitel="6"],
.reise-kapitel[data-kapitel="7"] {
    /* 7 statt der 5,5 rem der rechten Kante: bewusst ein Stück von der Kante
       weg zum Gerät hin — die Karten sollen NEBEN dem Handy stehen, nicht am
       Rand der Kunstfläche. */
    --ziel-x: calc(7rem * var(--rv) - var(--reise-kunst-breite) / 2);
}

/* ---- Maße der Bewegung ----------------------------------------------------
   Drei Weiten und zwei Wege für die ganze Sektion. Vorher standen hier sechzehn
   Fensterbreiten und fünf Weglängen; dieselbe Geste lief je nach Szene
   unterschiedlich schnell und unterschiedlich weit.

   Die Weiten rechnen in BEAT-Anteilen, nicht in --sp: --sp läuft über das ganze
   Kapitel, und Kapitel sind ein bis drei Beats lang. Ein Fenster von 0,06 --sp
   bedeutete in Kapitel 1 rund 73 px Scrollweg und in Kapitel 4 rund 24 px —
   dieselbe Zahl, dreifaches Tempo. Geteilt durch --beats braucht dieselbe Geste
   überall denselben Weg.

   Die Wege stehen in rem und skalieren über --rv mit der Bühne. Feste Pixel
   blieben auf schmalen Flächen stehen, während alles andere um 18 % schrumpfte. */
.reise-kapitel {
    --w-kurz: calc(0.12 / var(--beats, 1));    /* Marken, Haken, Statuswechsel */
    --w-mittel: calc(0.22 / var(--beats, 1));  /* Auf- und Abtritte */
    --w-lang: calc(0.7 / var(--beats, 1));     /* Wege über die Bühne */
    --weg-klein: calc(0.5rem * var(--rv));     /* Zeilen, Marken, Karten */
    --weg-gross: calc(1rem * var(--rv));       /* Geräte, große Flächen */
}

/* Basis: alle Beats eines Kapitels stehen untereinander und sind vollständig
   lesbar. Erst der Scrub-Modus legt sie übereinander und blendet sie durch —
   sonst gingen ohne JavaScript neun von sechzehn Texten verloren. */
.reise-captions {
    display: grid;
    gap: 2rem;
    max-width: 27rem;
}

/* Die Schritt-Zeile („SCHRITT 1" … „SCHRITT 11") ist ersatzlos entfallen.
   Sie zählte eine zweite, feinere Reihe als die Spur — über der markierten
   Station 4 stand „SCHRITT 7" —, und in Crema auf Milch kam sie auf 2,53:1,
   wo 4,5:1 verlangt sind. Zwei Zählungen für dieselbe Reise sind eine zu viel;
   die Spur ist die sichtbare, also bleibt sie allein. */

/* EIN DISPLAYSCHNITT JE SEKTION, UND DEN HAT DIE SEKTIONSÜBERSCHRIFT.
   „Die Reise eines Belegs" steht in Comfortaa auf 40 px, oben und mittig. Die
   Szenenüberschrift stand daneben in DERSELBEN Schrift auf rund 30 px — 74
   Prozent Größe bei sonst gleichen Merkmalen, und weil sie im optischen Zentrum
   neben dem Bild sitzt, gewann die kleinere den Blick. Zwei Überschriften
   gleichen Rangs sind kein Einstieg.

   Also: Grundschrift, Gewicht 600, rund 23 px, nach oben UND unten begrenzt.
   Der Rang steht jetzt in der Schriftfamilie und nicht mehr im Millimeter. */
.reise-caption h3 {
    margin-bottom: 0.75rem;
    font-family: var(--font-sans);
    font-size: clamp(1.25rem, 1.6vw, 1.45rem);
    font-weight: 600;
    color: var(--espresso);
}

.reise-caption p {
    margin: 0;
    font-family: var(--font-sans);
    font-size: 1.02rem;
    line-height: 1.65;
    color: var(--stone-500);
}

/* Bühne des einzelnen Kapitels: die Requisiten liegen darin absolut. */
.reise-art {
    position: relative;
    aspect-ratio: 4 / 3;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ==========================================================================
   PLAYER-FASSUNG

   Der Kapitelwechsel ist ein diskreter Zustandswechsel, kein getweenter Wert.
   Damit fallen die beiden verzahnten Überblend-Formeln ersatzlos weg, die
   unter Scrubbing nötig waren: Dort musste eine einzige stetige Größe alles
   tragen, also musste auch das Ein- und Ausblenden aus --sp gerechnet werden —
   und zwar in Beat-Einheiten, weil Kapitel ein bis drei Beats lang sind und
   ein --sp-Fenster sonst je nach Kapitellänge anders schnell liefe.

   Die Regel dahinter bleibt wörtlich dieselbe: Aus- und Einblenden laufen
   NACHEINANDER, nie überlappend. Überschrift und Fließtext hängen daran, und
   zwei Texte übereinander liest niemand. Nur die Mechanik wechselt — vom
   Fenster in --sp zum transition-delay.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

    /* Die Bühne ist ein Kasten fester Höhe im normalen Fluss. Kein sticky: Das
       Scroll-Scrubbing ist zweimal gebaut und zweimal verworfen worden, und
       scripts/lint_template_idiom.py hält die Entscheidung fest. */
    [data-reise-mode="player"] .reise-buehne {
        position: relative;
        height: var(--reise-stage-h);
        display: grid;
        place-items: center;
        /* clip statt hidden: erzeugt keinen Scroll-Container. */
        overflow: clip;
        /* Senkrecht gehört der Finger der Seite, waagerecht dem Player. Ohne
           diese Zeile entscheidet das der Browser erst nach dem ersten Frame,
           und der erste Wisch geht verloren. */
        touch-action: pan-y;
    }

    /* Das Gehäuse steht als Requisit auf der Bühne und wechselt beim
       Kapitelwechsel nur seine Lage: --tel-x/--tel-y kommen aus js/reise.js und
       werden dort getweent. Die Grundstellung ist die Mitte der Kunstfläche —
       exakt dieselbe Rechnung wie beim Bildschirm ein paar Zeilen tiefer.

       Rand statt Polster: In der statischen Fassung zeichnet der Bildschirm sein
       Gehäuse als Rand (--reise-geraet-rand breit). Im Player übernimmt das
       Gehäuse diese Aufgabe, also trägt es denselben Rand — sonst stünde die
       Szene im Player in einem dünneren Telefon als daneben. */
    [data-reise-mode="player"] .reise-geraet {
        display: block;
        position: absolute;
        left: 50%;
        top: var(--reise-kunst-mitte-y);
        margin: calc(0px - var(--reise-geraet-halbhoehe)) 0 0
                calc(var(--reise-kunst-mitte-x) - var(--reise-geraet-breite) / 2);
        padding: 0;
        border-width: var(--reise-geraet-rand);
        /* Unter die Kapitel: Der Bildschirm liegt IM Kapitel und muss über der
           Fläche des Gehäuses stehen, sonst deckt das Gehäuse ihn zu. */
        z-index: auto;
        /* Erst der Weg, dann der Maßstab: Mit transform-origin in der Mitte
           schiebt das translate den Mittelpunkt an seine Lage, und das scale
           danach dreht ihn nicht mehr weg. Andersherum skalierte es den Weg
           gleich mit. */
        transform: translate(calc(var(--tel-x, 0) * var(--tel-spanne-x)),
                             calc(var(--tel-y, 0) * var(--tel-spanne-y)))
                   scale(var(--tel-s, 1));
    }

    /* Die Blende steht bewusst in einem eigenen Block: Im Block darüber hängt
       das transform am Fortschritt, und eine transition dort liefe dem Tween
       hinterher. Getrennt nach Eigenschaften können sie sich nicht in die Quere
       kommen — der Weg gehört dem Tween, die Deckkraft dem Blatt. */
    [data-reise-mode="player"] .reise-geraet {
        transition: opacity 180ms linear;
    }

    /* In Kapitel 1 Beat 1 gibt es das Telefon erzählerisch noch nicht: Der
       Umschlag liegt auf dem Stapel, die Rechnung kommt heraus. Ein leeres
       Gehäuse daneben ist kein Requisit, sondern eine Vorwegnahme — es steht
       1,6 Sekunden lang schwarz im Bild und wartet auf seinen Auftritt. Es
       kommt mit dem Scan-Beat, zusammen mit dem Sucher darin. */
    [data-reise-mode="player"][data-active-kapitel="1"][data-active-beat="1"] .reise-geraet {
        opacity: 0;
    }

    /* Im Player kommt der Rahmen vom Gehäuse, der Bildschirm behält nur seine
       Fläche. Die Randbreite bleibt durchsichtig stehen, damit beide Fassungen
       dieselbe Geometrie haben. */
    [data-reise-mode="player"] .reise-screen {
        border-color: transparent;
        background: var(--flaeche);
        /* Sonst deckt die Fläche des Bildschirms den Rand des Gehäuses zu:
           Ein Hintergrund reicht standardmäßig BIS UNTER den Rand, und der ist
           hier 7 px breit und durchsichtig. Vom Gehäuse blieb dann eine
           Haarlinie übrig, wo ein Rahmen stehen sollte. */
        background-clip: padding-box;
    }

    /* Die Insel zeichnet im Player der Bildschirm, nicht das Gehäuse — obwohl
       sie zum Gehäuse gehört. Das Gehäuse liegt unter den Kapiteln (der
       Bildschirm muss über seiner Fläche stehen), und damit läge auch seine
       Insel darunter: unsichtbar in jedem Kapitel, das einen Bildschirm hat.
       Doppelt liegen die beiden nie, weil genau eine davon sichtbar ist. */
    [data-reise-mode="player"] .reise-geraet-insel {
        display: none;
    }

    /* Der Bildschirm steht an derselben Lage wie das Gehäuse, nur statisch: Er
       liest --lage-x/--lage-y direkt aus dem Kapitel, während das Gehäuse den
       getweenten Wert bekommt. Stehen beide still, sind sie deckungsgleich.

       Die Lage steht hier in margin und nicht in transform, weil transform in
       drei Szenen bereits der Choreografie gehört (das Telefon fährt in
       Kapitel 1 und 3 ins Bild). Zwei Transforms an einem Element gibt es nicht,
       zwei Margins schon.

       Die vier Selektorstufen sind nötig: `.reise-art--zahlung
       .reise-screen--banking` weiter unten wiegt drei und stünde sonst
       dagegen. */
    [data-reise-mode="player"] .reise-kapitel .reise-art .reise-screen {
        position: absolute;
        /* 50 % und nicht --reise-kunst-mitte-y: Der Bildschirm rechnet gegen
           die Kunstfläche, das Gehäuse gegen die Bühne. Die Kunstfläche liegt
           mit ihrer MITTE auf --reise-kunst-mitte-y — für den Bildschirm ist
           dieselbe Stelle deshalb seine eigene Mitte. Stand hier kurzzeitig
           dieselbe Variable, lagen Rahmen und Inhalt auf schmalen Flächen
           47 px auseinander. */
        left: 50%;
        top: 50%;
        right: auto;
        bottom: auto;
        margin: calc(0px - var(--reise-geraet-halbhoehe)
                     + var(--lage-y, 0) * var(--tel-spanne-y))
                0 0
                calc(0px - var(--reise-geraet-breite) / 2
                     + var(--lage-x, 0) * var(--tel-spanne-x));
    }

    /* Und er fährt mit. Der Bildschirm gehört zum Gerät; steht er still,
       während sein Rahmen wegfährt, bleibt eine Szene ohne Telefon in der Luft
       hängen. Der Versatz ist die Differenz zwischen der getweenten Lage des
       Gehäuses und der festen Lage dieses Kapitels: Steht das Gehäuse an seinem
       Platz, ist sie null und der Bildschirm sitzt exakt im Rahmen. Läuft ein
       Wechsel, fährt der gehende Bildschirm mit hinaus und der kommende von der
       alten Lage herein — beide im selben Rahmen.

       Der Maßstab steht hier ohne Differenz: Das Gehäuse skaliert von seiner
       Grundgröße aus, der Bildschirm ist genauso groß, also ist --tel-s für
       beide dieselbe Zahl. Steht das Gerät still, ist sie das --lage-s des
       Kapitels, und der Bildschirm sitzt pixelgenau im Rahmen. */
    [data-reise-mode="player"] .reise-kapitel .reise-art .reise-screen {
        transform:
            translate(calc((var(--tel-x, 0) - var(--lage-x, 0)) * var(--tel-spanne-x)),
                      calc((var(--tel-y, 0) - var(--lage-y, 0)) * var(--tel-spanne-y)))
            scale(var(--tel-s, 1));
    }

    [data-reise-mode="player"] .reise-kapitel-liste {
        position: relative;
        display: grid;
        width: 100%;
        height: 100%;
    }

    [data-reise-mode="player"] .reise-kapitel {
        --sp: 0;
        grid-area: 1 / 1;
        /* Der Kasten des Kapitels IST die Bühne. Nur so liegt die Kunstfläche
           darin an derselben Stelle wie das Gehäuse darüber — im Raster wanderte
           sie mit der Länge der Beschriftung. */
        position: relative;
        display: block;
        max-width: none;
        margin: 0;
        padding: 0;
        /* layout und style, NICHT content — Paint-Containment würde Requisiten
           abschneiden, die bewusst über das Kapitel hinausragen. */
        contain: layout style;
        /* MUSS bleiben: Nur so landen Pointer-Events zuverlässig auf der Bühne
           statt auf einem der sechs durchsichtigen Kapitel darüber. */
        pointer-events: none;
        opacity: 0;
        transition: opacity 180ms linear;
    }

    /* Die Kunstfläche hängt am selben Anker wie das Gehäuse und behält ihr
       Seitenverhältnis: Sämtliche Requisiten darin sind in Prozent davon
       bemaßt, eine andere Form verschöbe jedes einzelne. */
    [data-reise-mode="player"] .reise-art {
        position: absolute;
        left: 50%;
        top: var(--reise-kunst-mitte-y);
        width: var(--reise-kunst-breite);
        height: calc(var(--reise-kunst-halbhoch) * 2);
        /* DIE ZEILE HÄLT DIE MITTEN ZUSAMMEN. Eine Fläche mit aspect-ratio und
           overflow: visible bekommt eine automatische Mindestbreite aus ihrem
           Inhalt — hier aus dem Beleg im Fluss, rund 249 px. Unter 378 px fällt
           --reise-kunst-breite (min(16rem, 66vw)) darunter, die Fläche schrumpft
           nicht mehr mit, und das margin daneben rechnet weiter mit dem kleineren
           Wert: Das Gehäuse hängt an der Bühnenmitte, der Bildschirm an der Mitte
           der Fläche, und die beiden drifteten um (249 − Breite)/2 auseinander —
           gemessen 19,0 px auf 320 px, 5,8 auf 360, 0,9 auf 375.
           Nur im Player: Die statische Fassung rechnet alle Requisiten in Prozent
           DERSELBEN Fläche und ist deshalb in sich stimmig, auch zu breit. */
        min-width: 0;
        margin: calc(0px - var(--reise-kunst-halbhoch)) 0 0
                calc(var(--reise-kunst-mitte-x) - var(--reise-kunst-breite) / 2);
    }

    /* Nacheinander, nicht überlappend: Das gehende Kapitel blendet sofort aus,
       das kommende wartet dieselbe Zeit ab. Zusammen 360 ms — unter der
       400-ms-Grenze, ab der man auf die Bedienung wartet, statt sie zu
       bekommen. */
    [data-reise-mode="player"] .reise-kapitel[data-state="active"] {
        opacity: 1;
        transition-delay: 180ms;
    }

    /* Beschriftungen wechseln beatweise nach demselben Muster. Sie liegen dafür
       alle in derselben Rasterzelle — und die steht neben der Kunstfläche, an
       derselben Kante, an der diese endet. */
    [data-reise-mode="player"] .reise-captions {
        position: absolute;
        left: 50%;
        top: 0;
        bottom: 0;
        width: var(--reise-text-breite);
        max-width: none;
        /* auto oben und unten zentriert senkrecht, ohne transform — das gehört
           in dieser Sektion der Bewegung. */
        height: max-content;
        margin: auto 0 auto calc(var(--reise-kunst-mitte-x)
                                 + var(--reise-kunst-breite) / 2
                                 + var(--reise-text-abstand));
        gap: 0;
    }

    [data-reise-mode="player"] .reise-caption {
        grid-area: 1 / 1;
        opacity: 0;
        transition: opacity 180ms linear;
    }

    /* Am Kapitel festgemacht, nicht an irgendeinem Vorfahren: data-active-beat
       steht auch am Player selbst, und ein loser Selektor zeigte dann in jedem
       Kapitel gleichzeitig dieselbe Beat-Nummer. */
    [data-reise-mode="player"] .reise-kapitel[data-active-beat="1"] .reise-caption[data-beat="1"],
    [data-reise-mode="player"] .reise-kapitel[data-active-beat="2"] .reise-caption[data-beat="2"],
    [data-reise-mode="player"] .reise-kapitel[data-active-beat="3"] .reise-caption[data-beat="3"] {
        opacity: 1;
        transition-delay: 180ms;
    }

    /* Nur das laufende und das kommende Kapitel bekommen eine eigene Ebene. */
    [data-reise-mode="player"] .reise-kapitel[data-state="active"],
    [data-reise-mode="player"] .reise-kapitel[data-state="next"] {
        will-change: opacity, transform;
    }

    /* ---- bleibt: gar kein Wechsel ---------------------------------------
       Kapitel 6 und 7 zeigen denselben Bildschirm an derselben Stelle. Blendete
       er nach dem Normalfall — erst weg, dann wieder her —, wäre in der Mitte
       ein Loch, wo nichts steht: sichtbarer Wechsel genau dort, wo keiner
       stattfinden soll. Also andersherum: Das kommende Kapitel legt sich sofort
       darüber (sein Bildschirm ist deckend), das gehende zieht danach darunter
       weg. Die Beschriftungen bleiben davon unberührt, sie wechseln wie
       überall nacheinander. */
    [data-reise-mode="player"][data-uebergang-laeuft="bleibt"]
        .reise-kapitel[data-state="active"] {
        transition-delay: 0s;
    }

    [data-reise-mode="player"][data-uebergang-laeuft="bleibt"]
        .reise-kapitel[data-state="complete"] {
        transition-delay: 180ms;
    }
}

/* ==========================================================================
   Player-Chrome — Spur, Pfeile und Abschluss-Weg

   Sie liegen NEBEN bzw. ÜBER der Bühne, nie in ihrem DOM: Dort stehen sieben
   Kapitel übereinander, sechs davon durchsichtig, und ein fokussierbares
   Element darin wäre eine Tastaturfalle. Die Pfeile und der Abschluss-Halter
   sind Geschwister der Bühne im .reise-buehnenrahmen und nur absolut über sie
   gelegt.

   Die Pfeile tragen im Server-HTML ein `hidden` und werden erst von
   js/reise.js aufgedeckt — was niemand bedienen kann, soll auch nicht danach
   aussehen. Deshalb steht die Ausblendung hier ausdrücklich: eigene
   display-Werte weiter unten schlügen das Attribut sonst.

   ========================================================================== */

/* Bootstraps .btn setzt display:inline-block und schlüge sonst das
   UA-Stylesheet für [hidden] — deshalb steht die Regel für den Abschluss-Weg
   ausdrücklich hier; die Pfeile brauchen sie aus demselben Grund (eigenes
   display: grid). */
.reise-pfeil[hidden],
.reise-abschluss-halter [hidden] {
    display: none;
}

/* ---- Die Pfeile ----
   Keine Steuerungszeile unter dem Bild: Sie kostet rund 60 px Sektionshöhe
   (FEATURE-0143). Zwei dezente Pfeile stehen
   absolut im Rahmen um die Bühne (.reise-buehnenrahmen), auf Höhe der Mitte
   der Kunstfläche — derselbe Anker (--reise-kunst-mitte-y), an dem auch Gerät
   und Kunstfläche hängen, quer wie hochkant.

   NICHT im DOM der Bühne: Dort darf nichts Fokussierbares liegen. Der Rahmen
   ist eigens dafür da — die Bühne selbst konnte die Pfeile nicht tragen.

   44 × 44 px Trefferfläche direkt am Element (2.75rem), kein Polster-Trick
   nötig, weil die Fläche hier sichtbar sein darf: Die halbtransparente
   Milk-Scheibe dahinter hält die Pfeile auf jeder Szene lesbar, auch wo sie
   den Bühnenrand überlappen. Das Icon steht in Tinte, nicht im Akzent
   (dezent) — die gedämpfte Ruhefassung hebt sich im Hover und für
   den Fokus auf volle Kraft. */
.reise-buehnenrahmen {
    position: relative;
}

.reise-pfeil {
    position: absolute;
    top: var(--reise-kunst-mitte-y);
    z-index: 2;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    margin-top: -1.375rem;
    /* Beiger Kreis wie hinter den Icons der Startseite (--tasse-muted
       traegt Testimonial-Avatare und den Scanner-Kreis), voll deckend,
       Espresso-Pfeil. Den 1-px-Rand braucht der Kontrast: Auf --milk-warm-
       Sektionen (#F8EBDD) waere der Kreis sonst beinahe unsichtbar. KEIN
       Schatten — die Sektion traegt keine Schlagschatten. */
    border: 1px solid var(--crema-deep);
    border-radius: 50%;
    background: var(--tasse-muted);
    color: var(--espresso);
    cursor: pointer;
    transition: opacity 160ms linear;
}





.reise-pfeil--zurueck { left: 0.25rem; }
.reise-pfeil--weiter { right: 0.25rem; }

.reise-pfeil:hover:not(:disabled),
.reise-pfeil:focus-visible {
    opacity: 1;
    background: var(--crema-latte);
}

/* Deaktiviert (erster Schritt: „Zurück"), nicht versteckt: Ein
   verschwindender Pfeil ließe genau dort ins Leere klicken, wo man gerade
   zielt. Der Fokus wird beim Deaktivieren wie bisher mitgenommen
   (endenSetzen in reise.js). */
.reise-pfeil:disabled {
    opacity: 0.25;
    cursor: default;
}

/* ---- Der Abschluss-Weg im letzten Schritt ----
   Er erscheint an der Stelle der früheren Steuerungszeile: mittig unter der
   Beschriftung. Der Halter ist absolut am unteren Bühnenrand verankert und
   nimmt keine Höhe im Fluss ein — beim Schrittwechsel springt nichts, der
   Knopf steht im unteren Band der Bühne, das die feste Bühnenhöhe ohnehin
   reserviert (die Beschriftung des letzten Schritts endet darüber,
   nachgemessen auf 1440/768/390/320).

   pointer-events: Der volle Streifen läge sonst über der Bühne und schluckte
   Wisch und Klick — der leere Halter ist deshalb durchlässig, nur der Knopf
   selbst fängt. */
.reise-abschluss-halter {
    position: absolute;
    right: 0;
    bottom: 0.5rem;
    left: 0;
    z-index: 2;
    margin: 0;
    text-align: center;
    pointer-events: none;
}

.reise-abschluss-halter > * {
    pointer-events: auto;
}

/* Der Abschluss bricht nie um: Eine zweizeilige Beschriftung wüchse aus dem
   unteren Band der Bühne heraus. Der Wortlaut ist auf beiden Breiten derselbe
   — „Kostenlos starten" —; die frühere Zwei-Textknoten-Mechanik (lange
   Fassung quer, kurze hochkant) ist mit der Vereinheitlichung entfallen. */
[data-reise-abschluss] {
    white-space: nowrap;
}

/* ---- Der Weg für die statische Fassung ----
   Ohne JavaScript gibt es keinen letzten Schritt, in dem aus „Weiter" das
   Angebot wird — dort endete die Sektion in einem Schlusssatz. Im Player ist er
   überflüssig und wird deshalb ausgeblendet: Der Knopf sagt dasselbe, und zwei
   gleiche Angebote untereinander sind eines zu viel.

   display:none ist hier unbedenklich — anders als bei Kapiteln und
   Beschriftungen, wo es verboten ist: Der Weg steht im Player unverändert
   daneben, es verschwindet also keine Auskunft aus dem Dokument. */
.reise-abschluss-statisch {
    margin: 1.75rem 0 0;
    text-align: center;
}

[data-reise-player][data-reise-mode="player"] ~ .container .reise-abschluss-statisch {
    display: none;
}

/* Ist der Knopf ausgeblendet, ist der Container leer, und sein Kopfabstand
   aus der Grundregel bliebe als 32px hoher Streifen zwischen Bühne und Welle
   stehen. Bis August 2026 fiel das nicht auf, weil dort noch der Schlusssatz
   stand, der in beiden Fassungen sichtbar war. */
[data-reise-player][data-reise-mode="player"] ~ .container:last-child {
    padding-top: 0;
}

/* Am Anfang und am Ende der Reise wird ein Knopf deaktiviert — nicht
   versteckt, sonst rutschten die anderen beiden unter dem Finger weg. Wie ein
   deaktivierter Knopf aussieht, steht in cappuccino.css und nicht hier: Die
   Bootstrap-Falle dahinter (blau statt türkis, weil `.btn-primary:disabled`
   zwei Klassenstufen wiegt) gilt app-weit, und ein lokaler Fang hätte sie für
   jeden anderen Knopf im Haus stehen lassen. Die Maße bleiben dort ebenfalls
   unberührt — nähme man die Fläche weg, sprängen die Nachbarn genau so, wie
   ein `hidden` es täte. */

/* ==========================================================================
   Gemeinsame Bausteine
   ========================================================================== */

/* ---- Papierbeleg ---- */

.reise-beleg {
    position: relative;
    width: calc(19rem * var(--rv));
    padding: calc(1.2rem * var(--rv)) calc(1.2rem * var(--rv)) calc(1rem * var(--rv));
    background:
        repeating-linear-gradient(to bottom,
            transparent 0 calc(1.45rem * var(--rv)),
            rgba(190, 153, 119, 0.07) calc(1.45rem * var(--rv)) calc(1.5rem * var(--rv))),
        var(--beleg-papier);
    border: 1px solid var(--beleg-papier-rand);
    border-radius: var(--radius-sm);
    font-family: var(--beleg-mono);
    color: var(--beleg-text);
}

.reise-beleg-rip {
    position: absolute;
    inset: -1px -1px auto -1px;
    height: calc(0.5rem * var(--rv));
    background: radial-gradient(circle at calc(0.31rem * var(--rv)) 0,
                var(--milk) calc(0.25rem * var(--rv)),
                transparent calc(0.28rem * var(--rv)))
                repeat-x 0 0 / calc(0.62rem * var(--rv)) 100%;
}

.reise-beleg-kopf {
    padding-bottom: calc(0.55rem * var(--rv));
    border-bottom: 1px solid var(--beleg-linie);
}

.reise-beleg-praxis {
    display: block;
    font-family: var(--font-sans);
    font-size: calc(0.9rem * var(--rv));
    font-weight: 700;
}

.reise-beleg-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0 calc(0.6rem * var(--rv));
    margin-top: 0.2rem;
    font-size: calc(0.6rem * var(--rv));
    letter-spacing: 0.03em;
    color: var(--beleg-text-leise);
}

.reise-beleg-spalten,
.reise-beleg-zeile {
    display: grid;
    grid-template-columns:
        calc(2.6rem * var(--rv)) minmax(0, 1fr)
        calc(2.2rem * var(--rv)) calc(3rem * var(--rv));
    gap: calc(0.35rem * var(--rv));
    align-items: baseline;
}

.reise-beleg-spalten {
    margin: calc(0.6rem * var(--rv)) 0 calc(0.35rem * var(--rv));
    font-size: calc(0.52rem * var(--rv));
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--beleg-text-leise);
}

.reise-beleg-spalten span:nth-child(3),
.reise-beleg-spalten span:nth-child(4) {
    text-align: right;
}

.reise-beleg-zeilen {
    display: grid;
    gap: calc(0.3rem * var(--rv));
    padding-top: calc(0.3rem * var(--rv));
}

.reise-beleg-zeile {
    position: relative;
    font-size: calc(0.66rem * var(--rv));
}

.reise-beleg-zeile i,
.reise-beleg-zeile b,
.reise-beleg-zeile u,
.reise-beleg-zeile em {
    font-style: normal;
    font-weight: 400;
    text-decoration: none;
}

.reise-beleg-zeile i {
    color: var(--beleg-text-leise);
}

.reise-beleg-zeile b {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.reise-beleg-zeile u,
.reise-beleg-zeile em {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.reise-beleg-summe {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-top: calc(0.85rem * var(--rv));
    padding-top: calc(0.55rem * var(--rv));
    border-top: 1px solid var(--beleg-linie);
}

.reise-beleg-summe span {
    font-size: calc(0.54rem * var(--rv));
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--beleg-text-leise);
}

.reise-beleg-summe strong {
    font-size: calc(0.95rem * var(--rv));
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Markierungen liegen als Überzug ÜBER dem Text und multiplizieren, damit die
   Schrift durchscheint. Sie wachsen per scaleX — kein animiertes box-shadow,
   das jeden Frame neu gezeichnet werden müsste. */
.reise-beleg--erkannt [data-feld],
.reise-beleg--erkannt .reise-beleg-zeile--auffaellig {
    position: relative;
}

.reise-beleg--erkannt [data-feld]::after,
.reise-beleg--erkannt .reise-beleg-zeile--auffaellig::after {
    content: "";
    position: absolute;
    inset: -1px -2px;
    border-radius: 2px;
    background: var(--beleg-marker);
    mix-blend-mode: multiply;
    pointer-events: none;
    transform-origin: left center;
    transform: scaleX(1);
}

.reise-beleg--erkannt .reise-beleg-zeile--auffaellig::after {
    background: var(--status-error-bg);
}

/* ---- Gerät und Bildschirm: überall dieselbe Bauform ----
   Das Gehäuse ist ein Bühnen-Requisit und steht EINMAL da (.reise-geraet). Der
   Bildschirminhalt bleibt im Kapitel (.reise-screen) und blendet mit ihm. So
   bleibt das Gerät über den Kapitelwechsel hinweg stehen, und nur was darauf zu
   sehen ist, wechselt. Vorher stand dasselbe Telefon als sechs Markup-Kopien in
   den Kapiteln und musste bei jedem Wechsel aus- und wieder einblenden — bei
   34 px Versatz zwischen Kapitel 2 und 3.

   Ohne Player gibt es keine Bühne, auf der ein Gehäuse stehen könnte: Dort ist
   .reise-geraet ausgeblendet — es trägt keinen Text, ist also unbedenklich —
   und jeder Bildschirm bringt denselben Rahmen selbst mit. Beide Fassungen
   zeigen dieselbe Bauform, weil beide Elemente dieselbe Geometrie erben.

   Nur Lage und Neigung dürfen sich unterscheiden, nie Größe oder Radien. Sonst
   wirkt in jedem Kapitel ein anderes Gerät.
   DAS GERÄT IST DIE EINE AUSNAHME — bei der Strichstärke UND beim Radius.
   Aufgeschrieben, damit es eine bleibt: Jede andere Kontur der Sektion steht in
   --staerke (2 px) und jeder andere Radius auf der Token-Leiter (--radius-sm 4 /
   xs 6 / md 8 / lg 12 / pill 25). Das Gehäuse trägt 0,45 rem Rand und 2,1 rem
   Rundung, weil es ein Telefon zeigt und keine Karte, und weil beide Fassungen
   dieselbe Geometrie brauchen: In der statischen Fassung zeichnet der Bildschirm
   sein Gehäuse selbst, im Player übernimmt das Bühnen-Requisit. Auf --staerke
   verschmälert wüchse die Fläche darin um rund 24 px, und die Szene stünde ohne
   JavaScript in einer anderen Größe als daneben.

   Nicht unter diese Regel fällt, was keine KONTUR eines Requisits ist:
   Was ein Bildschirm ZEIGT —
   Trennlinien im Beleg, Zeilenlinien, Marken, das Schreibfeld — ist das
   Druckbild einer App und keine Zeichnung; 2 px stünden dort bei 7 px
   Schriftgrad als Balken. */

.reise {
    --reise-geraet-breite: calc(13.5rem * var(--rv));
    --reise-geraet-halbhoehe: calc(12.5rem * var(--rv));
    --reise-geraet-radius: calc(2.1rem * var(--rv));
    --reise-geraet-rand: calc(0.45rem * var(--rv));
}

/* Gleiche Geometrie wie das Telefon im Hero. Lage und Inhalt wechseln, Rahmen,
   Proportion und Rundungen nicht.

   DAS GEHÄUSE STEHT IN --strich, NICHT IN #16100B. Der handgeschriebene Ton war
   ein sechster Braunton neben espresso, espresso-light, espresso-dark, tasse und
   crema und stand in keinem Token — gegen Paragraf 8 der Frontend-Regel, nach
   der tokens.css die einzige Quelle ist. In der Tinte der Zeichnung ist das
   Gerät nicht mehr die dunkelste Fläche der Sektion, sondern deren dickster
   Strich. */
.reise-geraet,
.reise-screen {
    position: relative;
    width: var(--reise-geraet-breite);
    aspect-ratio: 41 / 76;
    background: var(--strich);
    border-radius: var(--reise-geraet-radius);
}

/* Ohne Player gibt es keine Bühne, auf der es stehen könnte. Ausblenden ist
   hier unbedenklich: Das Gehäuse ist Dekoration und trägt keinen Text — anders
   als Kapitel und Captions, die nie ausgeblendet werden dürfen. */
.reise-geraet {
    display: none;
    padding: var(--reise-geraet-rand);
}

/* Die Insel steht im Gehäuse als eigenes Element und auf dem Bildschirm als
   Pseudoelement. Zwei Wege für dieselbe Sache, weil in der einen Fassung ein
   Element existiert und in der anderen nicht — ein echtes Kind im Bildschirm
   läge im Player doppelt über dem des Gehäuses. */
.reise-geraet-insel,
.reise-screen::before {
    position: absolute;
    top: calc(0.95rem * var(--rv));
    left: 50%;
    width: calc(3.6rem * var(--rv));
    height: calc(0.9rem * var(--rv));
    transform: translateX(-50%);
    background: var(--strich);
    border-radius: var(--radius-pill);
    z-index: 2;
}

.reise-screen::before {
    content: "";
}

/* Der Bildschirm trägt sein Gehäuse als Rand: außen der Rahmen, innen die
   Fläche, auf der die Szene liegt. Im Player übernimmt das Gehäuse auf der
   Bühne, dann bleibt hier nur die Fläche. */
.reise-screen {
    display: flex;
    flex-direction: column;
    padding: calc(2.4rem * var(--rv)) calc(0.7rem * var(--rv)) calc(0.9rem * var(--rv));
    border: var(--reise-geraet-rand) solid var(--strich);
    background: var(--milk);
    overflow: hidden;
    font-family: var(--font-app);
    color: var(--espresso);
}

/* Lagen — gleiche Bauform, andere Position. */
.reise-screen--links {
    position: absolute;
    left: 0;
    top: 56%;
    margin-top: calc(0rem - var(--reise-geraet-halbhoehe));
}

.reise-screen--haltend {
    position: absolute;
    right: 0;
    top: 50%;
    margin-top: calc(0rem - var(--reise-geraet-halbhoehe));
    z-index: 8;
}

.reise-screen--banking {
    position: absolute;
    right: 0;
    top: 50%;
    margin-top: calc(0rem - var(--reise-geraet-halbhoehe));
}

.reise-screen-kopf {
    margin-bottom: calc(0.6rem * var(--rv));
    font-family: var(--font-sans);
    font-size: calc(0.64rem * var(--rv));
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--stone-500);
}

/* ---- Taste ---- */

.reise-taste {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: calc(0.8rem * var(--rv));
    padding: calc(0.5rem * var(--rv));
    background: var(--accent);
    border-radius: var(--radius-md);
    font-family: var(--font-sans);
    font-size: calc(0.72rem * var(--rv));
    font-weight: 600;
    color: var(--flaeche);
}

.reise-taste--still {
    background: transparent;
    border: var(--staerke) solid var(--control-border);
    color: var(--stone-500);
}

/* Der Fingertipp: ein Ring, der auf der Taste aufsetzt. */
/* Der Träger trägt keine Optik, nur die Lage: Ob getippt wird, sagt der Scroll
   über seine Deckkraft. Der Ring darin ist ein eigenes Element, damit sein Puls
   nach eigener Uhr laufen kann, ohne mit der Deckkraft zu kollidieren. Die Lage
   steht als Rand, nicht als translate — das transform gehört der Bewegung. */
.reise-tipp {
    position: absolute;
    top: 50%;
    left: 50%;
    width: calc(2.8rem * var(--rv));
    height: calc(2.8rem * var(--rv));
    margin: calc(-1.4rem * var(--rv)) 0 0 calc(-1.4rem * var(--rv));
    opacity: 0;
}

/* Der Ring stand in rgba(255,255,255,0.85) und war damit auf der Milchfläche
   unsichtbar — der Linienstil-Block setzte die Farbe am TRÄGER, und der hat
   keinen Rand. Tinte und nicht Türkis: Ein Fingertipp ist Bedienung. */
.reise-tipp::after {
    content: "";
    position: absolute;
    inset: 0;
    border: var(--staerke) solid var(--strich);
    border-radius: 50%;
    transform: scale(0.3);
}

/* ---- Statusmarken ---- */

.reise-badge {
    flex-shrink: 0;
    padding: 0.12rem calc(0.45rem * var(--rv));
    border-radius: var(--radius-pill);
    font-size: calc(0.58rem * var(--rv));
    font-style: normal;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.reise-badge--offen {
    background: var(--status-open-bg);
    color: var(--status-open-fg);
}

.reise-badge--erstattet {
    background: var(--status-success-bg);
    color: var(--status-success-fg);
}

/* Beide Zustände liegen übereinander und blenden gegeneinander — ohne
   Sprung in der Zeilenhöhe. */
.reise-badge-wechsel {
    display: grid;
    justify-self: start;
    margin-top: calc(0.2rem * var(--rv));
}

.reise-badge-wechsel .reise-badge {
    grid-area: 1 / 1;
}

.reise-badge-wechsel .reise-badge--offen {
    opacity: 0;
}

/* ==========================================================================
   Kapitel 1 — Post, Scannen, Ablegen
   ========================================================================== */

.reise-stapel {
    position: absolute;
    left: 42%;
    top: 50%;
    width: calc(17rem * var(--rv));
    height: calc(11rem * var(--rv));
    margin: calc(-1.5rem * var(--rv)) 0 0 calc(-8.5rem * var(--rv));
}

/* Die fruehere Maskier-Tasche des Stapels ist ersatzlos entfallen
   (FEATURE-0143). Sie existierte nur, um das Blatt waehrend
   des Zugs aus dem Umschlag zu verstecken — der Zug selbst ist gestrichen,
   die Rechnung liegt im Player von Anfang an vor den Umschlaegen. Die Tasche
   war dreimal Fehlerquelle: der "beige Rand" um die Briefe, 147 px frei
   haengendes Blatt bei --sp 0, 70 px Blattkante neben der Maske. */


.reise-brief {
    position: absolute;
    left: 50%;
    width: calc(20rem * var(--rv));
    height: calc(8.6rem * var(--rv));
    background: linear-gradient(160deg, var(--milk-pure) 0%, var(--crema-latte) 100%);
    border: 1px solid var(--crema-deep);
    border-radius: var(--radius-sm);
}

/* Angedeutete Klappenkante, damit der Stapel als Post lesbar ist. */
.reise-brief::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 52%;
    border-bottom: 1px solid var(--crema-deep);
    clip-path: polygon(0 0, 100% 0, 50% 100%);
    opacity: 0.5;
}

/* Der oberste Umschlag liegt ÜBER dem Blatt, damit es sichtbar dahinter
   hervorkommt statt davor aufzutauchen. */
.reise-brief--1 { bottom: 10%; transform: translateX(-50%) rotate(-2deg); z-index: 6; }
.reise-brief--2 { bottom: 3%;  transform: translateX(-55%) rotate(4deg);  z-index: 3; }
.reise-brief--3 { bottom: -3%; transform: translateX(-44%) rotate(-6deg); z-index: 2; }
.reise-brief--4 { bottom: -9%; transform: translateX(-53%) rotate(9deg);  z-index: 1; }

.reise-brief-klappe {
    position: absolute;
    inset: 0 0 auto 0;
    height: 55%;
    background: linear-gradient(180deg, var(--crema-latte) 0%, var(--crema-deep) 100%);
    clip-path: polygon(0 0, 100% 0, 50% 100%);
    transform-origin: center top;
    z-index: 2;
}

/* Die Ringmechanik ist ersatzlos entfallen. Sie trug den dritten Beat von
   Kapitel 1 („Einmal aufheften, nie wieder hervorholen"); die Aussage lautet
   jetzt „du brauchst es nicht mehr", und dafür fliegt das Papier aus dem Bild,
   statt sich in etwas einzuordnen. Mit ihr geht die Ebene --e-behaelter: Sie
   existierte nur, um Papier zu verdecken, das in einen Behälter geht. */

.reise-scanrahmen {
    position: absolute;
    left: 42%;
    top: 50%;
    width: calc(21.5rem * var(--rv));
    height: calc(21.05rem * var(--rv));
    margin: calc(-11.25rem * var(--rv)) 0 0 calc(-10.75rem * var(--rv));
    /* Strecke der Laufschiene: Rahmenhöhe minus Höhe des Balkens. */
    --scan-strecke: calc(21rem * var(--rv));
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
    z-index: 6;
}

.reise-scanecke {
    position: absolute;
    width: calc(1.6rem * var(--rv));
    height: calc(1.6rem * var(--rv));
    border: var(--staerke) solid var(--strich);
    border-radius: var(--radius-sm);
}

.reise-scanecke--ol { top: 0;    left: 0;  border-right: 0; border-bottom: 0; }
.reise-scanecke--or { top: 0;    right: 0; border-left: 0;  border-bottom: 0; }
.reise-scanecke--ul { bottom: 0; left: 0;  border-right: 0; border-top: 0; }
.reise-scanecke--ur { bottom: 0; right: 0; border-left: 0;  border-top: 0; }

.reise-scanlinie {
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg,
                transparent 0%,
                rgba(42, 157, 143, 0.45) 12%,
                var(--accent) 50%,
                rgba(42, 157, 143, 0.45) 88%,
                transparent 100%);
}

/* Der Auslöser sitzt mittig zwischen der Unterkante des Bildbereichs und der
   Unterkante des Gehäuses. Das Polster rechnet deshalb den Rand des Telefons
   mit, nicht nur den des Bildschirms. */
.reise-screen--sucher {
    justify-content: flex-end;
    align-items: center;
    padding-bottom: calc(0.84rem * var(--rv));
    background: var(--milk-pure);
}

/* Das Hilfslinien-Raster des Suchers (.reise-sucher-raster) ist ersatzlos
   entfallen: Es erschien als brauner Rahmen im Display, bevor irgendetwas
   passierte, und rahmte nichts.
   Der Sucher ist die leere Fläche mit dem Auslöser — wie eine Kamera-App,
   bevor man auslöst. */

/* Runder Auslöser wie in jeder Kamera-App: ein roter Punkt, sonst nichts. */
.reise-sucher-ausloeser {
    position: relative;
    z-index: 2;
    width: calc(2.5rem * var(--rv));
    height: calc(2.5rem * var(--rv));
    background: var(--danger);
    border-radius: 50%;
}

/* DAS AUFBLITZEN IST ERSATZLOS ENTFALLEN. Es lag in --accent-muted über dem
   ganzen Sucher und war damit die fünfte türkise Stelle in einem Kapitel, das
   zwei haben darf. Quittiert wird die Aufnahme ohnehin sichtbar: Der Beleg
   wandert ins Gerät und verschwindet beim Ankommen. Ein Blitz obendrauf ist
   Dekoration auf einer Geste, die schon zu sehen ist — und in einer Sektion,
   die zu dick aufträgt, die erste Zeile, die geht. */

/* Die vordere Fassung des Blatts. Sie liegt deckungsgleich auf dem Papier —
   dieselbe Lage, dieselbe Größe — und übernimmt am Ende von Beat 1 per
   Kreuzblende: Das Papier zieht sich HINTER dem Stapel aus dem Umschlag (nur
   dort kann es verdeckt anfangen), aber die Hauptdarstellerin darf im
   Ruhebild nicht hinter den Umschlägen stehen. Ein z-index darf nicht am
   Fortschritt hängen (Lint: nur transform und opacity am Fortschritt), also
   wechselt die Deckkraft zwischen zwei deckungsgleichen Fassungen — sichtbar
   ist davon nur, dass das Blatt vor die Umschläge tritt.

   In Beat 2 wandert dieselbe Fassung ins Telefon: „Die Briefumschläge
   blenden aus, und der Beleg wandert ins Handy" (FEATURE-0143).
   Deshalb absolut und nicht im Fluss: Das Papier ist das einzige Flusskind
   der Kunstfläche und steht durch deren `align-items: center` in der Mitte;
   ein zweites Kind rückte beide nebeneinander. `left: 42%` und
   `translate(-50%, -50%)` treffen genau diese Stelle. */
.reise-beleg--vorn {
    position: absolute;
    left: 42%;
    top: 50%;
    /* Der Weg in den Sucher, waagerecht. Das Gerät steht --lage-x Spannen
       rechts der Mitte der Kunstfläche (der Faktor rechnet die Gerätelage
       mit, damit ein Justieren der Lage den Weg nicht verfehlt);
       das Papier liegt bei 42 % davon. Beides gegen dieselben Größen
       gerechnet und nicht als Pixelzahl, denn zwischen 1440 und 390 px ist
       dieselbe Spanne gut viermal kleiner. Senkrecht ist der Weg null: Beide
       stehen auf der Mittellinie der Kunstfläche. */
    --vorn-x: calc(var(--reise-kunst-breite) * 0.08
                   + var(--lage-x, 1) * var(--tel-spanne-x));
    opacity: 0;
}

/* Der erfasste Beleg im Bildschirm: Am Ende von Beat 2 zeigt das Telefon den
   Inhalt — Briefkopf und Positionen, nicht nur den Sucher. Dieselbe Bauform wie --erkannt in Kapitel 2, die Maße stehen
   dort (geteilte Selektoren).

   ER FÜLLT DAS DISPLAY RANDLOS:
   Das Foto ist der Bildschirminhalt, kein Blatt Papier, das auf dem
   Bildschirm liegt. Kontur und Fläche nimmt ihm der Linienstil-Block am Ende
   des Blatts wieder ab — die Grundregel „alles wird Kontur" gäbe ihm sonst
   den Papier-Rahmen zurück, weil sie später im Blatt steht. Kapitel 2 rahmt
   seinen Beleg weiterhin: Dort ist er das Dokument in der App, hier ist er
   das Foto.

   Er legt sich ÜBER den Sucher statt ihn auszublenden — zwei Blenden für
   einen Wechsel wären eine zu viel. z-index 3: über dem Auslöser (2), lokal
   im Stapelkontext des Bildschirms. Beim Aufsteigen (Choreografie) schneidet
   der Bildschirm ab, was unter seine Kante ragt (overflow: hidden).

   Nur im Player sichtbar (Basis-Deckkraft 0): Das Ruhebild der statischen
   Fassung ist der Scan-Moment — Blatt neben Telefon, Sucher darüber —, dort
   gibt es kein „danach". */
.reise-beleg--erfasst {
    position: absolute;
    inset: calc(2.4rem * var(--rv)) 0 0 0;
    z-index: 3;
    opacity: 0;
}

/* ==========================================================================
   Kapitel 2 — Erkennen und Prüfen
   ========================================================================== */

/* Die Maße gelten auch für --erfasst in Kapitel 1: derselbe Beleg im selben
   Bildschirm — Kapitel 2 beginnt mit exakt dem Bild, mit dem Kapitel 1
   endet. */
.reise-beleg--erkannt,
.reise-beleg--erfasst {
    width: 100%;
    padding: calc(0.7rem * var(--rv));
    border: 0;
    background: transparent;
}

.reise-beleg--erkannt .reise-beleg-rip,
.reise-beleg--erfasst .reise-beleg-rip {
    display: none;
}

/* Im schmalen Telefon bekommt die Leistungsspalte den Platz. */
.reise-beleg--erkannt .reise-beleg-spalten,
.reise-beleg--erkannt .reise-beleg-zeile,
.reise-beleg--erfasst .reise-beleg-spalten,
.reise-beleg--erfasst .reise-beleg-zeile {
    grid-template-columns:
        calc(2rem * var(--rv)) minmax(0, 1fr)
        calc(1.5rem * var(--rv)) calc(2.4rem * var(--rv));
    gap: calc(0.45rem * var(--rv));
}

.reise-beleg--erkannt .reise-beleg-spalten,
.reise-beleg--erfasst .reise-beleg-spalten {
    font-size: calc(0.46rem * var(--rv));
}

/* Der Praxisname darf im schmalen Bildschirm nicht auf zwei Zeilen brechen. */
.reise-beleg--erkannt .reise-beleg-praxis,
.reise-beleg--erfasst .reise-beleg-praxis {
    font-size: calc(0.76rem * var(--rv));
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.reise-beleg--erkannt .reise-beleg-zeile,
.reise-beleg--erfasst .reise-beleg-zeile {
    font-size: calc(0.62rem * var(--rv));
}

/* Die Schilder benennen, was erkannt wurde — mit Haken, damit es als Bestätigung
   liest und nicht als bloße Beschriftung. */
.reise-fahne {
    position: absolute;
    display: inline-flex;
    align-items: center;
    gap: calc(0.4rem * var(--rv));
    padding: calc(0.35rem * var(--rv)) calc(0.75rem * var(--rv));
    background: var(--espresso);
    border-radius: var(--radius-pill);
    font-family: var(--font-sans);
    font-size: calc(0.8rem * var(--rv));
    font-weight: 600;
    color: var(--milk);
    white-space: nowrap;
    opacity: 0;
}

.reise-fahne-kreis {
    position: relative;
    width: calc(1.05rem * var(--rv));
    height: calc(1.05rem * var(--rv));
    background: var(--accent);
    border-radius: 50%;
}

.reise-fahne-haken {
    position: absolute;
    inset: 24%;
    background: var(--milk);
    clip-path: polygon(14% 52%, 38% 76%, 86% 20%, 96% 32%, 38% 96%, 4% 62%);
}

/* Jede Fahne hängt an der Kante, zu der sie zeigt: die linken mit ihrer
   rechten, die rechten mit ihrer LINKEN — und beide innerhalb der Kunstfläche.
   Genau das fehlte rechts: `left: 73%` legt den ANFANG fest, das Ende ergab
   sich aus der Beschriftungsbreite. Die skaliert mit --rv (0,92), die Fläche
   mit der Breite des Fensters (50vw) — auf 1440 px endete „Alle Positionen"
   zufällig bündig, auf 768 px stand es 39 px über der Fläche und damit 13 px
   auf der zweiten Zeile des Fließtextes, der 1,5 rem daneben beginnt.
   Über `right` gemessen kann das nicht mehr passieren: Die Fahne endet, wo die
   Fläche endet, gleich wie breit ihr Text ist. */
.reise-fahne--aussteller { top: 21%; right: 73%; }
.reise-fahne--datum      { top: 32%; right: 75%; }
.reise-fahne--position   { top: 47%; left: auto; right: 0; }
.reise-fahne--betrag     { top: 58%; left: auto; right: 12%; }

/* Die Empfehlung steht außerhalb des Telefons — sie ist ein Rat, keine Anzeige
   der App. */
/* LINKS NEBEN dem Gerät, auf Höhe der markierten Zeile. Auf dem Telefon
   (left: 56 %) verdeckte sie genau die Zahlen, um die es geht: die
   Betragsspalte und den GESAMTBETRAG (Sichtungs-Befund, August 2026). Weiter
   rechts ragte sie in die Textspalte — also die linke Seite: In Beat 2 sind
   die Schilder weg, das Band links vom zentrierten Gerät ist frei. `right`
   statt `left`, damit die Karte am Gerät endet, gleich wie breit ihr Text
   ist; die 72 % lassen rund 0,7 rem Luft zur Gehäusekante. Hochkant gilt
   weiter die eigene Lage unten (unter dem Gerät). */
.reise-empfehlung {
    position: absolute;
    left: auto;
    right: 72%;
    top: 46%;
    width: calc(12rem * var(--rv));
    padding: calc(0.8rem * var(--rv)) calc(1rem * var(--rv));
    background: var(--status-error-bg);
    border-radius: var(--radius-sm);
    font-family: var(--font-sans);
    font-size: calc(0.85rem * var(--rv));
    line-height: 1.45;
    color: var(--status-error-fg);
}

.reise-empfehlung strong {
    display: block;
    margin-bottom: 0.2rem;
    font-weight: 700;
}

/* ==========================================================================
   Kapitel 3 — Bezahlen
   ========================================================================== */

.reise-zahlkarte {
    position: absolute;
    left: 3%;
    top: 58%;
    width: calc(15rem * var(--rv));
    margin-top: calc(-8rem * var(--rv));
    padding: calc(1rem * var(--rv));
    background: var(--milk-pure);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-lg);
    font-family: var(--font-app);
    text-align: center;
    z-index: 1;
}

.reise-art--zahlung .reise-screen--banking {
    right: 24%;
    top: 58%;
    /* Das Telefon hält man ÜBER die Zahlkarte, sonst schneidet der QR-Code quer
       durch das Gerät, das ihn gerade scannt. Hier stand eine 3, und die lag
       unter der Karte (35) — sichtbar wurde es erst, als das Gehäuse auf die
       Bühne wanderte und der Bildschirm die Ebene allein tragen musste. */
    z-index: calc(var(--e-geraet) + 2);
}

.reise-faellig {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: calc(0.4rem * var(--rv));
    margin-bottom: calc(0.7rem * var(--rv));
    font-size: calc(0.8rem * var(--rv));
    font-weight: 600;
}

/* --status-open-fg und nicht --warning: Beide sind Bernstein, aber --warning
   ist die Fläche und kommt auf Milch nur auf 3,14:1. Der Vordergrund-Token
   derselben Statusfamilie trägt 5,19:1 — und „Fällig" IST der Status „offen",
   also steht hier ohnehin der richtige Name. */
.reise-faellig-label {
    font-size: calc(0.6rem * var(--rv));
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--status-open-fg);
}

/* EINE ZAHL FÜR BREITE, HÖHE UND STRAHLWEG. Das Zeichen ist quadratisch, das
   Polster ringsum gleich — also ist die Höhe der Karte gleich ihrer Breite, und
   der Strahl läuft genau diese Strecke. Sie stand hier als 9,4 rem daneben und
   hätte bei jeder Größenänderung von Hand nachgezogen werden müssen; das ist
   bei der Verkleinerung auf 60 Prozent Fläche prompt aufgefallen. */
.reise-qr {
    --qr-breite: calc(8.5rem * var(--rv));
    position: relative;
    width: var(--qr-breite);
    margin: 0 auto calc(0.7rem * var(--rv));
    padding: calc(0.55rem * var(--rv));
    background: var(--flaeche);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.reise-qr-code {
    display: block;
    width: 100%;
    height: auto;
}

/* Kontur in der Strichstärke der Sektion. non-scaling-stroke, weil das Zeichen
   knapp vierfach skaliert wird: 2 Nutzereinheiten wären dort 9 px. */
.reise-qr-ecke {
    fill: none;
    stroke: var(--strich);
    stroke-width: var(--staerke);
    vector-effect: non-scaling-stroke;
}

.reise-qr-kern {
    fill: var(--strich);
}

/* Module in Tinte, nicht leise: In --strich-leise las sich das Raster nicht
   mehr als QR-Code. Als Punktraster
   von rund 45 Prozent bleibt es trotzdem heller als jede gefüllte Fläche. */
.reise-qr-modul {
    fill: var(--strich);
}

/* Der Scanstrahl läuft sichtbar über den Code — das Scannen ist der Beat. */
.reise-qr-strahl {
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg,
                transparent 0%,
                rgba(42, 157, 143, 0.45) 12%,
                var(--accent) 50%,
                rgba(42, 157, 143, 0.45) 88%,
                transparent 100%);
    opacity: 0;
}

.reise-zahlkarte-fuss {
    display: block;
    font-size: calc(0.68rem * var(--rv));
    color: var(--stone-500);
}

.reise-screen--banking {
    gap: calc(0.5rem * var(--rv));
    background: var(--milk-pure);
}

/* Die Banking-App ist als App erkennbar, nicht als Formular — und ihr Kopf
   ist eine KOPFZEILE, kein Wappen: Groß und zentral im Screen lesen sich
   Logo und Name nicht wie eine App. Deshalb dieselbe Formensprache wie „ABRECHNUNG DER PKV" und
   „EINREICHUNG": .reise-screen-kopf trägt Schrift und Abstand, hier kommen
   nur das kleine Logo links daneben und die Zeilenform dazu. Die frühere
   auto-Zentrierung des Logo-Blocks ist damit gegenstandslos — der Inhalt
   ordnet sich unter der Kopfzeile, die Taste hält ihr margin-top: auto. */
.reise-bank-kopf {
    display: flex;
    align-items: center;
    gap: calc(0.4rem * var(--rv));
}

/* KEIN non-scaling-stroke mehr: In Kopfzeilengröße (1,5 rem Breite) liegen
   die Linien des Giebels rund 1,6 px auseinander — feste 2 px Strich
   verschmierten sie zu einer Fläche. Mitskaliert wird der Strich zur
   Haarlinie, und das ist für ein kleines App-Logo die richtige Stärke. */
.reise-bank-logo {
    display: block;
    width: calc(1.5rem * var(--rv));
    flex-shrink: 0;
    fill: none;
    stroke: var(--strich);
    stroke-width: var(--staerke);
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Der Platz am unteren Rand (margin-top: auto) gehört dem Stapel, nicht der
   einzelnen Taste — so bleibt die Taste unten, gleich was darüber steht.
   Mit Luft zur Gehäuseunterkante: Bündig am Polsterrand klebte die Taste am
   Gehäuse (Sichtungs-Befund, August 2026). */
.reise-bank-tasten {
    position: relative;
    display: grid;
    margin-top: auto;
    margin-bottom: calc(0.9rem * var(--rv));
}

.reise-bank-tasten .reise-bank-taste {
    grid-area: 1 / 1;
}

.reise-bank-taste {
    position: relative;
    padding: calc(0.45rem * var(--rv));
    background: var(--espresso);
    border-radius: var(--radius-sm);
    font-family: var(--font-sans);
    font-size: calc(0.68rem * var(--rv));
    font-weight: 600;
    color: var(--milk);
    text-align: center;
}

/* Die Erfolgsmeldung erscheint UNTER der Kopfzeile, im selben Screen — kein
   Screen-Wechsel, keine deckende Quittung über der ganzen Fläche: Eine
   Überweisungsmaske, die sie zudecken müsste, gibt es nicht. Im Fluss zwischen Kopfzeile und
   Taste, nicht absolut: Sie gehört zur App-Seite, nicht darüber. */
.reise-quittung {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-top: calc(0.8rem * var(--rv));
    gap: calc(0.5rem * var(--rv));
    font-family: var(--font-sans);
    font-size: calc(0.72rem * var(--rv));
    font-weight: 700;
    color: var(--espresso);
    text-align: center;
}

.reise-quittung-haken {
    position: relative;
    width: calc(2.2rem * var(--rv));
    height: calc(2.2rem * var(--rv));
    background: var(--accent);
    border-radius: 50%;
}

.reise-quittung-haken::after {
    content: "";
    position: absolute;
    inset: 26%;
    background: var(--flaeche);
    clip-path: polygon(14% 52%, 38% 76%, 86% 20%, 96% 32%, 38% 96%, 4% 62%);
}

/* Nach der Banking-Bestätigung wird dieselbe Zahlung an der Arztrechnung
   sichtbar. Die Karte steht neben dem Telefon und bleibt als Endzustand stehen.

   LINKS UNTER DER ZAHLKARTE, NICHT RECHTS AM GERÄT (Sichtungs-Befund, August
   2026): Bei right −2 % lag die Karte halb auf dem Telefon und schnitt dessen
   rechten Bildschirmrand — rechts daneben ist kein Platz, dort beginnt nach
   98 px die Textspalte. Links unten ist Platz: Die Karte liegt wie die
   Zahlkarte „auf dem Tisch", bündig unter ihr, und berührt das Gerät nicht.
   Hochkant gilt weiter die eigene Lage (mittig unter dem Gerät). */
.reise-zahlbeleg {
    position: absolute;
    left: 3%;
    right: auto;
    bottom: -12%;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: calc(0.2rem * var(--rv)) calc(0.7rem * var(--rv));
    width: calc(13rem * var(--rv));
    padding: calc(0.75rem * var(--rv)) calc(0.85rem * var(--rv));
    background: var(--milk-pure);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    font-family: var(--font-app);
    z-index: 4;
}

.reise-zahlbeleg-art {
    grid-column: 1 / -1;
    font-size: calc(0.58rem * var(--rv));
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--stone-500);
}

.reise-zahlbeleg strong,
.reise-zahlbeleg-betrag {
    font-size: calc(0.7rem * var(--rv));
    font-weight: 600;
}

.reise-zahlbeleg-betrag {
    font-variant-numeric: tabular-nums;
}

.reise-zahlbeleg-status {
    grid-column: 1 / -1;
    display: grid;
    justify-items: start;
    margin-top: calc(0.15rem * var(--rv));
}

.reise-zahlbeleg-status .reise-badge {
    grid-area: 1 / 1;
}

.reise-badge--zahlung-offen {
    background: var(--status-neutral-bg);
    color: var(--status-neutral-fg);
}

.reise-badge--zahlung-bezahlt {
    background: var(--status-success-bg);
    color: var(--status-success-fg);
}

.reise-zahlbeleg-status .reise-badge--zahlung-offen {
    opacity: 0;
}

/* ==========================================================================
   Kapitel 4 — Einreichen
   ========================================================================== */

.reise-auswahl {
    display: grid;
    gap: calc(0.3rem * var(--rv));
}

.reise-auswahl-zeile {
    position: relative;
    display: grid;
    grid-template-columns: calc(1.1rem * var(--rv)) minmax(0, 1fr) auto;
    gap: calc(0.5rem * var(--rv));
    align-items: center;
    padding: calc(0.45rem * var(--rv)) calc(0.4rem * var(--rv));
    border-radius: var(--radius-xs);
    font-size: calc(0.7rem * var(--rv));
}

/* Der grüne Grund zeigt die Auswahl deutlicher als das Häkchen allein. */
.reise-auswahl-zeile::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--status-success-bg);
    border-radius: var(--radius-xs);
    transform-origin: left center;
    transform: scaleX(1);
}

.reise-auswahl-zeile > * {
    position: relative;
    z-index: 1;
}

.reise-auswahl-zeile b {
    font-weight: 600;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.reise-auswahl-zeile em {
    font-style: normal;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.reise-haken {
    position: relative;
    width: calc(1.05rem * var(--rv));
    height: calc(1.05rem * var(--rv));
    border: 1.5px solid var(--control-border);
    border-radius: var(--radius-sm);
    background: var(--milk-pure);
}

.reise-haken::after {
    content: "";
    position: absolute;
    inset: -1px;
    background: var(--accent);
    border-radius: var(--radius-sm);
    clip-path: polygon(16% 52%, 38% 74%, 84% 24%, 92% 34%, 38% 90%, 8% 60%);
}

/* ---- Die Kostenträger als Gebäude ----------------------------------------
   Beihilfe und PKV sind ORTE, keine Bedienelemente. Vorher standen hier zwei
   türkis gefüllte Kacheln mit Rundung und Beschriftung — sie sahen aus wie
   Knöpfe und wurden im Gestaltungs-Review genau dafür beanstandet. Ein Gebäude
   kann nicht versehentlich anklickbar aussehen.

   Sie stehen in Kapitel 4 (dorthin geht die Einreichung) und in Kapitel 6 (von
   dort kommt die Abrechnung) an derselben Stelle — nur so ist zu sehen, dass
   Hinweg und Rückweg dieselbe Strecke sind. */
/* WO SIE STEHEN, STEHT AN EINER STELLE: --ziel-x/--ziel-y, die Mitte des
   Gebäudeblocks gegen die Mitte der Kunstfläche. Der Block liest sie, und der
   Flug liest sie auch — deshalb landet die Sendung am Gebäude und nicht neben
   ihm, und zwar auf jeder Breite. Als der Weg noch als eigene Zahl daneben
   stand, flog die Einreichung auf 1440 px an den Gebäuden vorbei aus dem Bild.

   Waagerecht bündig an der rechten Kante der Kunstfläche, senkrecht mittig. Auf
   schmalen Flächen ist rechts kein Platz; dort rücken sie unter das Telefon,
   und beide Zeilen unten setzen nur diese zwei Werte um. */
.reise {
    --ziel-x: calc(var(--reise-kunst-breite) / 2 - 5.5rem * var(--rv));
    --ziel-y: 0px;
}

.reise-ziele {
    position: absolute;
    left: 50%;
    top: 50%;
    display: grid;
    gap: calc(1.4rem * var(--rv));
    width: calc(11rem * var(--rv));
    /* Halbe Höhe zweier Gebäude plus halber Abstand: Die Beihilfe steht damit
       so weit über der Mittellinie, wie die PKV darunter steht. */
    margin: calc(var(--ziel-y) - 5.6rem * var(--rv)) 0 0
            calc(var(--ziel-x) - 5.5rem * var(--rv));
}

/* Steht nur ein Gebäude da (Kapitel 6), sitzt es auf der Mittellinie. */
.reise-ziele--eins {
    margin-top: calc(var(--ziel-y) - 2.5rem * var(--rv));
}

.reise-ziel {
    position: relative;
    display: grid;
    justify-items: center;
    gap: calc(0.3rem * var(--rv));
}

/* Kontur wie jede andere Zeichnung der Sektion: dieselben Tokens, dieselbe
   Strichstärke. Keine zweite Bildsprache — nur Umriss, Dach, Öffnungen und ein
   Bodenstrich, damit auf 320 px ein Haus zu erkennen ist und kein Muster. */
.reise-haus {
    width: calc(4.8rem * var(--rv));
    height: auto;
    fill: none;
    stroke: var(--strich);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.reise-ziel b {
    font-family: var(--font-sans);
    font-size: calc(0.9rem * var(--rv));
    font-weight: 600;
    color: var(--espresso);
}

/* Das Aussehen jeder Sendung: dieselbe Kopfzeile, dieselben Zeilen, derselbe
   Fuß — ob Einreichung in Kapitel 4 oder Abrechnung in Kapitel 6. Es steht hier
   bei den gemeinsamen Bausteinen und nicht mehr bei Kapitel 6, weil es das
   längst nicht mehr allein gehört.

   left/top/margin sind der Ruheplatz für den Fall, dass niemand fliegt; .reise-flug
   darunter überschreibt beides. */
.reise-dokument {
    position: absolute;
    left: -4%;
    top: 50%;
    display: grid;
    gap: calc(0.45rem * var(--rv));
    width: calc(11rem * var(--rv));
    margin-top: calc(-4.5rem * var(--rv));
    padding: calc(1rem * var(--rv));
    background: var(--milk-pure);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    font-family: var(--font-app);
}

.reise-dokument-kopf {
    font-size: calc(0.72rem * var(--rv));
    font-weight: 700;
}

.reise-dokument-zeile {
    height: calc(0.4rem * var(--rv));
    background: var(--hairline);
    border-radius: var(--radius-pill);
}

.reise-dokument-zeile--kurz { width: 62%; }

.reise-dokument-fuss {
    margin-top: calc(0.2rem * var(--rv));
    font-size: calc(0.6rem * var(--rv));
    color: var(--stone-500);
}

/* ---- Das eine Flugmotiv, zweimal verwendet -------------------------------
   In Kapitel 4 fliegt die Einreichung vom Telefon zum Gebäude, in Kapitel 6 die
   Abrechnung vom Gebäude zum Telefon. Das ist DIESELBE Strecke, und genau darin
   liegt der Reiz — also steht sie auch als eine Formel da und nicht als zwei
   Animationen, die man beieinanderhalten müsste. Umgekehrt wird über das
   Vorzeichen: --flug-von/--flug-bis vertauschen, mehr ist es nicht.

   Der Anker ist das Telefon: --flug 0 heißt „am Gerät", 1 heißt „am Gebäude".
   Deshalb rechnet die Lage gegen --lage-x/--lage-y des Kapitels, genau wie der
   Bildschirm — steht das Gerät woanders, fliegt die Sendung mit.

   DER WEG WIRD GERECHNET, NICHT GERATEN: Anfang ist die Lage des Telefons,
   Ende die Lage des Gebäudes (--ziel-* plus dem Versatz --ab-* des einzelnen
   Hauses im Block). Beide Enden stehen ohnehin im Blatt; sie noch einmal als
   Weglänge daneben zu schreiben hieße, zwei Zahlen von Hand beieinanderzuhalten
   — und genau das ging beim ersten Anlauf schief, da flog die Einreichung an
   den Gebäuden vorbei aus dem Bild.

   Das Aussehen kommt von .reise-dokument und ist bewusst dasselbe: Was fliegt,
   unterscheidet sich nur im Text. Diese Regeln stehen deshalb NACH dem Block
   von .reise-dokument — bei gleicher Gewichtung zählt die Reihenfolge, und
   dessen left/margin würden die Lage sonst zurücknehmen. */
.reise-flug {
    position: absolute;
    left: 50%;
    top: 50%;
    width: calc(9.5rem * var(--rv));
    margin: calc(-3.2rem * var(--rv)) 0 0 calc(-4.75rem * var(--rv));
    --flug-x: calc(var(--ziel-x) + var(--ab-x, 0px)
                   - var(--lage-x, 0) * var(--tel-spanne-x));
    --flug-y: calc(var(--ziel-y) + var(--ab-y, 0px)
                   - var(--lage-y, 0) * var(--tel-spanne-y));
    opacity: 0;
}

/* ==========================================================================
   Kapitel 5 — Warten
   ========================================================================== */

/* Die Uhr liegt im Hintergrund und das Telefon klein davor. Sie steht deshalb
   absolut und nicht mehr im Fluss der Kunstfläche: Als einziges Flusskind stand
   sie mittig, und ein zweites Kind hätte beide nebeneinandergerückt. */
.reise-uhr {
    position: absolute;
    left: 6%;
    top: 50%;
    width: calc(15rem * var(--rv));
    height: calc(15rem * var(--rv));
    margin-top: calc(-7.5rem * var(--rv));
}

.reise-uhr svg {
    position: relative;
    z-index: 2;
    width: 100%;
    height: 100%;
}

.reise-uhr-rand { fill: var(--accent-muted); }
.reise-uhr-flaeche { fill: var(--milk-pure); }

/* Ring, Striche und beide Zeiger in DERSELBEN Strichstärke wie jede andere
   Zeichnung der Sektion. Sie standen bei 2, 3, 4 und 6 — vier der sechs
   Strichstärken, die ein Gestaltungs-Review gezählt hat, an einem einzigen
   Requisit. Der Stundenzeiger unterscheidet sich jetzt über seine Länge, und
   das ist auch die einzige Auskunft, die ein Uhrzeiger trägt. */
.reise-uhr-striche line {
    stroke: var(--accent);
    stroke-width: 2;
    stroke-linecap: round;
}

.reise-uhr-zeiger {
    stroke: var(--accent);
    stroke-width: 2;
    stroke-linecap: round;
}

.reise-uhr-mitte {
    fill: var(--accent-dark);
}

.reise-uhr-welle {
    position: absolute;
    inset: 0;
    border: 2px solid var(--accent);
    border-radius: 50%;
    opacity: 0;
}

/* DIE RANDREGEL VON KAPITEL 5: Der Bildschirm trägt seinen Gehäuserand hier
   auch im Player selbst. Das Gehäuse liegt UNTER den Kapiteln, die Uhr liegt
   im Kapitel — wo ihr Zifferblatt den Rahmen kreuzt, war der Rahmen weg:
   „Handy-Rand abgeschnitten". Der
   eigene Rand liegt deckungsgleich über dem des Gehäuses und füllt nur diese
   Lücke; sichtbar doppelt ist da nichts. Die Stufenzahl (drei gegen zwei der
   transparent-Regel in der Player-Fassung) ist Absicht. */
[data-reise-mode="player"] .reise-art--warten .reise-screen {
    border-color: var(--strich);
}

/* Der Wartezustand auf dem Bildschirm. Er trägt keine eigene Bildsprache:
   dieselbe Kopfzeile, dieselben Zeilen wie die Listen in Kapitel 4 und 6. */
.reise-screen--warten {
    position: absolute;
    left: 0;
    top: 50%;
    margin-top: calc(0rem - var(--reise-geraet-halbhoehe));
}

.reise-warten-marke {
    display: block;
    /* OBEN, direkt unter der Kopfzeile „EINREICHUNG" — wie eine App-Liste,
       nicht wie ein Splash. Keine senkrechte Zentrierung (margin-top: auto
       hier, margin-bottom: auto unter der Liste): Eine Liste beginnt oben,
       und die Leere darunter ist der leere Rest des Bildschirms. */
    margin-top: calc(0.2rem * var(--rv));
    margin-bottom: calc(0.7rem * var(--rv));
    font-family: var(--font-sans);
    font-size: calc(0.78rem * var(--rv));
    font-weight: 600;
    color: var(--espresso);
}

.reise-warten {
    display: grid;
    gap: calc(0.3rem * var(--rv));
}

.reise-warten-zeile {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: calc(0.4rem * var(--rv));
    padding: calc(0.4rem * var(--rv)) 0;
    border-bottom: 1px solid var(--hairline-row);
    font-size: calc(0.66rem * var(--rv));
}

.reise-warten-zeile b {
    font-weight: 500;
}

.reise-warten-zeile em {
    flex-shrink: 0;
    font-style: normal;
    color: var(--stone-500);
}

/* ==========================================================================
   Kapitel 6 — Abrechnung und Zuordnung
   ========================================================================== */

.reise-abrechnung {
    display: grid;
    gap: calc(0.3rem * var(--rv));
}

.reise-abrechnung-zeile {
    position: relative;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: calc(0.4rem * var(--rv));
    padding: calc(0.4rem * var(--rv)) 0;
    border-bottom: 1px solid var(--hairline-row);
    font-size: calc(0.66rem * var(--rv));
}

.reise-abrechnung-zeile b {
    font-weight: 500;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.reise-abrechnung-zeile em {
    flex-shrink: 0;
    font-style: normal;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.reise-abrechnung-zeile--abgelehnt {
    padding-inline: calc(0.35rem * var(--rv));
    border-radius: var(--radius-xs);
}

.reise-abrechnung-zeile--abgelehnt::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--status-error-bg);
    border-radius: var(--radius-xs);
    transform-origin: left center;
    transform: scaleX(1);
}

.reise-abrechnung-zeile--abgelehnt b,
.reise-abrechnung-zeile--abgelehnt em {
    position: relative;
    z-index: 1;
    color: var(--danger);
    font-weight: 600;
}

/* Das Telefon rückt nach rechts, damit Gebäude und Karten links Platz haben —
   dieselbe Seitenverteilung wie im Player, wo die Lage des Kapitels das Gerät
   nach rechts stellt. */
.reise-art--abrechnung .reise-screen {
    margin-left: 42%;
}

/* Die Karten stehen am --ziel-Anker: An der Stelle, an der das Gebäude
   geliefert hat, stehen danach die zugeordneten Belege. Ein Anker statt einer
   zweiten Zahl — rückt das Gebäude (mobil unter das Telefon), rücken die
   Karten mit, und sie stehen damit von selbst neben dem Gerät statt am Rand
   der Kunstfläche. */
.reise-belegkarten {
    position: absolute;
    left: 50%;
    top: 50%;
    display: grid;
    gap: calc(0.7rem * var(--rv));
    width: calc(12rem * var(--rv));
    margin: calc(var(--ziel-y) - 5.6rem * var(--rv)) 0 0
            calc(var(--ziel-x) - 6rem * var(--rv));
}

/* DIE MASKIER-TASCHE IST ERSATZLOS ENTFALLEN (Schritt 8, FEATURE-0143). Sie war eine Fläche in --milk mit 0,4 rem
   Überstand hinter den Karten — unsichtbar vor dem Grund, aber überall dort,
   wo die Karten das Gerät überlappen, ein BEIGER RAND um weiße Karten, der
   das Telefon abgeschnitten aussehen ließ. Was sie leistete, leisten jetzt
   die Karten selbst: Sie sind deckend (milk-pure, siehe Linienstil-Block),
   ihre Deckkraft springt beim Auftritt steil statt lang zu blenden (Fenster
   in der Kapitel-6-Choreografie), und hochkant schließen sie zu einem
   lückenlosen Stapel (767er-Abfrage) — es gibt keine Fugen mehr, durch die
   die Telefonecken stümmeln könnten. */

.reise-belegkarte {
    display: grid;
    gap: calc(0.15rem * var(--rv));
    padding: calc(0.65rem * var(--rv)) calc(0.8rem * var(--rv));
    background: var(--milk-pure);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    font-family: var(--font-app);
}

.reise-belegkarte b {
    font-size: calc(0.74rem * var(--rv));
    font-weight: 600;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.reise-belegkarte em {
    font-style: normal;
    font-size: calc(0.64rem * var(--rv));
    color: var(--stone-500);
}

.reise-belegkarte u {
    justify-self: start;
    margin-top: calc(0.2rem * var(--rv));
}

/* ==========================================================================
   Kapitel 7 — Widerspruch
   ========================================================================== */

.reise-wahl {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: calc(0.5rem * var(--rv));
    margin-top: auto;
}

.reise-wahl .reise-taste {
    margin-top: 0;
}

/* DER ENTWURF STEHT FREI NEBEN DEM GERÄT — am --ziel-Anker, an dem in
   Kapitel 6 das Gebäude geliefert hat und die Belegkarten standen. Er lag
   vorher deckend IM Bildschirm und verdeckte dort genau die abgelehnte
   Position, aus der er hervorgeht. Schritt 9: Man soll
   im Handy weiterhin sehen, WAS abgelehnt wurde, während daneben die Antwort
   entsteht. Ein Blatt neben dem Gerät ist dieselbe Bildsprache wie Beleg und
   Dokument — Kontur und Fläche bekommt er im Linien-Abschnitt unten wie jedes
   andere Requisit.

   Davor lag er schon einmal frei über der Kunstfläche und zerschnitt Text.
   Der Unterschied zu damals ist der Anker: Die linke Bühnenhälfte ist in
   Kapitel 7 leer (die Belegkarten sind mit Kapitel 6 gegangen), er steht auf
   einem Platz, der ihm gehört, statt über fremden Requisiten. */
.reise-entwurf {
    position: absolute;
    left: 50%;
    top: 50%;
    display: flex;
    flex-direction: column;
    width: calc(12.5rem * var(--rv));
    margin: calc(var(--ziel-y) - 6rem * var(--rv)) 0 0
            calc(var(--ziel-x) - 6.25rem * var(--rv));
    padding: calc(0.9rem * var(--rv)) calc(0.8rem * var(--rv));
    background: var(--milk-pure);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    font-family: var(--font-app);
}

.reise-entwurf .reise-taste--senden {
    margin-top: calc(0.6rem * var(--rv));
}

/* Statisch steht das Gerät in Kapitel 7 rechts (wie in Kapitel 6, wo die
   margin-left-Zeile oben dasselbe leistet), damit der Entwurf links neben ihm
   Platz hat — .reise-screen--links läge sonst auf dem --ziel-Anker. Nur quer:
   Hochkant zentriert die Mobil-Abfrage alle Bildschirme, und der Entwurf
   steht unter dem Gerät. Im Player wiegt die Lage-Regel vier Stufen und
   bleibt unberührt. */
@media (min-width: 768px) {
    .reise-art--widerspruch .reise-screen--links {
        left: auto;
        right: 0;
    }
}

/* Die Erfolgsmeldung von Beat 2 liegt IM Bildschirm über der Liste: Der
   Vorgang ist auf dem Gerät erledigt, also sagt es das Gerät. 1-px-Rand und
   Radius wie die Karten — sie ist Druckbild der App, keine Kontur. Grundwert
   unsichtbar: Sie gehört allein dem Player; das Ruhebild der statischen
   Fassung erzählt Kapitel 7 über den geschriebenen Entwurf. */
.reise-erfolg {
    position: absolute;
    left: calc(0.7rem * var(--rv));
    right: calc(0.7rem * var(--rv));
    top: 50%;
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: calc(0.5rem * var(--rv));
    margin-top: calc(-1.5rem * var(--rv));
    padding: calc(0.7rem * var(--rv)) calc(0.6rem * var(--rv));
    background: var(--milk-pure);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    opacity: 0;
    z-index: 4;
}

.reise-erfolg b {
    font-size: calc(0.78rem * var(--rv));
    font-weight: 600;
    color: var(--espresso);
}

.reise-entwurf-kopf {
    display: block;
    margin-bottom: calc(0.5rem * var(--rv));
    font-size: calc(0.62rem * var(--rv));
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--stone-500);
}

/* Das Schreibfeld nimmt den Platz, der zwischen Kopfzeile und Absende-Knopf
   übrig ist — der Bildschirm gibt die Höhe vor, nicht eine Mindesthöhe hier.
   milk-pure statt milk: Der Entwurf liegt jetzt auf milk, und ein Feld in
   derselben Farbe wie sein Grund ist keines. */
.reise-entwurf-text {
    flex: 1;
    margin: 0;
    padding: calc(0.6rem * var(--rv));
    background: var(--milk-pure);
    border: 1px solid var(--hairline-soft);
    border-radius: var(--radius-xs);
    font-size: calc(0.72rem * var(--rv));
    line-height: 1.6;
    color: var(--espresso);
}

.reise-cursor {
    display: inline-block;
    width: 1px;
    height: calc(0.85rem * var(--rv));
    margin-left: 1px;
    background: var(--espresso);
    vertical-align: text-bottom;
}

/* Die Taube startet AM ENTWURF, nicht am Telefon: Seit der Entwurf frei neben
   dem Gerät steht, ist der Absende-Knopf dort — was auffliegt, ist das
   Schreiben, und es fliegt von seinem Blatt weg. Sie hängt deshalb am selben
   --ziel-Anker wie der Entwurf, etwas unter dessen Mitte, wo der Knopf steht.
   Der Weg selbst steht in der Choreografie und braucht keine Gerätelage mehr:
   Der Startpunkt ist eine feste Stelle der Kunstfläche. */
.reise-brieftaube {
    position: absolute;
    left: 50%;
    top: 50%;
    width: calc(3.6rem * var(--rv));
    margin: calc(var(--ziel-y) + 1.2rem * var(--rv))
            0 0 calc(var(--ziel-x) - 1.8rem * var(--rv));
    opacity: 0;
    z-index: 4;
}

.reise-brieftaube svg {
    width: 100%;
    height: auto;
    fill: var(--milk-pure);
    stroke: var(--crema);
    stroke-width: 2;
    stroke-linejoin: round;
}

.reise-brieftaube-klappe {
    fill: none;
}

/* ==========================================================================
   Choreografie — Endzustände über --sp, aktive Loops über Beat-Zustände
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

    /* ---- Impulse: Tastendruck und Fingertipp ----

       Beides sind Ereignisse, keine Zustände: Sie haben einen Anfang UND ein
       Ende. Am Scroll-Fortschritt braucht das ein Fenster, das wieder auf null
       zurückgeht. Hängt ein Druck monoton am Fortschritt, sinkt die Taste und
       bleibt über den Rest der Szene eingedrückt; und `1 - t` als Deckkraft
       ergibt vor dem Startpunkt 1, weshalb der Tipp-Ring von Beginn an auf der
       Taste klebt. Beides war so gebaut.

       Jede Stelle setzt nur ihren Startpunkt, die Form steht hier einmal. Der
       unerreichbare Vorgabewert bedeutet „passiert nie": Ohne Startpunkt bleibt
       die Taste unberührt und der Ring unsichtbar.

       DIE BREITE RECHNET IN BEAT-ANTEILEN wie jedes andere Fenster. Sie stand
       hier als feste 0,09 in --sp, während die Rampe daneben beat-geteilt war
       (--w-mittel = 0,22 / Beats). In einem Kapitel mit einem Beat war die
       Rampe damit zweieinhalbmal breiter als der ganze Impuls: Der Druck kam
       auf 20 Prozent Tiefe, der Ring auf 54, und die Geste war nicht mehr zu
       sehen. Auf und ab über je --w-kurz, dazwischen ein kurzer Halt — zusammen
       2,4 × --w-kurz, also 0,29 eines Beats, rund 260 ms Weg. */

    [data-reise-mode="player"] .reise-taste,
    [data-reise-mode="player"] .reise-bank-taste,
    [data-reise-mode="player"] .reise-sucher-ausloeser {
        --druck: clamp(0, min(calc((var(--sp) - var(--druck-ab, 9)) / var(--w-kurz)),
                              calc((var(--druck-ab, 9) + 2.4 * var(--w-kurz) - var(--sp))
                                   / var(--w-kurz))), 1);
    }

    /* Getrennt vom Rechnen: Der Druck ist eine Zahl, das Einsinken ist eine
       Darstellung davon, und der Fingertipp darin liest dieselbe Zahl.
       Die PKV stand hier bis August 2026 mit — als Kachel, die auf einen
       Tastendruck einsank. Sie ist ein Ort, kein Bedienelement; mit dem Gebäude
       ist der Druck ersatzlos entfallen. */
    [data-reise-mode="player"] .reise-taste,
    [data-reise-mode="player"] .reise-bank-taste,
    [data-reise-mode="player"] .reise-sucher-ausloeser {
        transform: scale(calc(1 - var(--druck) * var(--druck-tiefe, 0.05)));
    }

    /* Der Scroll sagt nur, OB gerade getippt wird. Wie der Ring dabei aussieht,
       ist ein einziger Zustand, gestaffelt dargestellt — das läuft nach eigener
       Uhr weiter, solange man an der Stelle steht (§9). Am Fortschritt hinge
       sonst eine Geste, die man von Hand aufziehen müsste. */
    /* Ein Haken setzt sich überall gleich: aus 40 Prozent Größe auf volle, im
       kurzen Takt. Unterschiedlich ist nur, wann. Vorher hatte jede der drei
       Stellen ihre eigene Startgröße (0, 0,4 und 0,5). */
    [data-reise-mode="player"] .reise-fahne-haken,
    [data-reise-mode="player"] .reise-quittung-haken,
    [data-reise-mode="player"] .reise-haken::after {
        --k: clamp(0, calc((var(--sp) - var(--haken-ab, 9)) / var(--w-kurz)), 1);
        opacity: var(--k);
        transform: scale(calc(0.4 + var(--k) * 0.6));
    }

    /* Der Ring ist so sichtbar, wie der Druck tief ist — dieselbe Zahl, einmal
       gerechnet. Er erbt sie: --druck steht an der Taste, der Ring liegt darin.
       Vorher trug jede Stelle einen zweiten Startpunkt (--tipp-ab), immer
       0,02 vor dem Druck, und beide Fenster mussten von Hand beieinander
       gehalten werden. Ein Fingertipp und der Druck darunter sind aber EIN
       Ereignis. */
    [data-reise-mode="player"] .reise-tipp {
        opacity: var(--druck, 0);
    }

    /* ---- Der Flug zwischen Telefon und Gebäude ---------------------------
     * Zweimal dieselbe Strecke: In Kapitel 4 geht die Einreichung hin, in
     * Kapitel 6 kommt die Abrechnung zurück. EINE Formel, umgekehrt über das
     * Vorzeichen — zwei getrennte Animationen müsste jemand von Hand
     * beieinanderhalten, und der Reiz liegt gerade darin, dass beide Wege
     * derselbe sind.
     *
     *   --t     Fortschritt DES FLUGES, 0 bis 1, immer in Flugrichtung.
     *   --flug  0 = am Telefon, 1 = am Gebäude. Hinweg 0→1, Rückweg 1→0.
     *   --bogen 0 an beiden Enden, 1 in der Mitte.
     *
     * Alles, was nicht die Richtung betrifft, hängt am BOGEN und nicht am Flug:
     * Deckkraft, Neigung, Maßstab. Deshalb sieht der Rückweg aus wie der Hinweg
     * rückwärts und nicht wie eine zweite Bewegung — die Sendung taucht am
     * einen Ende auf, wächst unterwegs, und schrumpft am anderen wieder
     * hinein.
     *
     * Der Maßstab macht aus dem Weg eine Übergabe: Was klein aus dem Gerät
     * kommt und klein im Gebäude ankommt, ist dort hineingegangen. Eine Sendung
     * in voller Größe läge nur davor.
     */
    [data-reise-mode="player"] .reise-flug {
        --t: clamp(0, calc((var(--sp) - var(--flug-ab, 9)) / var(--flug-weg, 0.4)), 1);
        --flug: calc(var(--flug-von, 0)
                     + (var(--flug-bis, 1) - var(--flug-von, 0)) * var(--t));
        --bogen: calc(var(--t) * (1 - var(--t)) * 4);
        /* Ein Plateau statt einer Spitze: Sichtbar ist die Sendung fast den
           ganzen Weg, nur die letzten Achtel an beiden Enden blenden. */
        opacity: clamp(0, min(calc(var(--t) / 0.16),
                              calc((1 - var(--t)) / 0.16)), 1);
        transform:
            translate(calc(var(--lage-x, 0) * var(--tel-spanne-x)
                           + var(--flug) * var(--flug-x)),
                      calc(var(--lage-y, 0) * var(--tel-spanne-y)
                           + var(--flug) * var(--flug-y)))
            rotate(calc(var(--bogen) * -7deg))
            scale(calc(0.4 + var(--bogen) * 0.6));
    }

    /* ---- Kapitel 1: zwei Beats, Grenze bei 0,5 ----
     *
     * DIE RUHEPUNKT-REGEL — sie gilt für das ganze Blatt und wird von
     * scripts/reise_ruhebilder.py nachgerechnet:
     *
     *   Kein Fenster darf einen Ruhepunkt enthalten.
     *
     * Ruhepunkte sind --sp = k/beats, hier also 0,5 und 1. Liegt einer
     * echt innerhalb von (Anfang, Anfang + Weite), steht das Element im Ruhebild
     * halb da — und zwar nicht einen Frame lang wie unter Scrubbing, sondern die
     * volle Haltezeit von 1,6 Sekunden. Bei einem absteigenden Fenster
     * (E − --sp) ist der Anfang E − Weite; genau das wurde hier zweimal
     * übersehen. Wer eine Schwelle verschiebt, lässt das Skript laufen. */

    /* Der Stapel verschwindet, sobald das Scannen beginnt — also IN Beat 2, nie
       davor: Ein Stapel, der weg ist, bevor sein eigener Beat zu Ende ist,
       stünde am Ruhepunkt halb da. */
    [data-reise-mode="player"] .reise-stapel {
        opacity: clamp(0, calc((0.63 - var(--sp)) / var(--w-mittel)), 1);
    }

    /* Die Klappe oeffnet im selben Zug wie die Rechnung erscheint — die eine
       ruhige Bewegung des Anspielens, nachdem der Zug gestrichen ist. */
    [data-reise-mode="player"] .reise-brief-klappe {
        transform: scaleY(calc(1 - clamp(0, calc(var(--sp) / 0.4), 1) * 0.9));
    }

    /* DER ZUG AUS DEM UMSCHLAG IST GESTRICHEN (FEATURE-0143): Der Beleg fuhr
       von hinter den Briefen rein und war dann ploetzlich oben. Drei Nacharbeiten an derselben Choreografie
       (beiger Rand, Ebenen-Sprung, hektischer Auftritt) waren das Signal,
       dass die Erzaehlung zu viel wollte: herausziehen, vortreten, ablegen —
       in 900 ms Anspielzeit. Jetzt blenden Stapel und Rechnung gemeinsam ein,
       die Rechnung liegt von Anfang an vorn (die geoeffnete Klappe erzaehlt
       das Oeffnen). Das Flusskind hier bleibt als Hoehengeber der Kunstflaeche
       im DOM und traegt die STATISCHE Fassung — im Player ist durchgehend die
       vordere Fassung sichtbar. */
    [data-reise-mode="player"] .reise-beleg--reise {
        opacity: 0;
    }

    /* Scanrahmen und Telefon gehören zu Beat 2. Der Rahmen bleibt stehen, bis
       der Scan durchgelaufen ist (0,66–0,88), und geht dann zusammen mit dem
       Auslöser (0,88–0,94) — vorher schloss sein Fenster bei 0,80 und schnitt
       den Durchlauf ab. */
    [data-reise-mode="player"] .reise-scanrahmen {
        opacity: clamp(0, min(calc((var(--sp) - 0.51) / var(--w-mittel)),
                              calc((0.94 - var(--sp)) / var(--w-kurz))), 1);
    }

    /* Der Scan läuft GENAU EINMAL komplett von oben bis ganz unten — am
       Fortschritt, nicht nach eigener Uhr. Vorher lief hier eine 1,65-s-
       Endlosschleife, solange Beat 2 aktiv war: Mit der Ease-out-Kurve des
       Players war das Fenster des Rahmens nach rund 770 ms vorbei, und die
       Schleife kam nie unten an.
       Das Fenster (0,66–0,88) liegt hinter dem steilen Anfang der Kurve; bei
       2200 ms Schrittdauer sind das rund 700 ms sichtbarer Durchlauf.
       Deckkraft als Plateau: auf dem Weg voll da, an beiden Enden kurz
       blendend, damit der Streifen nicht oben und unten stehend erscheint. */
    [data-reise-mode="player"] .reise-scanlinie {
        --sl: clamp(0, calc((var(--sp) - 0.66) / (var(--w-mittel) * 2)), 1);
        opacity: clamp(0, min(calc(var(--sl) / 0.12),
                              calc((1 - var(--sl)) / 0.12)), 1);
        transform: translateY(calc(var(--sl) * var(--scan-strecke)));
    }

    /* Herein von rechts — und dann bleibt es. Der frühere Abflug nach links
       (-(100vw + 100%) ab --sp 0,62) ist mit dem persistenten Gehäuse entfallen:
       Das Telefon verlässt das Bild nicht mehr, es geht in Kapitel 2 weiter.
       Unter Scrubbing fiel das nicht auf; im Player stünde der Ruhepunkt von
       Beat 2 mitten im Abflug, also ein Telefon zu zwei Dritteln aus dem Bild.

       Der Eintritt beginnt bei 0,51 und damit knapp NACH dem Ruhepunkt von
       Beat 1 (--sp 0,5). Bei 0,49 stünde dort ein halb sichtbarer Bildschirm —
       unter Scrubbing ein Frame, im Player 1,6 Sekunden Geisterrest. */
    [data-reise-mode="player"] .reise-screen--haltend {
        --rein: clamp(0, calc((var(--sp) - 0.51) / var(--w-mittel)), 1);
        opacity: var(--rein);
    }

    [data-reise-mode="player"] .reise-sucher-ausloeser {
        --druck-ab: 0.63;
        --druck-tiefe: 0.18;
    }

    /* Der Auslöser geht mit der Ankunft des Fotos (0,88–0,94): Sobald der
       Bildschirm den erfassten Beleg zeigt, ist die Kamera nicht mehr die
       Geschichte, und ein roter Knopf unter dem Ergebnis widerspräche ihr.
       Das Sucher-Raster, das hier mitging, ist ersatzlos entfallen (brauner
       Rahmen, siehe die Basisregeln von Kapitel 1). */
    [data-reise-mode="player"] .reise-sucher-ausloeser {
        opacity: clamp(0, calc((0.94 - var(--sp)) / var(--w-kurz)), 1);
    }

    /* Der Weg hinter das Gerät: Auslösen (0,63), der Scan läuft durch
       (0,66–0,88), dann schiebt sich das Blatt HINTER das Telefon (0,78–0,96)
       — nach rechts und leicht nach unten, und weil es in Kapitel 1 unter dem
       Bildschirm liegt (Stapelordnung), verschwindet es sichtbar dahinter.
       Vorher flog es AUF das Display und schrumpfte dort — das las sich, als
       käme der Beleg von oben ins Telefon geflogen. Er soll von hinten/unten
       kommen, als entstünde das Foto im Gerät. Alle Fenster schließen vor --sp 1.

       Sichtbar ist die Fassung von Beat 1 an (gemeinsamer Auftritt mit dem
       Stapel, siehe unten). Die spaete Blende (0,90–0,96) raeumt ab, was der
       Bildschirm nicht verdeckt. */
    /* NACHEINANDER, NICHT GEKREUZT (Sichtungs-Befund, August 2026): Das
       Papier schloss erst bei 0,96, während die Display-Fassung ab 0,88
       aufstieg — acht Hundertstel lang standen beide Fassungen halb sichtbar
       versetzt übereinander, ein Doppeldruck. Jetzt ist das Papier bei 0,90
       komplett weg, DANN kommt die Display-Fassung (0,90, unten bei
       --erfasst). */
    /* Die Rechnung tritt mit dem Stapel gemeinsam auf — ein ruhiges Bild
       statt einer Zieh-Choreografie: "alles gleichzeitig ohne falsche
       Ueberlappung einblenden". Ein Hauch Anheben (2 %) gibt dem Einblenden
       Richtung, mehr Bewegung traegt Beat 1 nicht mehr. Ab 0,78 der Weg
       hinter das Telefon, unveraendert. */
    [data-reise-mode="player"] .reise-beleg--vorn {
        --vorn-weg: calc(var(--w-mittel) * 1.6);
        --f: clamp(0, calc((var(--sp) - 0.78) / var(--vorn-weg)), 1);
        /* Ueber den ganzen Beat gestreckt (0 bis 0,44, schliesst vor dem
           Ruhepunkt 0,5): In 900 ms Anspielzeit ist ein w-mittel-Fenster nach
           rund 100 ms durch, und die Einladung waere unsichtbar. */
        --auf: clamp(0, calc(var(--sp) / 0.44), 1);
        opacity: clamp(0, min(var(--auf),
                              calc((0.90 - var(--sp)) / var(--w-kurz))), 1);
        transform:
            translate(calc(-50% + var(--f) * var(--vorn-x)),
                      calc(-50% + (1 - var(--auf)) * 2% + var(--f) * 18%))
            scale(calc(1 - var(--f) * 0.2));
    }

    /* Das Foto entsteht im Gerät: Der erfasste Beleg steigt von der
       Unterkante des Displays auf (der Bildschirm schneidet ab, overflow:
       hidden) und füllt es dann randlos — Briefkopf und Positionen, nicht
       nur ein Sucher. Das Fenster (0,90–0,99)
       beginnt exakt dort, wo das Papier komplett verschwunden ist (Blende
       des Papiers oben), und schließt vor --sp 1. */
    [data-reise-mode="player"] .reise-beleg--erfasst {
        --e: clamp(0, calc((var(--sp) - 0.90) / (var(--w-kurz) * 1.5)), 1);
        opacity: var(--e);
        transform: translateY(calc((1 - var(--e)) * 45%));
    }

    /* ---- Kapitel 2: zwei Beats, Grenze bei 0,5 ----
     *
     * Drei Takte statt elf Einzelereignisse: Felder markiert, Felder benannt,
     * Felder abgehakt. „Alles automatisch erkannt" ist EIN Gedanke, und die
     * Reihenfolge der Felder sagt nichts aus — jedes einzeln nachschieben zu
     * lassen zerteilt ihn in Portionen.
     *
     * Innerhalb eines Takts laufen die Elemente aber als Welle, nicht synchron:
     * überlappend, mit 70 ms Versatz. Das ist der eine Fall, in dem Zeit richtig
     * ist (§9, „wann darf etwas nach eigener Uhr laufen"), und zwar aus einem
     * technischen Grund: Ein Scroll-Versatz kann keine Welle erzeugen. Wahrnehmbar
     * wird eine Staffelung ab etwa 80 ms Abstand, das sind bei normaler
     * Scrollgeschwindigkeit 80 bis 150 px und hier rund 0,12 --sp — genau die
     * sequenziellen Schwellen, die es vorher waren. Kleiner Versatz ist unsichtbar,
     * großer ist Nachschieben. Dazwischen liegt nichts.
     *
     * Die Wellen hängen deshalb an [data-active-beat="1"], nicht an --sp. Was den
     * Takt AUSLÖST, bleibt der Scroll; nur die Verteilung innerhalb der 420 ms
     * gehört der Uhr. In Beat 2 greifen die Selektoren nicht mehr und die
     * scrollgebundenen Formeln übernehmen wieder — an der Beat-Grenze stehen beide
     * auf demselben Wert, es gibt also keinen Sprung. */
    [data-reise-mode="player"] .reise-beleg--erkannt [data-feld]::after {
        transform: scaleX(clamp(0, calc((var(--sp) - 0.04) / var(--w-kurz)), 1));
    }

    /* Die Belegnummer bleibt ohne Markierung — sie wird gelesen, aber nicht als
       erkanntes Feld ausgezeichnet. */
    [data-reise-mode="player"] .reise-beleg--erkannt [data-feld="nummer"]::after {
        transform: scaleX(0);
    }

    /* Takt zwei: die Schilder. Sie weichen IN Beat 2 wieder, deshalb steht das
       Ausblenden hier und nicht in der Welle. Es endete bei 0,56 und begann
       damit bei 0,45: Am Ruhepunkt von Beat 1 hingen alle vier Schilder bei
       55 Prozent — halb durchsichtig über der Rechnung, die sie benennen. */
    [data-reise-mode="player"] .reise-fahne {
        --f: clamp(0, calc((var(--sp) - 0.17) / var(--w-mittel)), 1);
        --fahne-von: -10px;
        opacity: clamp(0, min(calc((var(--sp) - 0.17) / var(--w-mittel)),
                              calc((0.62 - var(--sp)) / var(--w-mittel))), 1);
        transform: translateX(calc((1 - var(--f)) * var(--fahne-von)));
    }

    [data-reise-mode="player"] .reise-fahne--betrag,
    [data-reise-mode="player"] .reise-fahne--position {
        --fahne-von: 10px;
    }

    /* Takt drei: alle Haken gemeinsam, kurz nach den Schildern. Der Versatz zum
       Kreis lässt es wie ein Abhaken wirken statt wie ein fertiges Etikett. */
    [data-reise-mode="player"] .reise-fahne-haken {
        --haken-ab: 0.29;
    }

    /* 0,34 statt 0,38: Der Impuls ist mit 2,4 × --w-kurz jetzt 0,144 breit
       und liefe sonst über den Ruhepunkt bei 0,5 — eine Taste, die am
       Beat-Ende halb eingedrückt stehenbleibt. */
    [data-reise-mode="player"] .reise-taste--bestaetigen {
        --druck-ab: 0.34;
    }

    /* Beat 2: die auffällige Position wird markiert, DANN kommt die Empfehlung
       — zwei Züge nacheinander, das ist der Aufbau dieses Schritts.

       Die Fenster liegen bewusst SPÄT im Beat (Marker 0,70, Empfehlung 0,82):
       Bei 0,58/0,68 lagen beide im schnellen Teil der Ease-out-Kurve und
       waren nach rund 250 ms durch — der Schritt zeigte in jedem Teilbild
       dasselbe fertige Bild, als hätte er keine Animation (Sichtungs-Befund,
       August 2026). In der langsamen Kurvenhälfte und mit data-dauer 1800 an
       der Caption bekommt der Marker real rund 150 ms ab 300 ms und die
       Empfehlung rund 400 ms ab 500 ms — erst sieht man die Zeile sich
       markieren, dann erscheint der Rat dazu. Beide Fenster schließen vor dem
       Ruhepunkt 1 (0,76 und 0,93). */
    [data-reise-mode="player"] .reise-beleg--erkannt .reise-beleg-zeile--auffaellig::after {
        transform: scaleX(clamp(0, calc((var(--sp) - 0.70) / var(--w-kurz)), 1));
    }

    [data-reise-mode="player"] .reise-empfehlung {
        --e: clamp(0, calc((var(--sp) - 0.82) / var(--w-mittel)), 1);
        opacity: var(--e);
        transform: translateY(calc((1 - var(--e)) * var(--weg-klein)));
    }

    /* ---- Kapitel 3: EIN Beat ----
       Keine Zwei-Beat-Teilung (FEATURE-0143). Eine Sequenz in einem Schritt: die Banking-App erkennen
       (Logo, „Meine Bank", Taste), der sichtbare Druck auf „Per QR-Code
       bezahlen", der Scan über die Karte hinunter und hinauf, dann die
       Erfolgsmeldung UNTER dem Bank-Logo — kein Screen-Wechsel. Als Nachklang
       wechselt die Arztrechnung daneben von offen auf bezahlt.

       Mit data-dauer 4400 und der Ease-out-Kurve, gemessen ab Schrittanfang:
       Druck ab ~440 ms, Scan ~710–1390 ms (hinunter und hinauf), Erfolg ab
       ~1550 ms, Statuswechsel ab ~2070 ms — danach Ruhe bis zur Eingabe. */

    /* Die App zuerst: Sie blendet gleich zu Beginn ein und steht dann still —
       die Standzeit bis zum Tastendruck (0,24) ist die Erkennzeit. Nur
       blenden, nicht anfliegen: Das Gehäuse steht schon da, und ein
       Bildschirminhalt, der neben seinem eigenen Rahmen hereinrutscht, sieht
       nach Fehler aus. */
    [data-reise-mode="player"] .reise-screen--banking {
        --b: clamp(0, calc((var(--sp) - 0.02) / var(--w-kurz)), 1);
        opacity: var(--b);
    }

    [data-reise-mode="player"] .reise-qr {
        --q: clamp(0, calc(var(--sp) / var(--w-mittel)), 1);
        opacity: var(--q);
        transform: scale(calc(0.9 + var(--q) * 0.1));
    }

    /* Der sichtbare Klick, der den Scan anstößt. --druck-tiefe 0.08 statt der
       0.05 der Vorgabe: Dieser Klick IST der Erzählschritt (sichtbar
       gedrückt), und bei 4,4 s Schrittdauer läuft der Impuls langsam
       — flacher wäre er kaum zu sehen.

       Nach dem Erfolg blendet die Taste aus (gegen 0,88, nach der Quittung ab
       0,72 und vor dem Ruhepunkt): Sie ist benutzt, und im Ruhebild deckte die
       Arztrechnungs-Karte sie sonst HALB — halb verdeckt liest sich als
       Fehler, ganz weg ist die Aussage „bezahlt". */
    [data-reise-mode="player"] .reise-bank-taste--qr {
        --druck-ab: 0.24;
        --druck-tiefe: 0.08;
        opacity: clamp(0, calc((0.88 - var(--sp)) / var(--w-kurz)), 1);
    }

    /* Der Strahl fährt nach dem Druck über den Code: einmal hinunter und
       wieder hinauf (--lauf ist ein Dreieck über --s). Fenster 0,38–0,68 —
       nach dem Druckimpuls, in der langsameren Kurvenhälfte; mit data-dauer
       4400 rund 0,8 s gut sichtbarer Lauf. */
    [data-reise-mode="player"] .reise-qr-strahl {
        --s: clamp(0, calc((var(--sp) - 0.38) / (var(--w-mittel) * 1.36)), 1);
        --lauf: calc(1 - max(calc(1 - 2 * var(--s)), calc(2 * var(--s) - 1)));
        opacity: calc(var(--s) * (1 - var(--s)) * 4);
        transform: translateY(calc(var(--lauf) * var(--qr-breite)));
    }

    /* JEDES FENSTER MUSS VOR --sp 1 SCHLIESSEN. Unter Scrubbing lief --sp über
       die Kapitelgrenze hinaus, und was am Ende noch fehlte, holte die Blende
       zum nächsten Kapitel. Im Player hält --sp bei exakt 1 an — was hier
       nach 0,98 noch offen ist, steht im Ruhebild halb da.
       Wer Schwellen verschiebt, rechnet Anfang plus Fenster nach. */

    /* Nach dem Scan: die Erfolgsmeldung unter dem Logo, mit kleinem Aufstieg
       aus der Zeile darunter. */
    [data-reise-mode="player"] .reise-quittung {
        --qe: clamp(0, calc((var(--sp) - 0.72) / var(--w-kurz)), 1);
        opacity: var(--qe);
        transform: translateY(calc((1 - var(--qe)) * var(--weg-klein)));
    }

    [data-reise-mode="player"] .reise-quittung-haken {
        --haken-ab: 0.76;
    }

    /* Die Arztrechnung steht von Beginn an im Bild — mit „Offen", damit der
       Statuswechsel am Ende eine Geschichte hat. */
    [data-reise-mode="player"] .reise-zahlbeleg {
        --zb: clamp(0, calc((var(--sp) - 0.04) / var(--w-mittel)), 1);
        opacity: var(--zb);
        transform: translateY(calc((1 - var(--zb)) * var(--weg-klein)));
    }

    [data-reise-mode="player"] .reise-zahlbeleg-status .reise-badge--zahlung-offen {
        opacity: clamp(0, calc((0.92 - var(--sp)) / var(--w-kurz)), 1);
    }

    [data-reise-mode="player"] .reise-zahlbeleg-status .reise-badge--zahlung-bezahlt {
        opacity: clamp(0, calc((var(--sp) - 0.84) / var(--w-kurz)), 1);
    }

    /* ---- Kapitel 4: ein Beat ----
     *
     * DER RHYTHMUS IST: markieren — Pause — Druck — Pause — Flug. Ohne die
     * Pausen läuft alles zu schnell hintereinander. Die Fenster sind gegen die Ease-out-Kurve gestaffelt
     * und mit data-dauer 3600 an der Caption gerechnet (Zeiten unten je
     * Marke): Die frühen Fenster laufen real drei- bis viermal schneller als
     * ihre --sp-Breite sagt, deshalb liegen Druck und Flüge bewusst in der
     * langsamen Kurvenhälfte. */

    /* Die drei Zeilen markieren sich nacheinander (bis ~430 ms), dann steht
       das Bild kurz still — die erste Pause (~240 ms), bevor gedrückt wird. */
    [data-reise-mode="player"] .reise-auswahl-zeile[data-pos="1"]::before {
        transform: scaleX(clamp(0, calc((var(--sp) - 0.06) / var(--w-kurz)), 1));
    }

    [data-reise-mode="player"] .reise-auswahl-zeile[data-pos="2"]::before {
        transform: scaleX(clamp(0, calc((var(--sp) - 0.13) / var(--w-kurz)), 1));
    }

    [data-reise-mode="player"] .reise-auswahl-zeile[data-pos="3"]::before {
        transform: scaleX(clamp(0, calc((var(--sp) - 0.20) / var(--w-kurz)), 1));
    }

    [data-reise-mode="player"] .reise-auswahl-zeile[data-pos="1"] .reise-haken::after {
        --haken-ab: 0.06;
    }

    [data-reise-mode="player"] .reise-auswahl-zeile[data-pos="2"] .reise-haken::after {
        --haken-ab: 0.13;
    }

    [data-reise-mode="player"] .reise-auswahl-zeile[data-pos="3"] .reise-haken::after {
        --haken-ab: 0.20;
    }

    /* Der Druck kommt NACH der Pause (0,44; Talsohle real bei ~900 ms) und
       tiefer als die Vorgabe: Er ist der Erzählschritt dieser Szene. */
    [data-reise-mode="player"] .reise-taste--einreichen {
        --druck-ab: 0.44;
        --druck-tiefe: 0.12;
    }

    /* Die Gebäude haben keine eigene Choreografie und brauchen auch keine: Ein
       Ort tritt nicht auf, er steht da. Vorher blendeten die beiden Kacheln
       nacheinander ein und die PKV-Kachel bekam obendrein einen Tastendruck —
       zwei Bewegungen für etwas, das gar nichts tut. */

    /* Die Einreichung fliegt zu beiden Gebäuden, zur Beihilfe zuerst. Der
       Versatz von 0,06 ist die Staffelung: darunter wirken beide synchron,
       darüber wie zwei getrennte Vorgänge.

       --ab-y ist der Platz des einzelnen Hauses IM Block: eines darüber, eines
       darunter. Mehr braucht keine der beiden Stellen, weil der Weg selbst
       gerechnet wird. */
    /* Die zweite Pause liegt zwischen Druck-Talsohle (~900–1000 ms) und
       Flugbeginn (0,72, real ~1250 ms): Der Knopf federt aus, das Bild steht
       einen Moment, DANN fliegt die Einreichung — statt noch während der
       Geste loszuhuschen. Die Fenster reichen bis 0,92/0,96 in die langsame
       Endregion: real rund 800 und 950 ms je Sendung (bei data-dauer 3600),
       und vor dem Ruhepunkt bleibt Luft. */
    [data-reise-mode="player"] .reise-flug--beihilfe {
        --flug-ab: 0.72;
        --flug-weg: 0.20;
        --ab-y: calc(-3.1rem * var(--rv));
    }

    [data-reise-mode="player"] .reise-flug--pkv {
        --flug-ab: 0.76;
        --flug-weg: 0.20;
        --ab-y: calc(3.1rem * var(--rv));
    }

    /* ---- Kapitel 5: ein Beat, eine Umdrehung ---- */

    /* Die Zeiger laufen von selbst — siehe die Ambient-Schleifen unten. Eine Uhr,
       die stillsteht, liest man als defekt, und inhaltlich stimmt es auch: Warten
       passiert ohne einen. Nur die Achsen stehen hier, weil sie Geometrie sind
       und keine Bewegung. */
    [data-reise-mode="player"] .reise-uhr-zeiger--minute,
    [data-reise-mode="player"] .reise-uhr-zeiger--stunde {
        transform-box: fill-box;
        transform-origin: 50% 100%;
    }

    /* Die beiden Einreichungen tragen sich nacheinander ein. Mehr passiert in
       diesem Kapitel nicht, und das ist seine Aussage. */
    [data-reise-mode="player"] .reise-warten-zeile {
        --z: clamp(0, calc((var(--sp) - 0.14 - var(--pos-index, 0)) / var(--w-mittel)), 1);
        opacity: var(--z);
        transform: translateY(calc((1 - var(--z)) * var(--weg-klein)));
    }

    [data-reise-mode="player"] .reise-warten-zeile:nth-child(2) { --pos-index: 0.1; }

    /* ---- Kapitel 6: ein Beat ----
     *
     * Ankommen und Zuordnen sind ein Gedanke und deshalb ein Beat. Er läuft in
     * drei Zügen, die ineinandergreifen: Die Abrechnung fliegt vom Gebäude ins
     * Telefon, dort gehen die Positionen auf, und an der Stelle, an der eben
     * noch das Gebäude stand, stehen danach die zugeordneten Belege. */

    /* Der Rückweg: dieselbe Formel wie in Kapitel 4, nur von 1 nach 0.

       --flug-weg 0,54 statt der 0,4-Vorgabe, aus demselben nachgemessenen
       Grund wie beim Hinweg: Das Fenster 0,04–0,44 lag ganz im schnellen Teil
       der Tween-Kurve, und vom 2,6-s-Schritt blieben dem Rückflug real 400 ms
       (Frame-Zeitstempel, 1440 px) — für die Ankunft der Abrechnung, die
       Aussage dieses Kapitels, zu hastig. Bis 0,58 verlängert sind es real
       710 ms. Die Kette dahinter rückt mit: Die Zeilen gehen auf, WO die
       Abrechnung ankommt (0,58), das Gebäude räumt ab der Ankunft das Feld
       (über --w-kurz, damit es vor den Karten weg ist), und die Karten treten
       ab 0,66 an seine Stelle — die letzte schließt exakt am Ruhepunkt. */
    [data-reise-mode="player"] .reise-flug--zurueck {
        --flug-ab: 0.04;
        --flug-weg: 0.54;
        --flug-von: 1;
        --flug-bis: 0;
    }

    /* Das Gebäude räumt das Feld, sobald es geliefert hat: An seiner Stelle
       stehen gleich die Belegkarten. Übrig bleibt deine Liste, nicht die des
       Versicherers. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="6"] .reise-ziele {
        opacity: clamp(0, calc((0.70 - var(--sp)) / var(--w-kurz)), 1);
    }

    /* Die Positionen gehen dort auf, wo die Abrechnung im Telefon ankommt. Der
       Versatz von 0,06 ist die Staffelung; darunter wäre sie mit rund 70 ms
       nicht mehr wahrnehmbar. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="6"] .reise-abrechnung-zeile {
        --z: clamp(0, calc((var(--sp) - 0.58 - var(--pos-index, 0)) / var(--w-mittel)), 1);
        opacity: var(--z);
        transform: translateY(calc((1 - var(--z)) * var(--weg-klein)));
    }

    [data-reise-mode="player"] .reise-abrechnung-zeile[data-pos="1"] { --pos-index: 0; }
    [data-reise-mode="player"] .reise-abrechnung-zeile[data-pos="2"] { --pos-index: 0.06; }

    /* Die Maskier-Tasche der Karten stand hier mit ihrem Fenster und ist
       ersatzlos entfallen (beiger Rand über dem Gerät — siehe den Kommentar
       im Kapitel-6-Grundblock). */

    /* Die Karten treten NUR in Kapitel 6 auf. In Kapitel 7 stehen dieselben
       drei da — im Zustand, in dem Kapitel 6 sie hinterlassen hat, und ohne
       eigene Regel: Der Grundwert IST dieser Zustand. Stünde die Choreografie
       ungebunden hier, führe Kapitel 7 sie ein zweites Mal ab, und der
       Übergang „bleibt" wechselte genau das, was er nicht wechseln soll.

       Sie kommen fertig, mit der Marke, die sie am Ende tragen. Bis August 2026
       kippte die Marke danach noch einmal von „Noch nicht erstattet" auf
       „Erstattet" — ein zweiter, gestaffelter Vorgang nach dem Auftritt, und
       damit genau die Portionierung, die dieses Kapitel loswerden sollte. Der
       Endzustand ist derselbe, und den zeigt jetzt schon der Auftritt.

       DECKKRAFT STEIL, WEG WEICH (Schritt 8): Die Karten
       liegen hochkant auf dem Gerät, und eine Karte, die über ihr ganzes
       Fenster blendet, lässt das Gehäuse durchscheinen. Wie beim Entwurf in
       Kapitel 7 springt die Deckkraft in 0,03 --sp auf (real unter 150 ms),
       der Aufstieg läuft weiter über --w-mittel. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="6"]
        .reise-belegkarte[data-pos="1"] {
        --c: clamp(0, calc((var(--sp) - 0.66) / var(--w-mittel)), 1);
        opacity: clamp(0, calc((var(--sp) - 0.66) / 0.03), 1);
        transform: translateY(calc((1 - var(--c)) * var(--weg-klein)));
    }

    [data-reise-mode="player"] .reise-kapitel[data-kapitel="6"]
        .reise-belegkarte[data-pos="2"] {
        --c: clamp(0, calc((var(--sp) - 0.72) / var(--w-mittel)), 1);
        opacity: clamp(0, calc((var(--sp) - 0.72) / 0.03), 1);
        transform: translateY(calc((1 - var(--c)) * var(--weg-klein)));
    }

    [data-reise-mode="player"] .reise-kapitel[data-kapitel="6"]
        .reise-belegkarte[data-pos="3"] {
        --c: clamp(0, calc((var(--sp) - 0.78) / var(--w-mittel)), 1);
        opacity: clamp(0, calc((var(--sp) - 0.78) / 0.03), 1);
        transform: translateY(calc((1 - var(--c)) * var(--weg-klein)));
    }

    /* ---- Kapitel 7: zwei Beats ---- */

    [data-reise-mode="player"] .reise-abrechnung-zeile--abgelehnt::before {
        transform: scaleX(clamp(0, calc((var(--sp) - 0.04) / var(--w-kurz)), 1));
    }

    [data-reise-mode="player"] .reise-wahl {
        --w: clamp(0, calc((var(--sp) - 0.12) / var(--w-mittel)), 1);
        opacity: var(--w);
        transform: translateY(calc((1 - var(--w)) * var(--weg-klein)));
    }

    /* IN BEAT 2 DIMMT DIE WAHL (Sichtungs-Befund, August 2026): Zwei voll
       aktive Knöpfe unter „Widerspruch versendet." lasen sich, als stünde
       die Entscheidung noch aus — getroffen ist sie seit dem Druck in
       Beat 1. Als ZUSTANDS-Blende und nicht als --sp-Fenster: Ein Fenster,
       das auf 0,45 schließt, ließe die Deckkraft am Ruhepunkt zwischen 0
       und 1 stehen, und genau das verbietet die Ruhepunkt-Regel
       (scripts/reise_ruhebilder.py). Der Beat-Wechsel ist ein Zustand, die
       Blende gehört dem Blatt. Die transition steht NUR in diesem Block:
       Im --sp-Block darüber liefe sie dem Tween hinterher. Rückwärts
       (Beat 1) fällt die Regel weg und die Fensterformel übernimmt wieder.
       Hochkant deckt dieselbe Regel den Rückweg nach dem Abflug des
       Entwurfs: gedimmt zurück statt voll aktiv. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="7"][data-active-beat="2"] .reise-wahl {
        opacity: 0.45;
        transition: opacity 300ms linear;
    }

    /* Tiefer als die 5-Prozent-Vorgabe (0,18 wie die Tasten in Kapitel 2 und
       3): Man soll SEHEN, dass hier gedrückt wird — mit der Vorgabetiefe war
       die Geste nicht zu erkennen. Gilt für beide Tasten des
       Kapitels, der Ring im Knopf erbt --druck ohnehin. */
    [data-reise-mode="player"] .reise-taste--widerspruch {
        --druck-ab: 0.26;
        --druck-tiefe: 0.18;
    }

    /* Der Entwurf tritt neben dem Gerät auf, sobald „Widerspruch" gedrückt
       ist, mit einem kleinen Weg von unten. Das Fenster liegt VOR dem
       Ruhepunkt bei 0,5, dem Ruhebild von Schritt 9: Dort steht er ganz.

       Und er geht mit dem Abschicken: --e-aus blendet das Blatt in DENSELBEN
       Frames aus, in denen der Brief abhebt (Taubenfenster ab 0,82, unten) —
       das Blatt WIRD der Brief. Vorher schloss es erst bei 0,97: Der Brief
       flog quer über den eigenen, noch stehenden Entwurfstext. Ein Schreiben,
       das wegfliegt UND liegen bleibt, wäre zweimal dasselbe Schreiben. Das
       Ruhebild von Schritt 10 ist das Gerät mit der Erfolgsmeldung. Beide
       Fenster auf einer Eigenschaft über min(): An den Ruhepunkten liefern
       sie 1 und 1 (Schritt 9) beziehungsweise 1 und 0 (Schritt 10). */
    /* DIE BOX IST VON ANFANG AN DECKEND (Schritt 9, mobil): Solange die Deckkraft über das ganze Auftritts-Fenster lief,
       schien das Handy rund 600 ms lang durch den Blatthintergrund. Der
       Auftritt bleibt der Aufstieg (--e, transform über --w-mittel), die
       Deckkraft springt in einem eigenen, steilen Fenster von 0,02 --sp auf —
       real unter 100 ms (data-dauer 3000, langsame Kurvenhälfte). */
    [data-reise-mode="player"] .reise-entwurf {
        --e: clamp(0, calc((var(--sp) - 0.34) / var(--w-mittel)), 1);
        --e-an: clamp(0, calc((var(--sp) - 0.34) / 0.02), 1);
        --e-aus: clamp(0, calc((0.93 - var(--sp)) / var(--w-mittel)), 1);
        opacity: min(var(--e-an), var(--e-aus));
        transform: translateY(calc((1 - var(--e)) * 12%));
    }

    /* Der Text schreibt sich Wort für Wort — nach eigener Uhr (siehe unten bei
       den Schleifen). Der Scroll sagt nur, dass der Entwurf steht: Das ist der
       Endzustand, den diese Formel liefert und der beim Zurückkommen gilt.

       0,40 und nicht 0,44: Mit --w-kurz 0,06 endete das Fenster genau auf dem
       Ruhepunkt 0,5, und ein Fenster, dessen Rand auf einem Ruhepunkt liegt,
       ist eine Rundung vom Geisterrest entfernt. */
    [data-reise-mode="player"] .reise-entwurf-wort {
        opacity: clamp(0, calc((var(--sp) - 0.40) / var(--w-kurz)), 1);
    }

    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(1)  { --wort-index: 0; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(2)  { --wort-index: 0.4; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(3)  { --wort-index: 0.8; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(4)  { --wort-index: 1.2; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(5)  { --wort-index: 1.6; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(6)  { --wort-index: 2.0; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(7)  { --wort-index: 2.4; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(8)  { --wort-index: 2.8; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(9)  { --wort-index: 3.2; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(10) { --wort-index: 3.6; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(11) { --wort-index: 4.0; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(12) { --wort-index: 4.4; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(13) { --wort-index: 4.8; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(14) { --wort-index: 5.2; }
    [data-reise-mode="player"] .reise-entwurf-wort:nth-child(15) { --wort-index: 5.6; }

    /* Über scaleY statt opacity: Das Blinken unten läuft über opacity, und eine
       Animation schlägt jede normale Deklaration derselben Eigenschaft. */
    [data-reise-mode="player"] .reise-cursor {
        transform: scaleY(clamp(0, calc((var(--sp) - 0.68) / var(--w-kurz)), 1));
    }

    [data-reise-mode="player"] .reise-taste--senden {
        --druck-ab: 0.80;
        --druck-tiefe: 0.18;
    }

    /* DER SCHLUSSFLUG LIEST SICH ALS ADRESSE (FEATURE-0143). Vorher flog
       der Brief nach oben RECHTS — quer durch den Text des eigenen Entwurfs,
       auf das Gerät zu, und verlosch nach rund 80 px in der Luft. Der
       Widerspruch geht aber an den Kostenträger, und der stand in Kapitel 6
       LINKS. Also: nach oben links aus dem Bild, dieselbe Seite, von der die
       Abrechnung kam.

       Das Fenster beginnt mit dem Tastendruck (0,80 plus Anlauf) und ist mit
       1,4 × --w-mittel breiter als ein normaler Auftritt: Es liegt damit in
       der LANGSAMEN Hälfte der Ease-out-Kurve — real gut eine Sekunde statt
       der rund 300 ms, die ein Fenster gleicher Breite am Schrittanfang
       bekäme (bekannte Falle: dort läuft es drei- bis viermal schneller als
       gedacht). Es schließt bei 0,974, vor dem Ruhepunkt 1.

       Und der ENTWURF GEHT MIT DEM ABFLUG (--e-aus unten): Das Blatt wird
       zum Brief, statt liegen zu bleiben, während sein eigener Inhalt
       davonfliegt — deshalb kreuzt der Flug auch keinen stehenden Text mehr,
       der Text darunter blendet in denselben Frames aus. */
    /* DER BRIEF FLIEGT HINAUS, NICHT INS NICHTS (Sichtungs-Befund, August
       2026). Vorher: −120 %/−400 % Weg mit Impuls-Deckkraft (voll nur in der
       Flugmitte) und Schrumpfung auf 0,6 — auf dem Desktop verlosch ein
       ~15-px-Kuvert nach kurzem Weg in der Luft, hochkant stand es genau auf
       der roten Zeile „Ziffer 2197 abgelehnt". Jetzt: schnell auf, sichtbar
       fast den ganzen Weg (Plateau wie beim Sendungs-Flug), erst am Schluss
       aus — und der Weg ist lang genug, dass der Brief auf beiden Breiten
       links aus der Bühne ist, bevor die Blende greift. Hochkant verlässt er
       die Bühne seitlich, BEVOR er die Höhe der Liste erreicht — er kreuzt
       damit keinen Text mehr. Die Schrumpfung ist auf 0,75 begrenzt, das
       Kuvert bleibt überall über 24 px.

       Ein Fenster, das schließt, muss auf null schließen: Bei --fl 1 steht
       die Deckkraft auf 0, das Ruhebild von Schritt 10 bleibt taubenfrei. */
    [data-reise-mode="player"] .reise-brieftaube {
        --fl: clamp(0, calc((var(--sp) - 0.82) / (var(--w-mittel) * 1.4)), 1);
        opacity: clamp(0, min(calc(var(--fl) / 0.12),
                              calc((1 - var(--fl)) / 0.08)), 1);
        /* Ohne Gerätelage: Der Start ist der Absende-Knopf des frei stehenden
           Entwurfs, und der ist ein fester Punkt der Kunstfläche (--ziel-Anker
           in der Ruhelage oben). Hochkant liegt der Entwurf auf dem Gerät und
           der Brief hebt an dessen Absende-Knopf ab. */
        transform:
            translate(calc(var(--fl) * -460%), calc(var(--fl) * -820%))
            rotate(calc(var(--fl) * -14deg))
            scale(calc(1 - var(--fl) * 0.25));
    }

    /* Die Erfolgsmeldung geht auf dem Bildschirm auf, während die Taube
       fliegt: Erst der Abflug (0,86), dann die Bestätigung — beide zusammen
       sind das Ruhebild von Schritt 10. Das Fenster endet vor dem Ruhepunkt 1,
       der Haken setzt sich mit der überall gleichen --k-Formel. */
    [data-reise-mode="player"] .reise-erfolg {
        --z: clamp(0, calc((var(--sp) - 0.88) / var(--w-kurz)), 1);
        opacity: var(--z);
        transform: translateY(calc((1 - var(--z)) * var(--weg-klein)));
    }

    [data-reise-mode="player"] .reise-erfolg .reise-haken::after {
        --haken-ab: 0.90;
    }

    /* ---- Ambient-Schleifen ----------------------------------------------
     * Alles bisher Genannte hängt am Scroll. Diese drei Bewegungen tun das
     * bewusst nicht, weil sie keinen Erzählschritt tragen, sondern zeigen, dass
     * etwas in Arbeit ist. Sie laufen als Schleife und nur, solange ihr Kapitel
     * das aktive ist.
     *
     * Neue zeitbasierte Animationen gehören hierher oder nirgendwohin: Ein
     * Erzählschritt, der nach eigener Uhr läuft, entkoppelt das Bild von der
     * Hand des Nutzers. Genau daran ist diese Sektion einmal gescheitert
     * (siehe §9 in .claude/rules/frontend-design.md).
     */

    /* Die Scan-Schleife von Kapitel 1 stand hier und ist ersatzlos
       entfallen: Der Scan ist ein Erzählschritt (EINMAL komplett bis unten)
       und hängt an --sp —
       siehe .reise-scanlinie in der Kapitel-1-Choreografie. Als Schleife kam
       er nie unten an, weil das Fenster des Rahmens vor dem ersten Durchlauf
       schloss. */

    /* Ein Fingertipp ist eine Geste, kein Fortschritt: Der Ring wächst und
       verblasst nach eigener Uhr, solange der Scroll sagt, dass getippt wird.
       Nur im aktiven Kapitel, damit nicht sechs Ringe unsichtbar mitlaufen. */
    [data-reise-mode="player"] .reise-kapitel[data-state="active"] .reise-tipp::after {
        animation: reise-tipp-puls 900ms ease-out infinite;
    }

    /* Der Widerspruch schreibt sich einmal, ohne dass man ihn scrollen muss.
       Ein Text, der Wort für Wort erscheint, ist ein Zustand — dass er sich
       aufbaut, ist Darstellung. Das letzte Wort steht nach 880 ms; scrollt man
       vorher weiter, übernimmt die --sp-Formel oben denselben Endzustand. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="7"][data-active-beat="1"]
        .reise-entwurf-wort {
        animation: reise-wort-ein 240ms ease-out both;
        animation-delay: calc(var(--wort-index, 0) * 115ms);
    }

    /* ---- Die Welle in Schritt 4 ------------------------------------------
     * Eine durchlaufende Choreografie von einer Sekunde: markieren, benennen,
     * abhaken. Drei Takte, die leicht ineinandergreifen, und innerhalb jedes Takts
     * läuft ein Element nach dem anderen mit 60 ms Versatz an.
     *
     * Warum hier Zeit und nicht --sp: Ein Scroll-Versatz kann keine Welle
     * erzeugen. Wahrnehmbar wird eine Staffelung ab etwa 80 ms Abstand, das sind
     * bei normaler Scrollgeschwindigkeit 80 bis 150 px und in diesem Kapitel rund
     * 0,12 --sp — genau die sequenziellen Schwellen, die es vorher waren und die
     * einen Gedanken in elf Portionen zerlegten. Kleiner Versatz ist unsichtbar,
     * großer ist Nachschieben; dazwischen liegt nichts.
     *
     * AUSGELÖST wird die Welle vom Scroll: Sie hängt an [data-active-beat="1"].
     * Der Uhr gehört nur die Verteilung innerhalb der Sekunde. Wer weiterscrollt,
     * überholt sie und sieht den Endzustand, denn in Beat 2 greifen diese
     * Selektoren nicht mehr und die --sp-Formeln oben übernehmen. An der
     * Beat-Grenze liefern beide denselben Wert, es springt also nichts. */

    /* Takt eins, ab 0 ms: die Felder werden markiert. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="2"][data-active-beat="1"]
        .reise-beleg--erkannt [data-feld]::after {
        animation: reise-welle-strich 320ms linear
            calc(var(--welle-i, 0) * 60ms) both;
    }

    /* Die Belegnummer trägt keine Markierung und bekommt deshalb auch keine
       Welle — sonst zöge sie eine Linie, die es nicht geben soll. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="2"][data-active-beat="1"]
        .reise-beleg--erkannt [data-feld="nummer"]::after {
        animation: none;
    }

    /* Takt zwei, ab 260 ms: sie bekommen einen Namen. Setzt ein, während der letzte
       Strich noch läuft — die Takte sollen greifen, nicht abwarten. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="2"][data-active-beat="1"]
        .reise-fahne {
        animation: reise-welle-fahne 320ms linear
            calc(260ms + var(--welle-i, 0) * 60ms) both;
    }

    /* Takt drei, ab 560 ms: alle abgehakt. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="2"][data-active-beat="1"]
        .reise-fahne-haken {
        animation: reise-welle-haken 260ms linear
            calc(560ms + var(--welle-i, 0) * 60ms) both;
    }

    /* Der Platz in der Welle. Steht an den Elementen, weil Markierung, Schild und
       Haken desselben Feldes denselben Platz haben — der Haken erbt ihn. */
    [data-reise-mode="player"] .reise-beleg--erkannt [data-feld="datum"],
    [data-reise-mode="player"] .reise-fahne--datum { --welle-i: 1; }

    [data-reise-mode="player"] .reise-beleg--erkannt [data-feld="betrag"],
    [data-reise-mode="player"] .reise-fahne--betrag { --welle-i: 2; }

    [data-reise-mode="player"] .reise-fahne--position { --welle-i: 3; }

    /* Warten läuft von selbst — Zeiger und Puls brauchen keine Hand. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="5"][data-state="active"]
        .reise-uhr-zeiger--minute {
        animation: reise-uhr-minute-loop 2.8s linear infinite;
    }

    [data-reise-mode="player"] .reise-kapitel[data-kapitel="5"][data-state="active"]
        .reise-uhr-zeiger--stunde {
        animation: reise-uhr-minute-loop 33.6s linear infinite;
    }

    [data-reise-mode="player"] .reise-kapitel[data-kapitel="5"][data-state="active"]
        .reise-uhr-welle {
        animation: reise-uhr-puls 1.8s ease-out infinite;
    }

    [data-reise-mode="player"] .reise-kapitel[data-kapitel="5"][data-state="active"]
        .reise-uhr-welle--2 {
        animation-delay: 900ms;
    }

    /* Ein Schreibcursor blinkt. Sichtbar wird er über scaleY aus --sp, das
       Blinken läuft über opacity — deshalb kommen sich beide nicht in die
       Quere. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="7"][data-state="active"]
        .reise-cursor {
        animation: reise-blinken 1.06s steps(2, jump-none) infinite;
    }

    /* Außerhalb des Entwurfs-Beats ist der Cursor still und unsichtbar. */
    .reise-cursor {
        transform: scaleY(0);
    }
}

@keyframes reise-wort-ein {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Der Ring läuft aus dem Fingerkuppen-Durchmesser nach außen und verblasst. Die
   Pause am Ende trennt die Wiederholungen, sonst wirkt es wie ein Kreisel — sie
   bleibt kurz, weil man mitten hineinscrollt und sonst auf den ersten Ring
   wartet. */
@keyframes reise-tipp-puls {
    0% { opacity: 1; transform: scale(0.3); }
    85% { opacity: 0; transform: scale(1.25); }
    100% { opacity: 0; transform: scale(1.25); }
}

/* Die drei Wellen aus Schritt 4. Sie enden auf demselben Wert, den die
   scrollgebundene Formel an dieser Stelle liefert — deshalb springt beim Wechsel
   zu Beat 2 nichts. */
@keyframes reise-welle-strich {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
}

@keyframes reise-welle-fahne {
    from { opacity: 0; transform: translateX(var(--fahne-von)); }
    to { opacity: 1; transform: translateX(0); }
}

@keyframes reise-welle-haken {
    from { transform: scale(0); }
    to { transform: scale(1); }
}

/* Eine Umdrehung. Der Stundenzeiger nutzt sie mit zwölffacher Dauer. */
@keyframes reise-uhr-minute-loop {
    from { transform: rotate(0); }
    to { transform: rotate(360deg); }
}

@keyframes reise-uhr-puls {
    from { opacity: 0.45; transform: scale(1); }
    to { opacity: 0; transform: scale(1.75); }
}

@keyframes reise-blinken {
    50% { opacity: 0; }
}

/* ==========================================================================
   Größenstufen

   Gleiche sieben Kapitel auf allen Geräten — keine gekürzte Fassung. Was sich
   ändert, sind Maßstab und Anordnung.
   ========================================================================== */

@media (max-width: 991.98px) {
    .reise {
        --rv: 0.92;
        /* Der Anker rückt mit: schmalere Kunstfläche, weniger Versatz aus der
           Mitte. Die sechs Lagezahlen bleiben unverändert — sie rechnen in
           Anteilen dieser Fläche, nicht in Pixeln.

           --reise-kunst-mitte-x steht hier NICHT mehr: Die Formel im Grundblock
           liest die beiden Zeilen darunter und rückt von selbst mit. Hier stand
           −23 %, geraten wie die −24 % darüber. */
        --reise-kunst-breite: min(28rem, 50vw);
        /* 34vw → 36vw und 21 → 22 rem: Auf 768 px war die Spalte 261 px breit,
           für rund 21 Wörter Beschriftung die engste Stelle der Sektion. */
        --reise-text-breite: min(22rem, 36vw);
        --reise-text-abstand: 1.5rem;
    }

    .reise-kapitel {
        grid-template-columns: minmax(0, 1fr);
        gap: 2rem;
        margin: 4rem auto;
    }

    .reise-captions {
        max-width: none;
        margin: 0 auto;
        text-align: center;
    }

    /* Kein Spur-Sonderfall mehr: Ein 0,6-rem-Punkt passt in jede der elf
       Spalten, auch wenn sie auf 320 px auf rund 27 px komprimieren — die
       Ziffernringe, die hier auf 1,5 rem schrumpfen mussten, gibt es nicht
       mehr. */
}

@media (max-width: 767.98px) {
    /* ---- Kein Einrasten mehr auf die Sektion.

       Kein scroll-snap-type: y proximity am <html> und kein
       scroll-snap-align an section.reise: Auch proximity zieht spürbar an, und
       beim Durchscrollen der Startseite am Handy fühlt sich das nicht wie
       Scrollen an. Die Kein-Einrasten-Regel aus §9 frontend-design.md gilt
       ohne Ausnahme für die senkrechte Achse.

       Wer das wiederhaben will, braucht mehr als die zwei Deklarationen: Der
       Grund, sie zu entfernen, war das Scrollgefühl, nicht ihre Technik. */

    .reise {
        /* Deutlich größer als zuvor: auf 390 px war vorher nichts zu erkennen. */
        --rv: 0.82;
        /* Kein Nebeneinander mehr: Die Kunstfläche steht mittig und oben, die
           Beschriftung darunter. Sie ist hier hochkant (3:4), deshalb ist die
           halbe Höhe zwei Drittel der Breite statt drei Achteln. */
        --reise-kunst-breite: min(16rem, 66vw);
        --reise-kunst-halbhoch: calc(var(--reise-kunst-breite) * 0.6667);
        --reise-kunst-mitte-x: 0%;
        /* Bündig an der Bühnenoberkante: Die Mitte liegt eine halbe Kunsthöhe
           tiefer, also beginnt die Fläche bei null. Vorher standen hier 34 %
           der Bühnenhöhe — eine Zahl, die von der Bühne abhing, und je nach
           Fenster ragte die Fläche oben heraus oder ließ Luft, die unten dem
           Text fehlte. */
        --reise-kunst-mitte-y: var(--reise-kunst-halbhoch);
        --reise-text-breite: min(21rem, 88vw);

        /* ---- Die Höhe der Bühne rechnet mit, statt zu raten ----
           Hochkant steht die Beschriftung IN der Bühne unter der Kunstfläche.
           Die Bühne muss deshalb beides tragen; tut sie es nicht, deckt ein
           Requisit den Text zu — auf 390 px war das in zehn der zwölf
           Ruhebilder der Fall.

           Sie hing an svh (57 %) und damit an einer Größe, die mit dem Inhalt
           nichts zu tun hat: Auf 390 × 844 waren das 481 px für 341 px Kunst
           plus 209 px längste Beschriftung — 69 px zu wenig, und auf einem
           flacheren Fenster mehr. Jetzt ist sie die Summe ihrer Teile.

           --reise-text-hoehe deckt die längste der zwölf Beschriftungen, den
           Abstand darüber und das, was Requisiten unter die Kunstfläche ragen.
           Wer eine Beschriftung deutlich länger schreibt, prüft diese Zahl nach.

           NACHGEMESSEN NACH DEM SCHRIFTWECHSEL (320 px, alle zwölf
           Beschriftungen durchgeklickt): die längste steht bei 203 px statt bei
           209 — Kapitel 1, beide Beats. Viel weniger ist es nicht geworden, und
           zwar aus einem Grund, den man vorher hätte sehen können: Hochkant lag
           die alte Überschrift mit clamp(1,35rem, 2,4vw, 1,85rem) längst an
           ihrer UNTEREN Schranke, 2,4 vw sind auf 320 px nur 7,7 px. Der
           Wechsel auf 1,25 rem spart dort 1,6 px je Zeile.

           203 + 3 rem Abstand darüber = 251 px Bedarf. 16,25 rem sind 260 und
           lassen 9 px Luft; die 17 rem waren 21 px zu großzügig. */
        --reise-text-hoehe: 16.25rem;
        --reise-stage-h: calc(var(--reise-kunst-halbhoch) * 2
                              + var(--reise-text-hoehe));
        --reise-text-abstand: 3rem;
    }

    section.reise {
        padding-bottom: 2rem;
    }

    section.reise > .container:first-child {
        padding-top: 2rem;
    }


    /* Hochkant stehen die Pfeile am äußersten Rand und überlappen die Bühne —
       auf 320 px liegt die Kunstfläche fast an der Containerkante, daneben ist
       kein Platz. Die Milk-Scheibe hält sie über jeder Szene lesbar; dass sie
       Requisiten streifen dürfen, aber keinen Text der Szenen, ist auf 390 und
       320 px nachgesehen (Kontaktbogen). */
    .reise-pfeil--zurueck { left: 0; }
    .reise-pfeil--weiter { right: 0; }

    /* Hochkant reicht das untere Band der Bühne für den Abschluss-Knopf nicht:
       Die Beschriftung des letzten Schritts endete 36 px über der Bühnenkante
       (390 px), der Knopf braucht 56. Der Rahmen reserviert deshalb 2,5 rem
       unter der Bühne — in JEDEM Schritt, damit beim Wechsel nichts springt —,
       und der Knopf darf zusätzlich 16 px in die Bühne hineinragen: gemessen
       bleiben so 20 px (390) bzw. 17 px (320) Luft zur Beschriftung. Netto
       spart der Umbau hochkant trotzdem rund 30 px gegenüber der alten
       Steuerungszeile. */
    .reise-buehnenrahmen {
        padding-bottom: 2.5rem;
    }

    .reise-abschluss-halter {
        bottom: 0;
    }

    /* Der Abschluss-Knopf mit 2 rem seitlichem Polster fraß auf 320 px zu viel
       der Zeile; auf 1,25 rem passt „Kostenlos starten" einzeilig. Die
       Trefferfläche bleibt unberührt: Sie hängt an der Höhe, und die steht in
       cappuccino.css. */
    .reise-abschluss-halter .btn {
        padding-inline: 1.25rem;
    }

    .reise-art {
        aspect-ratio: 3 / 4;
    }

    /* Nur die statische Fassung liest diesen Abstand — im Player ist das
       Kapitel ein Block und kennt kein Raster. Dort stehen Kunstfläche und
       Beschriftung untereinander, und mehrere Requisiten ragen bewusst unter
       ihre Fläche hinaus: auf 320 px bis zu 64 px (das Telefon ist dort höher
       als die Kunstfläche), auf 390 px 47 px (die Belegkarten). Mit 2 rem
       Abstand lag das im Vorspann der Beschriftung. */
    .reise-kapitel {
        gap: 5rem;
    }

    /* ---- Hochkant ist das Gerät kleiner: --lage-s 0,85 in ALLEN Kapiteln ----
       Leitregel: Die Screens dürfen sich zwischen
       Desktop und Mobil unterscheiden, wenn es sonst nicht passt — nichts darf
       verdeckt werden, die Abstände müssen harmonisch sein. In voller Größe
       füllte das Gerät (328 px) die Kunstfläche (341 px auf 390 px) fast
       vollständig; jede Beigabe — Gebäude, Uhr, Schilder — lag damit zwangsläufig
       AUF dem Telefon oder im Vorspann der Beschriftung. Mit 0,85 bleiben rund
       50 px Luft, und die Beigaben bekommen einen eigenen Platz.

       EINE Zahl für alle sieben Kapitel, nicht je Kapitel: Das Tween-Werk trägt
       Größenwechsel zwar, aber ein Telefon, das zwischen zwei Schritten atmet,
       wäre eine zweite Aussage ohne Auskunft. Die Abfrage unter 373 px brauchte
       denselben Wert schon vorher (dort ist das Gerät sonst höher als die
       Fläche); sie erbt ihn jetzt von hier.

       [data-kapitel] wegen der Stufe: Die sieben Lagenzeilen im Grundblock
       wiegen 0,2,0 — eine nackte .reise-kapitel-Zeile verlöre gegen jede. */
    .reise-kapitel[data-kapitel] {
        --lage-s: 0.85;
    }

    /* ---- Grundregel der Lagen hochkant ----
       Das Handy steht ZENTRIERT, wenn keine anderen Requisiten neben ihm
       stehen. Nur wo etwas dazukommt, weicht es zur Seite — und dann mit
       harmonischen Abständen:
         1: rechts (der Briefstapel liegt links daneben)
         2: mittig (die Schilder rücken unter das Gerät, siehe unten)
         3: rechts (die Zahlkarte liegt links daneben)
         4: mittig (die Gebäude stehen als Zeile darunter)
         5: rechts (die Uhr steht links dahinter, siehe unten)
         6 und 7: mittig (Kostenträger darunter, Entwurf auf dem Gerät) —
              beide gleich, das ist der Übergang „bleibt". */
    .reise-kapitel[data-kapitel="4"] {
        --lage-x: 0;
        --lage-y: 0;
    }

    .reise-kapitel[data-kapitel="5"] {
        --lage-x: 1;
        --lage-y: 0;
    }

    /* Auf schmalen Flächen rücken die seitlichen Requisiten unter das Telefon. */
    .reise-screen--links,
    .reise-screen--banking {
        left: 50%;
        right: auto;
        top: 20%;
        margin: 0 0 0 calc(-6.75rem * var(--rv));
    }

    /* Zwei Stufen, weil `.reise-art--zahlung .reise-screen--banking` weiter oben
       ebenfalls zwei wiegt und mit top: 58 % dagegenstand — die Zeile darüber
       hat für das Banking-Telefon nie gegriffen. In der statischen Fassung hing
       es dadurch 150 px unter seiner Kunstfläche und deckte die Beschriftung
       von Kapitel 3 zu; im Player fällt es nicht auf, weil dort vier Stufen die
       Lage bestimmen. */
    .reise-art--zahlung .reise-screen--banking {
        top: 20%;
    }

    /* Nur die statische Fassung liest das: Im Player setzt
       `[data-reise-mode="player"] .reise-kapitel .reise-art .reise-screen`
       right auf auto und wiegt vier Stufen.

       8,5 rem standen hier, und das sind auf 390 px 111 px NEBEN der
       Kunstfläche — bis zu deren Rand sind es aber nur 36 px. Das Gerät hing
       zu zwei Dritteln draußen. Es rückt jetzt an die Kante der Fläche: Über
       dem Blatt gehalten IST das Bild dieses Kapitels, nur eben nicht drei
       Handbreit daneben. */
    .reise-screen--haltend {
        left: auto;
        right: calc(-1rem * var(--rv));
        top: 50%;
        margin: calc(0rem - var(--reise-geraet-halbhoehe)) 0 0 0;
    }

    /* Etwas links der Mitte statt mittig: Das haltende Telefon steht auf
       schmalen Flächen weit im Bild, und der Scanbereich ist hier fast so breit
       wie die Bühne. Die Requisiten rücken gemeinsam, damit das Blatt
       weiterhin aus dem Umschlag kommt und denselben Weg ins Gerät nimmt. */
    .reise-stapel,
    .reise-beleg--reise,
    .reise-beleg--vorn,
    .reise-scanrahmen {
        left: 40%;
    }

    /* DER SUCHER RAHMT DAS PAPIER, NICHT DIE BÜHNE (Sichtungs-Befund, August
       2026): Mit den Quermaßen (21,5 rem) standen die Klammern hochkant an
       den Ecken der ganzen Bühne — auch um das Telefon herum, das damit in
       seinem eigenen Sucher stand. Auf Papiermaß plus Rand sitzen sie um das
       Blatt; die rechten Klammern liegen unter dem haltenden Bildschirm (der
       steht eine Ebene höher) und stören nicht. Die Laufschiene der
       Scanlinie rechnet mit der Rahmenhöhe.

       DIE MARKER UMSCHLIESSEN DAS BLATT GROSSZÜGIG (Schritt 2, mobil): Mit 18 × 13 rem war der Rahmen SCHMALER als das
       Blatt (19 rem breit, gemessen rund 249 × 161 px auf 390) — das Papier
       ragte je Seite rund 7 px über die Ecken hinaus. Jetzt 21,5 × 15 rem,
       zentriert auf dem Blatt: rund 1,25 rem Luft je Seite, wie auf dem
       Desktop. Die Ränder sind nachgemessen, nicht geraten. */
    .reise-scanrahmen {
        width: calc(21.5rem * var(--rv));
        height: calc(15rem * var(--rv));
        margin: calc(-7.5rem * var(--rv)) 0 0 calc(-10.75rem * var(--rv));
        --scan-strecke: calc(14.9rem * var(--rv));
    }

    /* KÜRZERE ZEILEN AUF DEM PAPIER, NUR IN BEAT 2 (Sichtungs-Befund, August
       2026): Das haltende Telefon deckt hochkant gut die halbe Blattbreite,
       und Faktor- und Betragsspalte wurden an seiner Kante hart geschnitten
       — „Zahnarztpraxis a" ohne Ellipse. Sobald das Gerät über dem Blatt
       steht (Beat 2), fallen die Spalten unter dem Gerät weg (die
       vollständige Fassung zeigt gleich der Bildschirm), Praxisname und
       Leistungen enden mit Ellipse vor der Gerätekante. NICHT in Beat 1:
       Dort steht das Blatt frei, und ein Blatt mit leerer rechter Hälfte
       läse sich als Fehler. Der Wechsel fällt mit dem Beat-Wechsel
       zusammen, in dem das Telefon hereinblendet. */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="1"][data-active-beat="2"]
        .reise-beleg--vorn .reise-beleg-zeile {
        grid-template-columns: auto minmax(0, 1fr);
    }

    [data-reise-mode="player"] .reise-kapitel[data-kapitel="1"][data-active-beat="2"]
        .reise-beleg--vorn .reise-beleg-zeile > u,
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="1"][data-active-beat="2"]
        .reise-beleg--vorn .reise-beleg-zeile > em,
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="1"][data-active-beat="2"]
        .reise-beleg--vorn .reise-beleg-summe strong {
        display: none;
    }

    [data-reise-mode="player"] .reise-kapitel[data-kapitel="1"][data-active-beat="2"]
        .reise-beleg--vorn .reise-beleg-zeile > b {
        max-width: calc(4.4rem * var(--rv));
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }

    [data-reise-mode="player"] .reise-kapitel[data-kapitel="1"][data-active-beat="2"]
        .reise-beleg--vorn .reise-beleg-praxis {
        max-width: calc(6.6rem * var(--rv));
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }

    /* Und der Weg des Belegs ins Gerät rechnet gegen dieselben 40 %. */
    .reise-beleg--vorn {
        --vorn-x: calc(var(--reise-kunst-breite) * 0.10
                       + var(--lage-x, 1) * var(--tel-spanne-x));
    }

    /* Die 40 % rechnen im Player gegen eine Mitte, die das transform gleich
       wieder um die halbe Blattbreite zurücknimmt. Die statische Fassung hat
       dieses transform nicht: Dort ist es ein reiner Versatz nach rechts, und
       das Blatt ist mit 249 px breiter als die halbe Kunstfläche — es stand
       57 px außerhalb des Fensters. Ohne Versatz liegt es mittig unter dem
       Gerät, und das ist das Bild dieses Kapitels. */
    [data-reise-player]:not([data-reise-mode="player"]) .reise-beleg--reise {
        left: 0;
    }

    .reise-empfehlung {
        left: 50%;
        right: auto;
        top: auto;
        bottom: 0;
        width: calc(17rem * var(--rv));
        margin-left: calc(-8.5rem * var(--rv));
    }

    /* ---- Kapitel 2: die Schilder rücken UNTER das Gerät (zwei mal zwei) ----
       Neben dem zentrierten Telefon ist hochkant kein Platz: An den Kanten der
       Kunstfläche verdeckten die vier Schilder genau die Werte, die sie
       benennen — „Alle Positionen" lag quer über der Betragsspalte. Unter dem
       Gerät sind sie eine Legende in zwei Zeilen (zulässig sind „kleiner,
       versetzt, oder unter dem Gerät"). Die Spalten
       hängen an der Mittelachse — linke Spalte endet an ihr, rechte beginnt —,
       die Zeilen an der Unterkante des Geräts, wie die Chip-Zeile der
       Kostenträger. In Beat 2 sind die Schilder weg, dann gehört derselbe
       Platz der Empfehlung darüber. */
    .reise-fahne {
        gap: calc(0.3rem * var(--rv));
        padding: calc(0.26rem * var(--rv)) calc(0.55rem * var(--rv));
        font-size: calc(0.68rem * var(--rv));
    }

    .reise-fahne-kreis {
        width: calc(0.9rem * var(--rv));
        height: calc(0.9rem * var(--rv));
    }

    .reise-fahne--aussteller,
    .reise-fahne--betrag {
        left: auto;
        right: calc(50% + 0.25rem);
    }

    .reise-fahne--datum,
    .reise-fahne--position {
        left: calc(50% + 0.25rem);
        right: auto;
    }

    /* Zeilenabstand NACHGEMESSEN (Schritt 3, mobil):
       Eine Fahne ist rund 25 px hoch (1,9 rem mit Rand), und genau 1,9 rem
       lagen zwischen den Zeilenoberkanten — die Rahmen der beiden Zeilen
       stießen aneinander. 2,4 rem Differenz lassen rund 6,5 px Luft zwischen
       den Borders; die erste Zeile rückt dafür ein Zehntel höher, damit die
       zweite auf 320 px nicht in die Caption-Überschrift läuft (dort liegen
       nur rund 9 px zwischen Legende und Text). */
    .reise-fahne--aussteller,
    .reise-fahne--datum {
        top: calc(50% + var(--reise-geraet-halbhoehe) * 0.85 + 0.3rem * var(--rv));
    }

    .reise-fahne--betrag,
    .reise-fahne--position {
        top: calc(50% + var(--reise-geraet-halbhoehe) * 0.85 + 2.7rem * var(--rv));
    }

    /* ---- Kapitel 5: die Uhr steht LINKS NEBEN dem Gerät, kleiner ----
       Hinter dem zentrierten Telefon war sie zu, bis auf einen Bogen links —
       „komplett verdeckt". Deshalb: Gerät rechts (Lage 1), die Uhr
       kleiner und links davon, Zifferblatt mit Nabe und beiden Zeigern
       sichtbar. Ihr rechter Rand läuft hinter das Gerät — das liest sich als
       Tiefe, nicht als Loch, seit der Bildschirm dieses Kapitels seinen
       Gehäuserand selbst trägt (Randregel im Kapitel-5-Block). */
    .reise-uhr {
        left: -4%;
        width: calc(11rem * var(--rv));
        height: calc(11rem * var(--rv));
        margin-top: calc(-5.5rem * var(--rv));
    }

    /* Hochkant ist rechts vom Telefon kein Platz: Die Kunstfläche ist 16 rem
       breit und das Gerät 13,5. Die Gebäude rücken deshalb unter das Telefon
       und nebeneinander. Geändert werden dafür genau die zwei Zahlen, die auch
       der Flug liest — er landet damit ohne eigene Regel an derselben Stelle.

       DER ANKER RECHNET GEGEN DIE UNTERKANTE DES GERÄTS, nicht gegen die
       Kunstfläche: Das zentrierte Gerät (Maßstab 0,85) endet bei halber
       Gerätehöhe mal 0,85 unter der Mitte, darunter kommen 2,2 rem Luft und
       dann die Chip-Zeile. Vorher rechnete der Anker gegen die Kunstfläche und
       das Gerät stieß mit −0,04 an deren Oberkante — die 2,6 rem „Abstand"
       wurden dabei vollständig von der Differenz aufgefressen: gemessen 0,6 px
       Luft zwischen Gerät und Gebäuden, und die Beschriftung „PKV" stand auf
       der Überschrift der Caption. */
    .reise {
        --ziel-x: 0px;
        --ziel-y: calc(var(--reise-geraet-halbhoehe) * 0.85 + 2.2rem * var(--rv));
    }

    /* Kapitel 6 und 7 spiegeln --ziel-x quer nach links; hochkant gilt wieder
       „unter dem Telefon". Die Zeile muss hier stehen, weil der Anker am
       Kapitel näher dran ist als die .reise-Zeile darüber und sonst gewänne.
       Die Lage dazu: mittig, beide gleich — das ist der Übergang „bleibt". */
    .reise-kapitel[data-kapitel="6"],
    .reise-kapitel[data-kapitel="7"] {
        --lage-x: 0;
        --ziel-x: 0px;
    }

    /* ---- Die Kostenträger werden hochkant zur CHIP-ZEILE ----
       Haus und Name nebeneinander statt übereinander, und die Häuser kleiner
       (2,6 statt 4 rem). Unter dem Gerät ist die Höhe das knappe Gut: Ein
       Block aus großem Haus MIT Namen darunter war rund 70 px hoch und stand
       damit zwangsläufig ohne Luft zwischen Gerät und Beschriftung — die
       Chip-Zeile trägt dieselbe Auskunft in 34 px. */
    .reise-ziele {
        grid-template-columns: 1fr 1fr;
        width: calc(13rem * var(--rv));
        margin: calc(var(--ziel-y) - 1.1rem * var(--rv)) 0 0
                calc(var(--ziel-x) - 6.5rem * var(--rv));
    }

    /* Ein Gebäude bleibt eine Spalte breit, sonst stünde es hochkant in der
       linken Hälfte statt in der Mitte — und der Flug endet in der Mitte. */
    .reise-ziele--eins {
        grid-template-columns: 1fr;
        margin-top: calc(var(--ziel-y) - 1.1rem * var(--rv));
    }

    .reise-ziel {
        grid-template-columns: auto auto;
        align-items: center;
        justify-content: center;
        gap: calc(0.35rem * var(--rv));
    }

    .reise-haus {
        width: calc(2.6rem * var(--rv));
    }

    /* Nebeneinander statt übereinander: Der Versatz des einzelnen Hauses im
       Block dreht sich damit von senkrecht auf waagerecht — ein Viertel der
       Blockbreite, die Mitte der jeweiligen Spalte.

       --ab-y −2,2 rem: Die Sendung endet KURZ VOR der Chip-Zeile und blendet
       dort aus, statt auf Icon und Beschriftung zu landen — bei --ab-y 0
       stand die Geisterkarte beim Ausblenden genau auf dem PKV-Chip und
       deckte beides (Sichtungs-Befund, August 2026). Zwischen Geräteboden
       und Chips liegt hochkant nur ein schmales Band; die Karte ist beim
       Ankommen auf 0,4 geschrumpft und passt mit ihrer Unterkante genau
       darüber. */
    [data-reise-mode="player"] .reise-flug--beihilfe {
        --ab-x: calc(-3.25rem * var(--rv));
        --ab-y: calc(-2.2rem * var(--rv));
    }

    [data-reise-mode="player"] .reise-flug--pkv {
        --ab-x: calc(3.25rem * var(--rv));
        --ab-y: calc(-2.2rem * var(--rv));
    }

    /* Hochkant liegen Telefon und Karten übereinander, und der Platz reicht für
       beides nur knapp. Bündig am Boden der Kunstfläche begannen die Karten bei
       254 px und deckten die Abrechnung im Telefon zu. Sie rücken tiefer und
       werden gedrängter gesetzt (zusammen rund 60 px) und beginnen damit unter
       der letzten Zeile. Die Karten stehen nur in Kapitel 6 — aus Kapitel 7
       sind sie ganz verschwunden, eine Hochkant-Ausblendung dort braucht es
       nicht. */
    .reise-belegkarten {
        left: auto;
        right: 50%;
        top: auto;
        bottom: -11%;
        /* LÜCKENLOS statt 0,35 rem Fuge: Die Karten liegen hochkant auf der
           unteren Gerätehälfte, und in jeder Fuge stand ein Streifen Telefon —
           früher deckte das eine Maskier-Tasche zu, deren Überstand als
           beiger Rand das Gerät abschnitt (Schritt 8). Jetzt schließen die Karten selbst: kein gap, die Ränder
           der Nachbarn fallen aufeinander, gerundet sind nur die Außenecken
           des Stapels — eine Liste aus drei Zeilen, wie in der App. */
        gap: 0;
        width: calc(16rem * var(--rv));
        margin: 0 calc(-8rem * var(--rv)) 0 0;
    }

    .reise-belegkarte {
        padding: calc(0.5rem * var(--rv)) calc(0.7rem * var(--rv));
        border-radius: 0;
    }

    .reise-belegkarte[data-pos="1"] {
        border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    }

    .reise-belegkarte[data-pos="2"],
    .reise-belegkarte[data-pos="3"] {
        margin-top: calc(0px - var(--staerke));
    }

    .reise-belegkarte[data-pos="3"] {
        border-radius: 0 0 var(--radius-sm) var(--radius-sm);
    }

    .reise-belegkarte u {
        margin-top: 0;
    }

    /* Hochkant hat die Bühne keine freie Seite für den Entwurf. Er legt sich
       als Blatt über die UNTERE Hälfte des Geräts — die Liste mit der
       abgelehnten Zeile oben bleibt frei, zugedeckt werden nur die beiden
       Knöpfe, aus denen er hervorgeht. Seine Ebene dafür steht in der
       Stapelordnung unten, wie bei jedem Requisit: Sie wäre hier von der
       späteren Papier-Zeile überschrieben worden, denn die Stapelordnung
       liegt im Blatt hinter diesem Block. */
    .reise-entwurf {
        width: calc(13.5rem * var(--rv));
        /* Halbe Breite: Das Gerät steht hochkant mittig (Lage 0), also liegt
           das Blatt auf derselben Achse. Hier stand −4,9 rem, die halbe Breite
           abzüglich der 24 px, die die frühere Lage 0,62 das Telefon nach
           rechts schob. */
        margin: calc(1.2rem * var(--rv)) 0 0 calc(-6.75rem * var(--rv));
    }

    /* Und die Taube startet an dessen Absende-Knopf statt am --ziel-Anker,
       der hochkant unter dem Gerät liegt. */
    .reise-brieftaube {
        margin: calc(5rem * var(--rv)) 0 0 calc(-1.8rem * var(--rv));
    }

    /* Kapitel 3 auf schmalen Flächen: Das Telefon hält man ÜBER die Karte, also
       darf die Karte nicht dahinter verschwinden — und genau das tat sie. Auf
       390 px war sie mit 197 px fast so breit wie die Kunstfläche, lag mittig
       unter dem Gerät, und vom QR-Code, um den es geht, blieb ein Streifen.

       Nebeneinander statt übereinander: Das Gerät rückt bündig an den rechten
       Rand der Kunstfläche, die Karte an den linken und etwas darüber hinaus —
       die Bühne ist breiter als die Kunstfläche, dort ist Platz. Der Fußtext
       fällt weg; er stünde in einer Karte dieser Breite in vier Zeilen, und
       seine Aussage trägt ohnehin die Beschriftung.

       --lage-y zurück auf 0: Die 0,16 waren für die Karte NEBEN dem Gerät
       gedacht. Hochkant schob dieselbe Zahl das Telefon in die Beschriftung. */
    .reise-kapitel[data-kapitel="3"] {
        --lage-x: 1;
        --lage-y: 0;
    }

    .reise-zahlkarte {
        left: -12%;
        top: 20%;
        width: calc(8.6rem * var(--rv));
        margin: 0;
        padding: calc(0.6rem * var(--rv));
    }

    .reise-qr {
        --qr-breite: calc(5rem * var(--rv));
        padding: calc(0.4rem * var(--rv));
    }

    .reise-zahlkarte-fuss {
        display: none;
    }

    /* LINKS VERSETZT (Schritt 5, mobil): Mittig unter
       dem Gerät deckte die Karte die Bank-Taste vollständig zu —
       Vollverdeckung liest sich als Fehler, bewusste Teilverdeckung nicht.
       Rechte Kante von 50 % + 7,5 rem auf 50 % + 4,5 rem: Auf 390 px bleibt
       das rechte Drittel der Taste frei (nachgemessen: 43 von 126 px), auf
       320 px ihr rechter Rand. Die linke Kante bleibt auf beiden Breiten in
       der Bühne. */
    .reise-zahlbeleg {
        left: auto;
        right: 50%;
        bottom: 2%;
        width: calc(15rem * var(--rv));
        margin-right: calc(-4.5rem * var(--rv));
    }

    /* Die Abrechnung startet links sichtbar und trifft das weiter rechts
       stehende Telefon, statt hinter dessen Rahmen zu verschwinden. */
    .reise-art--abrechnung .reise-screen {
        left: 12%;
        margin-right: 0;
    }

    /* Feindetails, die auf 390 px nicht mehr lesbar sind, kosten dort nur
       Rechenzeit beim Scrubben. */
    .reise-beleg-spalten,
    .reise-beleg-meta {
        display: none;
    }

    /* Im erkannten Beleg bleibt die Kopfzeile stehen — auf das Datum darin zeigt
       eines der Schilder. */
    .reise-beleg--erkannt .reise-beleg-meta,
    .reise-beleg--erfasst .reise-beleg-meta {
        display: flex;
    }

    .reise-beleg-zeile[data-pos="5"],
    .reise-beleg-zeile[data-pos="6"] {
        display: none;
    }
}

/* Auf schmalen Flächen steht die Beschriftung unter dem Gerät statt daneben.
   Als eigene Abfrage statt verschachtelt, damit der Lint-Parser einen Selektor
   je Block sieht.

   Sie hängt an der Unterkante der Kunstfläche und nicht mehr an der der Bühne:
   So beginnt jede der zwölf Beschriftungen an derselben Stelle. Am Bühnenboden
   ausgerichtet rutschte eine kurze Beschriftung (Kapitel 5: 152 px) 57 px
   tiefer als eine lange, und der Text sprang beim Kapitelwechsel. */
@media (max-width: 767.98px) and (prefers-reduced-motion: no-preference) {
    [data-reise-mode="player"] .reise-captions {
        top: calc(var(--reise-kunst-halbhoch) * 2 + var(--reise-text-abstand));
        bottom: auto;
        height: max-content;
        margin: 0 0 0 calc(var(--reise-text-breite) / -2);
        text-align: center;
    }

    /* ---- Kapitel 7 hochkant: die Wahl weicht dem Entwurf ------------------
       Der Entwurf legt sich hochkant ÜBER die beiden Knöpfe, und während
       seiner Blende stand der „Widerspruch"-Text doppelt übereinander — halb
       durchsichtiges Blatt über vollem Knopftext (Sichtungs-Befund, August
       2026). Die Fenster liegen deshalb NACHEINANDER: Knöpfe herein wie
       überall (0,12), wieder raus 0,30 bis 0,36, DANN der Entwurf herein
       (0,34). Ein Fenster, selbst-enthalten über min() wie bei den
       Schildern in Kapitel 2 — Ruhebild Schritt 9: Knöpfe weg (unter dem
       deckenden Entwurf), Doppeldruck ausgeschlossen. In Beat 2 übernimmt
       die Zustands-Regel der Choreografie (gedimmt auf 0,45): Nach dem
       Abflug des Entwurfs steht die Wahl damit als getroffene da, und beim
       Ausblenden liegt darunter nur der gedimmte Rest. Das translateY des
       Auftritts kommt weiter aus der Basisregel (--w). */
    [data-reise-mode="player"] .reise-kapitel[data-kapitel="7"] .reise-wahl {
        opacity: clamp(0, min(calc((var(--sp) - 0.12) / var(--w-mittel)),
                              calc((0.36 - var(--sp)) / var(--w-kurz))), 1);
    }

    /* Der Druck rückt vor die Ausblendung der Knöpfe (Impuls 0,24 bis 0,384,
       Spitze bei 0,31): Bei 0,26 fiel seine Spitze mitten in das
       Weg-Fenster, und die Geste war nicht mehr zu sehen. */
    [data-reise-mode="player"] .reise-taste--widerspruch {
        --druck-ab: 0.24;
    }
}

/* ---- Unter 373 px: die letzte Engstelle -----------------------------------
   Der Maßstab 0,85 gilt inzwischen hochkant überall (767er-Abfrage) — er war
   zuerst hier, weil das Gerät ab 373 px abwärts höher ist als die Kunstfläche
   (auf 320 px schnitt die Bühnenoberkante 23 px vom Gehäuse ab). Was hier
   bleibt, hängt an der Schmalheit selbst:
   - --reise-text-abstand 4 rem: Die Requisiten unter dem Gerät (Chip-Zeile,
     Schilder-Legende) reichen auf 320 px dichter an die Beschriftung heran,
     weil die Kunstfläche (281 px) das zentrierte Gerät (279 px) gerade noch
     fasst. --reise-text-hoehe wächst um dieselbe Differenz.
   - Kapitel 5 und der Briefstapel rücken, siehe die Kommentare im Block. */
@media (max-width: 372.98px) {
    .reise {
        --reise-text-abstand: 4rem;
        --reise-text-hoehe: 17rem;
    }

    /* Der Maßstab 0,85 und die Lagen kommen inzwischen aus der 767er-Abfrage:
       Beide gelten hochkant überall gleich, nicht erst hier. Übrig bleibt, was
       wirklich an der Engstelle unter 373 px hängt. */

    /* Kapitel 5: Auf 320 px ist die Kunstfläche so schmal, dass das Gerät auf
       Lage 1 links noch zu weit hereinragt — die Nabe der Uhr verschwand
       dahinter. Es rückt ein Stück über die Kante hinaus (die Bühne ist
       breiter als die Kunstfläche), die Uhr weicht weiter nach links; ihre
       Nabe bleibt damit sichtbar. Die 1,6 sind nachgerechnet, nicht geraten:
       --tel-spanne-x rechnet mit der ungeskalten Gerätebreite, auf 211 px
       Fläche sind das nur 17 px je Einheit. */
    .reise-kapitel[data-kapitel="5"] {
        --lage-x: 1.6;
    }

    .reise-uhr {
        left: -10%;
    }

    /* Der Briefstapel in Kapitel 1: Bei 40 % schnitt die Bühne auf 320 px
       19 px vom untersten, gedrehten Umschlag ab — eine flache Kante mitten
       durch die Ecke. Die Gruppe rückt geschlossen Richtung Mitte, dieselben
       vier Selektoren wie im 767er-Block, damit das Blatt weiterhin aus dem
       Umschlag kommt und denselben Weg ins Gerät nimmt. */
    .reise-stapel,
    .reise-beleg--reise,
    .reise-beleg--vorn,
    .reise-scanrahmen {
        left: 48%;
    }

    /* Und der Weg des Belegs rechnet gegen dieselben 48 %: Der erste Faktor
       ist der Abstand zur Mitte (50 % − 48 %), wie die 0,10 im 767er-Block
       die 40 % waren. */
    .reise-beleg--vorn {
        --vorn-x: calc(var(--reise-kunst-breite) * 0.02
                       + var(--lage-x, 1) * var(--tel-spanne-x));
    }
}

/* ==========================================================================
   GESTALTUNG: LINIE · ZEICHNUNG

   Stil aus docs/ui-mockups/beleg-stile.html (FEATURE-0142).

   Alle Requisiten werden auf Konturen umgestellt: gleichmäßige Strichstärke,
   helle Füllung, keine Verläufe, keine Texturen, keine Schlagschatten. Der
   Akzent markiert je Bild genau eine Stelle — mehr Türkis nimmt der Bewegung
   die Lesbarkeit, weil die Statusfarben dieselbe Sprache sprechen.

   Bewusst als eigener Block am Ende statt verteilt in den Requisiten: So ist
   die Gestaltung an einer Stelle nachvollziehbar, vergleichbar und im Zweifel
   in einem Zug wieder zu entfernen. Bleibt der Stil, wandert er in die
   Definitionen.

   KEIN SCHLAGSCHATTEN, NIRGENDS. In der Sektion lagen vierzehn davon in sechs
   Rezepturen, fünf als handgeschriebene rgba-Werte außerhalb der Tokens, dazu
   zwei türkise Glühschatten am Scanstrahl. Elf davon hat dieser Block ohnehin
   schon auf `none` zurückgenommen — sie standen nur noch als tote Deklaration
   im Blatt, und die sechs `none` daneben waren die Gegengewichte dazu. Alle
   zwanzig sind ersatzlos entfallen: Wo nichts wirft, braucht auch niemand
   etwas zurückzunehmen.

   Sichtbar geändert hat das genau drei Stellen — das Glühen um Scanlinie und
   QR-Strahl und den Schatten unter dem Auslöser. Abgehoben wird ab jetzt über
   Kontur und deckende Fläche; braucht eine Stelle später doch mehr, kommt
   dafür EIN Token für alle und kein neuer rgba-Wert.
   ========================================================================== */

/* Die Werte stehen in tokens.css unter --linie-*, weil der Hero denselben Stil
   trägt und Tokens nirgends doppelt leben. Hier bleiben nur die kurzen Namen,
   mit denen die rund 30 Regeln unten arbeiten. */
.reise {
    --strich: var(--linie-strich);
    --strich-leise: var(--linie-strich-leise);
    --strich-stark: var(--linie-strich-stark);
    --flaeche: var(--linie-flaeche);
    --staerke: var(--linie-staerke);
}

/* ---- Grundregel: alles wird Kontur ---- */

.reise-beleg,
.reise-brief,
.reise-geraet,
.reise-zahlkarte,
.reise-dokument,
.reise-belegkarte,
.reise-empfehlung,
.reise-qr,
.reise-zahlbeleg {
    background: var(--flaeche);
    border: var(--staerke) solid var(--strich);
}

/* Der Bildschirm steht bewusst nicht in der Liste darüber: Sein Rand IST das
   Gehäuse. Auf 2 px verschmälert wüchse die Fläche darin um rund 24 px, und die
   Szene stünde ohne JavaScript in einer anderen Größe als im Player. Kontur
   wird er trotzdem — über die Farbe, nicht über die Breite. */
.reise-screen {
    background: var(--flaeche);
    border-color: var(--strich);
}

/* Verläufe und Texturen der bisherigen Fassung zurücknehmen. */
.reise-beleg,
.reise-brief {
    background-image: none;
}

/* AUSNAHME: Der erfasste Beleg in Kapitel 1 ist das FOTO im Display, kein
   Papier, das auf dem Bildschirm liegt. Er füllt das Display randlos und
   trägt deshalb weder Kontur noch eigene Fläche — die Fläche IST der
   Bildschirm. Die Zeile muss nach
   der Grundregel stehen, sonst gewinnt deren Rahmen. */
.reise-beleg--erfasst {
    background: transparent;
    border: 0;
}

.reise-beleg-rip,
.reise-brief::before {
    display: none;
}

/* ---- Papier ---- */

.reise-beleg {
    color: var(--strich);
}

.reise-beleg-kopf,
.reise-beleg-summe {
    border-color: var(--strich-leise);
}

.reise-beleg-praxis,
.reise-beleg-summe strong {
    color: var(--strich);
}

.reise-beleg-meta,
.reise-beleg-spalten,
.reise-beleg-summe span,
.reise-beleg-zeile i {
    color: var(--strich-leise);
}

/* Der frühere Kopie-Akzent (türkiser Rand) ist mit der Kopie entfallen: Was
   ins Telefon wandert, IST der Beleg — dieselbe Zeichnung wie das Papier
   davor und dahinter. Kapitel 1 behält damit eine Akzentstelle: die
   Scanlinie. */

/* AKZENT: was gefunden wurde. Die eine Akzentstelle von Kapitel 2 — als
   Unterstreichung statt als Fläche, damit sie zur Zeichnung passt. */
.reise-beleg--erkannt [data-feld]::after,
.reise-beleg--erkannt .reise-beleg-zeile--auffaellig::after {
    inset: auto 0 -2px 0;
    height: var(--staerke);
    border-radius: 0;
    background: var(--strich-stark);
    mix-blend-mode: normal;
}

.reise-beleg--erkannt .reise-beleg-zeile--auffaellig::after {
    background: var(--danger);
}

/* ---- Umschläge ---- */

/* Die Klappe bleibt im Linienstil eine reine Fläche. Eine Bodenlinie kann sie
   nicht tragen: Der clip-path schneidet sie bis auf die Dreiecksspitze weg, und
   was übrig blieb, lag als dunkler Rest mitten auf dem Umschlag — wie ein
   Papierschnipsel, der dort nichts zu suchen hat. */
.reise-brief-klappe {
    background: var(--flaeche);
    clip-path: polygon(0 0, 100% 0, 50% 100%);
}

/* ---- Bedienelemente: nie Akzent ----
   Sie standen in Türkis, und damit trug in Kapitel 2, 4 und 7 der KNOPF den
   Akzent — also das, was man drückt, und nicht das, was dabei herauskommt. Alle
   Tasten stehen jetzt in Tinte, wie die Banking-Taste es immer schon tat; eine
   Regel statt zweier. */

.reise-taste,
.reise-bank-taste {
    background: transparent;
    border: var(--staerke) solid var(--strich);
    color: var(--strich);
}

.reise-taste--still {
    border-color: var(--strich-leise);
    color: var(--strich-leise);
}

/* Der Fingertipp-Ring steht NICHT hier, sondern bei seiner Definition weiter
   oben. Genau diese Trennung war sein Fehler: Hier stand `.reise-tipp {
   border-color: … }`, und der Träger hat gar keinen Rand — der Ring liegt im
   ::after und blieb weiß und unsichtbar. */

.reise-haken {
    background: transparent;
    border-color: var(--strich);
    border-width: var(--staerke);
}

/* AKZENT: was ausgewählt wurde. Der Rahmen der Zeile daneben ist nur der
   Behälter und steht deshalb leise. */
.reise-haken::after {
    background: var(--strich-stark);
}

/* ---- Marken und Zeilen ---- */

.reise-badge {
    background: transparent;
    border: 1px solid currentColor;
}

/* Die Schilder waren dunkel gefüllt — im Linienstil sind auch sie Kontur. Der
   Haken bleibt der Akzent, denn er ist die eigentliche Aussage: erkannt. */
.reise-fahne {
    background: var(--flaeche);
    border: var(--staerke) solid var(--strich);
    color: var(--strich);
}

/* Die Kreise bleiben Kontur in Tinte — vier gefüllte Kacheln wären vier
   Flächen in einer Zeichnung. */
.reise-fahne-kreis {
    background: transparent;
    border: var(--staerke) solid var(--strich);
}

/* AKZENT — BEWUSSTE AUSNAHME von der Akzent-Sparsamkeit: Die Haken an den erkannten Feldern stehen in Türkis. Der
   Akzent markiert das ERGEBNIS — erkannt —, nicht das Bedienelement. Kapitel 2
   trägt damit zwei Akzentstellen: die Unterstreichungen im Beleg und diese
   Haken. */
.reise-fahne-haken {
    inset: 26%;
    background: var(--accent);
}

.reise-badge--offen { color: var(--status-open-fg); }
.reise-badge--erstattet { color: var(--status-success-fg); }
.reise-badge--teilweise { color: var(--status-pending-fg); }

/* Auswahl und Ablehnung werden als Rahmen markiert, nicht als Fläche.
   Der Auswahlrahmen steht leise: Drei türkise Kästen neben drei türkisen Haken
   waren sechs Akzentstellen für eine Aussage. Der Haken sagt sie schon. */
.reise-auswahl-zeile::before {
    background: transparent;
    border: var(--staerke) solid var(--strich-leise);
}

.reise-abrechnung-zeile--abgelehnt::before {
    background: transparent;
    border: var(--staerke) solid var(--danger);
}

.reise-abrechnung-zeile,
.reise-auswahl-zeile {
    border-color: var(--strich-leise);
}

/* Die einzige gefüllte Fläche unter den Hinweisen: Sie liegt über dem Gerät,
   und durchscheinende Gerätekanten machen den Text unlesbar. */
.reise-empfehlung {
    background: var(--flaeche);
    border: var(--staerke) solid var(--danger);
    color: var(--danger);
}

/* ---- Zahlung ----
   Der QR-Code bringt seine Farben selbst mit (Eckringe als Kontur, Kerne und
   Module in --strich, siehe _qr_code.html) — hier gibt es nichts mehr
   umzufärben. */

/* Kein Hintergrund mehr: Die Erfolgsmeldung steht im Fluss unter dem
   Bank-Logo und deckt nichts — die frühere Quittung lag als Fläche über der
   Überweisungsmaske, die es nicht mehr gibt. */
.reise-quittung {
    background: transparent;
}

.reise-quittung-haken {
    background: transparent;
    border: var(--staerke) solid var(--strich-stark);
}

.reise-quittung-haken::after {
    background: var(--strich-stark);
}

.reise-dokument-zeile {
    height: var(--staerke);
    background: var(--strich-leise);
    border-radius: 0;
}

/* ---- Uhr ---- */

.reise-uhr-rand {
    fill: none;
    stroke: var(--strich);
    stroke-width: 2;
}

.reise-uhr-flaeche {
    fill: var(--flaeche);
    stroke: none;
}

.reise-uhr-striche line {
    stroke: var(--strich-leise);
}

.reise-uhr-zeiger {
    stroke: var(--strich);
}

.reise-uhr-mitte {
    fill: var(--strich);
}

.reise-uhr-welle {
    border-color: var(--strich-stark);
}

/* ---- Einreichen, Zuordnen, Widerspruch ---- */

/* Die Gebäude bringen ihre Kontur im SVG mit (fill: none, stroke: --strich) und
   brauchen hier nichts: Sie sind schon Zeichnung, wo die anderen Requisiten
   erst dazu gemacht werden müssen. */

/* Der Entwurf ist ein frei stehendes Blatt neben dem Gerät und damit ein
   Requisit wie Beleg und Dokument: dieselbe Kontur, dieselbe Stärke. Solange
   er die Fläche des Bildschirms war, stand er bewusst ohne Rand — das gilt
   nicht mehr, ein Blatt ohne Kontur schwebte als weißes Loch im Bild. */
.reise-entwurf {
    background: var(--flaeche);
    border: var(--staerke) solid var(--strich);
}

/* Die Erfolgsmeldung ist Druckbild der App im Bildschirm, keine Kontur eines
   Requisits — 1 px wie die Zeilen und Marken daneben. */
.reise-erfolg {
    background: var(--milk-pure);
    border: 1px solid var(--hairline);
}

.reise-belegkarte b { color: var(--strich); }
/* Die Datumszeile bleibt die leise von beiden, aber nicht in --strich-leise:
   Crema auf Milch sind 2,58:1, und das hier ist gelesener Text und keine
   Kontur. --text-secondary ist der Token für genau diese Rolle (4,66:1). */
.reise-belegkarte em { color: var(--text-secondary); }

.reise-entwurf-text {
    background: transparent;
    border: 1px solid var(--strich-leise);
}

.reise-cursor {
    background: var(--strich);
}

.reise-brieftaube svg {
    fill: var(--flaeche);
    stroke: var(--strich);
    stroke-width: 2;
}

/* Der Sucherrahmen steht in Tinte: Er RAHMT nur, die Bewegung darin ist die
   Aussage. Vier türkise Ecken plus eine türkise Laufschiene waren fünf
   Akzentstellen für ein Ereignis. */
.reise-scanecke {
    border-color: var(--strich);
}

/* AKZENT: hier wird gerade gescannt. */
.reise-scanlinie {
    background: var(--strich-stark);
    height: var(--staerke);
}

.reise-qr-strahl {
    background: var(--strich-stark);
    height: var(--staerke);
}


/* ==========================================================================
   STAPELORDNUNG

   Benannte Ebenen statt verstreuter Zahlen. Im Linienstil deckt nichts mehr,
   deshalb ist jede falsche Reihenfolge sofort sichtbar — und jede neue
   Requisite braucht eine bewusste Einordnung statt einer geratenen Zahl.

   Von unten nach oben:
     kulisse    Stapelrücken, Hintergrundflächen
     papier     Belege, Umschläge, Dokumente
     geraet     Telefon
     aufsatz    Schilder, Empfehlung, Kacheln, Scanrahmen
     geste      Fingertipp, Stempel, fliegende Sendung
     leiste     Fortschritt
   ========================================================================== */

.reise {
    /* Zehnerschritte, damit Zwischenlagen ganze Zahlen bleiben: z-index ist
       ganzzahlig, halbe Stufen runden unkontrolliert und die Reihenfolge fällt
       dann auf die Markup-Reihenfolge zurück. */
    --e-kulisse: 10;
    --e-papier: 20;
    /* 30 bleibt frei: Dort lag der Ordner (--e-behaelter). Die Lücke ist
       billiger als das Umnummerieren aller Stufen darüber. */
    --e-geraet: 40;
    --e-aufsatz: 50;
    --e-geste: 60;
    --e-leiste: 70;
}

.reise-brief--4 { z-index: var(--e-kulisse); }
.reise-brief--3 { z-index: calc(var(--e-kulisse) + 1); }
.reise-brief--2 { z-index: calc(var(--e-kulisse) + 2); }

.reise-beleg,
.reise-beleg--reise,
.reise-dokument,
.reise-zahlbeleg {
    z-index: var(--e-papier);
}

/* In Kapitel 1 liegt das Blatt unter der Kulisse: Es steckt im Stapel und wird
   von dessen Tasche verdeckt, bis es herausgezogen ist. Der Stapel bekommt dafür
   einen eigenen Wert — sonst entscheidet über die Reihenfolge, ob er gerade
   einen Stapelkontext bildet, und die z-index seiner Briefe wirken nur nach
   innen. */
.reise-stapel { z-index: var(--e-kulisse); }
.reise-art--post .reise-beleg--reise { z-index: calc(var(--e-kulisse) - 5); }

/* Der oberste Umschlag liegt über dem Blatt, damit es sichtbar dahinter
   hervorkommt. */
.reise-brief--1 { z-index: calc(var(--e-papier) + 5); }

.reise-geraet,
.reise-screen {
    z-index: var(--e-geraet);
}

/* Ausnahme: Beim Scannen hält man das Telefon ÜBER den Beleg. Läge der
   Scanrahmen davor, schnitte er quer durch das Gerät. */
.reise-screen--haltend { z-index: calc(var(--e-aufsatz) + 5); }

.reise-scanrahmen,
.reise-fahne,
.reise-empfehlung,
.reise-belegkarten,
.reise-ziele {
    z-index: var(--e-aufsatz);
}

/* Der Entwurf steht als Blatt auf der Papier-Ebene: Er hat seinen eigenen
   Platz am --ziel-Anker und deckt dort nichts zu — die Belegkarten, über die
   er in einer früheren Fassung von der Aufsatz-Ebene aus Text deckte, gibt es
   in Kapitel 7 nicht mehr. Hochkant liegt er bewusst ÜBER dem Gerät (dessen
   untere Hälfte, die Knöpfe): Dort gibt es keine freie Seite, und ein Blatt
   unter dem opaken Bildschirm wäre zu zwei Dritteln unsichtbar. */
.reise-entwurf { z-index: var(--e-papier); }

@media (max-width: 767.98px) {
    .reise-entwurf { z-index: var(--e-aufsatz); }
}

/* Die Uhr ist Kulisse, seit das Telefon in Kapitel 5 zurück ist: Sie steht
   dahinter, nicht davor. Vorher lag sie auf der Aufsatz-Ebene — dort gab es
   nichts, wovor sie hätte liegen können. */
.reise-uhr { z-index: var(--e-kulisse); }

/* Die Zahlkarte liegt auf dem Tisch, das Telefon hält man darüber — sonst
   schneidet der QR-Code quer durch das Gerät, das ihn gerade scannt. */
.reise-zahlkarte { z-index: calc(var(--e-geraet) - 5); }

/* Der Beleg, der auf „bezahlt" springt, ist die Aussage dieser Szene und
   gehört deshalb vor das Gerät. */
.reise-art--zahlung .reise-zahlbeleg { z-index: calc(var(--e-aufsatz) + 2); }

/* Die FLIEGENDE Sendung ist eine Geste — sie steht seit jeher so in der
   Ebenen-Liste oben, nur die Regel dazu fehlte: Als .reise-dokument erbte sie
   die Papier-Ebene (20) und lag damit ÜBER dem Gehäusering, aber UNTER der
   Bildschirmfläche. Sichtbar blieb beim Kreuzen des Geräts nur das L-förmige
   Stück außerhalb des Bildschirms, dessen Espresso-Kontur mit dem
   Gehäuseumriss verschmolz — hochkant in Kapitel 6 las sich das als
   aufgeklappte Lasche am unteren Gehäuserand (Sichtungs-Befund, August 2026).
   Auf der Gesten-Ebene fliegt die Sendung als VOLLSTÄNDIGE Karte vor dem
   Gerät — und „fliegt sichtbar hinein" stimmt jetzt auch auf dem Bildschirm. */
.reise-flug { z-index: var(--e-geste); }

/* .reise-quittung stand hier mit: Als deckende Fläche über dem Bildschirm
   brauchte sie die Gesten-Ebene. Jetzt steht sie im Fluss der App-Seite und
   stapelt sich dort von selbst. */
.reise-tipp,
.reise-brieftaube,
/* Die vordere Fassung des Belegs liegt auf der Gesten-Ebene: In Beat 1 tritt
   sie VOR die Umschläge — genau dafür ist sie da. Ihr Platz steht hier und
   nicht bei ihrer Gestaltung, weil `.reise-beleg` oben eine Ebene tiefer
   liegt und bei gleicher Gewichtung die spätere Regel gewinnt. */
.reise-beleg--vorn {
    z-index: var(--e-geste);
}

/* In Kapitel 1 hat der Schluss von Beat 2 eine feste Reihenfolge von unten
   nach oben: Blatt (aufsatz + 3), Scanlinie im Rahmen darüber (aufsatz + 4),
   haltender Bildschirm zuoberst (aufsatz + 5).

   Das Blatt UNTER dem Bildschirm: Beim Erfassen schiebt es sich HINTER das
   Telefon und verschwindet sichtbar dahinter — das Foto steigt zeitgleich im
   Display auf (von hinten/unten, nicht von oben aufs Display). Über Stapel und Umschlägen bleibt es.

   Die Scanlinie ÜBER dem Blatt: Gescannt wird das Blatt, also muss der
   Streifen darüberlaufen — auf der Aufsatz-Ebene verschwand er hinter dem
   Papier, und vom Durchlauf blieben nur die Ränder. */
.reise-art--post .reise-beleg--vorn {
    z-index: calc(var(--e-aufsatz) + 3);
}

/* Der haltende Bildschirm traegt in Kapitel 1 seinen Rand selbst — dasselbe
   Muster wie Kapitel 5 (die Uhr): Der Gehaeuserahmen gehoert zur Buehne und
   liegt UNTER den Kapiteln; ein Kapitel-Element kann nicht dahinter. Ohne
   eigenen Rand lag das Blatt auf dem Weg hinter das Telefon sichtbar UEBER
   der linken Rahmenkante. */
[data-reise-mode="player"] .reise-art--post .reise-screen--haltend {
    border-color: var(--strich);
}

.reise-art--post .reise-scanrahmen {
    z-index: calc(var(--e-aufsatz) + 4);
}

/* Die frühere Reveal-Persistenz steht hier nicht mehr: Sie hielt einmal
   gezündete Anlauf-Animationen beim Zurückscrollen im Endzustand fest. Am
   Scroll-Fortschritt gibt es nichts zu zünden — dieselbe Position ergibt
   dieselbe Rechnung und damit dasselbe Bild, vorwärts wie rückwärts. */

/* ==========================================================================
   DAS RUHEBILD DER STATISCHEN FASSUNG

   Ohne JavaScript und bei reduzierter Bewegung steht jedes Kapitel für sich in
   seinem Endzustand. Für die meisten Requisiten ist das richtig — das Ende IST
   das Bild. Für ein paar ist es das nicht, und zwar aus zwei entgegengesetzten
   Gründen:

     - Was im Player NACHEINANDER auftritt, steht hier GLEICHZEITIG da. In
       Kapitel 1 lagen Briefstapel, Rechnung und Sucher übereinander im selben
       Bild — der Text war richtig, das Bild nicht.
     - Was im Player am Ende weg ist, trägt `opacity: 0` als Grundwert und
       fehlt hier deshalb, obwohl es zum Bild gehört. Und umgekehrt: Was den
       Endzustand „unsichtbar" hat, ohne ihn als Grundwert zu tragen, steht hier
       sichtbar da, obwohl es weg sein sollte.

   Beides ist dieselbe Frage — WELCHES Bild erzählt dieses Kapitel, wenn es nur
   eines geben darf? Sie wird hier je Kapitel einmal beantwortet, statt sie der
   Reihenfolge der Regeln zu überlassen.

   Der Selektor trifft beide Fälle: Ohne JavaScript trägt der Player nie ein
   data-reise-mode, bei reduzierter Bewegung nimmt js/reise.js es wieder weg.

   NUR DEKORATION. Kein Text wird hier unsichtbar — die Beschriftungen stehen
   vollständig und in ihrer Reihenfolge im Dokument, sie sind der Inhalt der
   Sektion. Was hier weicht, ist Zeichnung.
   ========================================================================== */

/* Kapitel 1 — der Scan-Moment: das Blatt liegt, das Telefon hält darüber.
   Der Stapel hat seine Rolle in Beat 1 gespielt; steht er daneben, erzählt das
   Bild „Post UND Scannen" und damit zwei Dinge auf einmal. */
[data-reise-player]:not([data-reise-mode="player"]) .reise-stapel {
    opacity: 0;
}

/* Und das Blatt rückt aus dem Telefonrahmen heraus. Im Player liegen beide
   übereinander, weil das Gerät darüber gehalten wird und sich bewegt; hier
   steht es still, und ein Blatt, dessen rechte Spalte dauerhaft unter einem
   Rahmen liegt, sieht nach Fehler aus statt nach Aufnahme. Der Rest überlappt
   weiter — genau so viel, dass „darüber gehalten" lesbar bleibt. */
[data-reise-player]:not([data-reise-mode="player"]) .reise-art--post .reise-beleg--reise {
    margin-right: calc(6rem * var(--rv));
}

/* Kapitel 5 — die Uhr links, das Telefon rechts. Im Player stellt die
   Gerätelage (0,62) das Telefon vor den rechten Rand der Uhr; statisch gibt es
   keine Lage, und ein mittig stehendes Telefon deckte die Uhr bis auf einen
   Rand zu. Dieselbe Seitenverteilung, zwei Mechanismen. */
[data-reise-player]:not([data-reise-mode="player"]) .reise-screen--warten {
    left: auto;
    right: 0;
}

/* Kapitel 6 — die zugeordneten Belege, nicht der Absender. Das Gebäude hat im
   Player geliefert und räumt danach das Feld; statisch stünde es hinter den
   Karten, die an seiner Stelle stehen sollen. */
[data-reise-player]:not([data-reise-mode="player"]) .reise-art--abrechnung .reise-ziele {
    opacity: 0;
}

/* Kapitel 4 hochkant — die Gebäude unter die Kunstfläche, genauer: unter die
   UNTERKANTE DES GERÄTS, denn es ist höher als die Fläche und ragt planvoll
   darunter hinaus. Die --ziel-y-Rechnung dafür steht seit --lage-s 1 für
   beide Fassungen gemeinsam im Mobil-Block: Das Gerät ist in beiden gleich
   groß, also ist es dieselbe Rechnung. Hier bleibt nur, was die statische
   Fassung eigen hat — ihr Bildschirm liegt nicht an der Gerätelage, sondern
   an seiner Klassenlage, und muss deshalb selbst an die Oberkante.

   Der Platz darunter ist da und dafür vorgesehen — .reise-kapitel hält hochkant
   5 rem Abstand zur Beschriftung, ausdrücklich für Requisiten, die unter ihre
   Fläche ragen. */
@media (max-width: 767.98px) {
    [data-reise-player]:not([data-reise-mode="player"]) .reise-art--einreichen .reise-screen {
        top: 0;
    }
}

/* ==========================================================================
   KONTRASTMODUS — nach den derzeitigen Gestaltungsregeln

   Im Kontrastmodus dürfen die Zeichnungen nicht verschwinden. Der Block stand
   bis August 2026 vor dem Gestaltungsteil „LINIE · ZEICHNUNG" und lief für die
   Uhrzeiger ins Leere: Ein Media-Query hebt die Spezifität nicht an, und
   `.reise-uhr-zeiger { stroke: var(--strich) }` weiter unten hat dieselbe —
   bei Gleichstand gewinnt die spätere Regel. Custom Properties ersetzt der
   Browser im Kontrastmodus nicht, und `stroke` gehört nicht zu den
   Eigenschaften, die er dort selbst erzwingt: Die Zeiger wären in einem
   Kontrastschema unsichtbar geblieben.

   Die Nutzerzusage ist sichtbarer Kontrast, nicht diese Position im CSS.
   Andere Lösungen für Spezifität und Kaskade bleiben ausdrücklich möglich;
   der Browser-Test prüft deshalb die gerenderte Wirkung.
   ========================================================================== */
@media (forced-colors: active) {
    .reise-uhr-zeiger {
        stroke: currentColor;
    }

    .reise-beleg--erkannt [data-feld]::after,
    .reise-beleg--erkannt .reise-beleg-zeile--auffaellig::after,
    .reise-auswahl-zeile::before,
    .reise-abrechnung-zeile--abgelehnt::before {
        display: none;
    }
}
