/* ═══════════════════════════════════════════════════════════════════════════════
   Kampagnen-Website „Jeder Traum beginnt mit Dir“ – Stylesheet

   Aufbau:
     1. Basis        Reset, Fonts, Variablen, body
     2. Navbar       fixierte Kopfleiste + Overlay-Menü
     3. Footer
     4. Slides       horizontaler Track, Story-Slides (Text/Medien/Zitate/Teaser)
     5. Mobil        Story-Slides ≤ 1024px inkl. Ebenen-Layout (is-bleeding, is-layered-text),
                     reduzierter Modus (≤ 640px und unter 750px Höhe) und dessen Komplement
     6. Startseite   Hero, Geschichten-Kacheln, Kartenstapel (Swap-Stack), Swipe-Intro
     7. Modal        „mehr erfahren“-Bottom-Sheet
     8. Feinwerte    Mobile Feinjustierung je Kind (reduziert / normal)
     9. Tablet quer  1025–1279px: Desktop-Layout mit kompakter Navbar
    10. Tablet hoch  641–1024px: mobiles Layout mit relativen Maßen (svh/vw)
    11. Reduzierte Bewegung  prefers-reduced-motion: alle Dauer-Animationen aus
    12. Consent & Video  Cookie-Banner, Footer-Button „Cookie-Einstellungen“, YouTube-2-Klick
    13. Hinweisleiste   Fotoausstellung (Startseite, zwischen Hero und Übersicht)

   Breakpoints: ≤ 640 Handy, 641–1024 Tablet hochkant, 1025–1279 Tablet quer,
   ≥ 1280 Desktop (Begründung in _overview/DECISIONS.md).

   Hinweis zur Reihenfolge: Viele Regeln gleicher Spezifität gewinnen nur durch ihre
   Position in der Datei (Mobil-Overrides nach den Desktop-Regeln, kindspezifische
   Feinjustierung nach den generischen Regeln). Blöcke daher nicht umsortieren.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── 1. Basis ── */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

@font-face {
    font-family: "Futura";
    src: url("../fonts/futura-std-book.otf") format("opentype");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Futura";
    src: url("../fonts/futura-std-bold.otf") format("opentype");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

:root {
    --navbar-height: 120px;
    --color-blue: #23529a;       /* Markenblau: Text, Buttons, Footer, Menü */
    --color-yellow: #f6ce46;     /* Markengelb: Navbar, CTAs, Sticky-Nav */
    --color-text: #333;
    --gradient-blue: linear-gradient(to top right, #12244a 0%, #1c3a70 55%, #2d559b 100%);
    --gradient-dark: linear-gradient(to top right, #1c1c1c 0%, #2e2e2e 55%, #3d3d3d 100%);
    /* Innenabstand der Story-Slides – Fotos durchbrechen ihn per negativem Margin,
       deshalb muss überall exakt derselbe Wert benutzt werden. */
    --slide-padding: clamp(1.5rem, 4vw, 3.5rem);
}

html {
    scroll-padding-top: var(--navbar-height);
    scroll-behavior: smooth;
}

body {
    font-family: "Futura", sans-serif;
    line-height: 1.6;
    color: var(--color-text);
    background-color: #fff;
    padding-top: var(--navbar-height); /* Inhalt nicht unter der fixierten Navbar verstecken */
}

/* Skip-Link: erstes Element im body, unsichtbar geparkt, bei Tastaturfokus oben links
   eingeblendet – Tastatur- und Screenreader-Nutzer überspringen damit die Navigation. */
.skip-link {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 200;
    padding: 0.75rem 1.25rem;
    background: var(--color-yellow);
    color: var(--color-blue);
    font-weight: 700;
    text-decoration: none;
    translate: 0 -150%;
}

.skip-link:focus-visible {
    translate: 0 0;
    outline: 3px solid var(--color-blue);
    outline-offset: -3px;
}

/* ── 2. Navbar ── */
.navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 100;
    height: var(--navbar-height);
    background-color: var(--color-yellow);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

/* Inhalt wie im Footer auf Content-Breite begrenzt, statt bis an den Viewport-Rand zu gehen. */
.navbar__inner {
    max-width: 1200px;
    margin: 0 auto;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 2rem;
}

.navbar__logo {
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--color-blue);
    text-decoration: none;
    display: flex;
    align-items: center;
}

.navbar__logo-img {
    height: 80px;
    width: auto;
    display: block;
}

/* Claim + Burger als Gruppe rechtsbündig, Claim sitzt somit direkt links neben dem Icon */
.navbar__right {
    display: flex;
    align-items: center;
    gap: 1.5rem;
}

.navbar__claim {
    color: var(--color-blue);
    font-weight: 700;
    text-transform: uppercase;
    white-space: nowrap;
    font-size: 1.38rem;
    line-height: 1.2;
    /* Nur auf der Startseite per JS erst nach einem Teil des Header-Scrolls eingeblendet
       (50% Desktop / 25% Mobil, siehe Schwelle im Script sowie body.home unten); auf
       Unterseiten ohne .hero gibt es diesen Scroll-Bezug nicht, daher dort immer sichtbar. */
    opacity: 1;
    transition: opacity 0.3s ease;
}

body.home .navbar__claim {
    opacity: 0;
}

body.home .navbar__claim.is-visible {
    opacity: 1;
}

.navbar__claim-line2 {
    display: inline;
}

.navbar__burger {
    /* Testweise komplett ausgeblendet – Claim rückt dadurch automatisch bündig an die
       Content-Kante, da .navbar__right dann nur noch den Claim enthält. */
    display: none;
}

.navbar__burger span {
    display: block;
    height: 5px;
    background-color: var(--color-blue);
    border-radius: 2px;
    transition: transform 0.25s ease, opacity 0.25s ease;
}

/* Burger → X wenn aktiv */
.navbar__burger[aria-expanded="true"] span:nth-child(1) {
    transform: translateY(9.5px) rotate(45deg);
}
.navbar__burger[aria-expanded="true"] span:nth-child(2) {
    opacity: 0;
}
.navbar__burger[aria-expanded="true"] span:nth-child(3) {
    transform: translateY(-9.5px) rotate(-45deg);
}

/* ── Nav-Menü ── */
.nav-menu {
    /* Bündig mit dem Burger-Icon in .navbar__inner (max-width 1200px + 2rem Padding),
       nicht am Viewport-Rand – wächst erst ab 1200px Content-Breite nach innen. Eigene
       Property, da sie sowohl für die Ruheposition (right) als auch für die
       Versteck-Transformation gebraucht wird (siehe unten). */
    --nav-menu-inset: max(2rem, calc((100vw - 1200px) / 2 + 2rem));
    position: fixed;
    top: var(--navbar-height);
    right: var(--nav-menu-inset);
    z-index: 99;
    background-color: var(--color-blue);
    padding: 1.75rem 2.25rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    /* Muss um die eigene Breite UND den Inset hinausfahren, sonst bleibt die Box bei
       größerem Inset (breite Viewports) im geschlossenen Zustand sichtbar im Bild stehen. */
    transform: translateX(calc(100% + var(--nav-menu-inset) + 24px));
    visibility: hidden;
    transition: transform 0.35s ease, visibility 0s 0.35s;
    min-width: 220px;
}

.nav-menu--open {
    transform: translateX(0);
    visibility: visible;
    transition-delay: 0s;
}

.nav-menu nav {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.nav-menu__item {
    color: #fff;
    text-decoration: none;
    font-size: 1.3rem;
    font-weight: 700;
    opacity: 0.85;
    transition: opacity 0.15s ease;
}

.nav-menu__item:hover {
    opacity: 1;
}

/* ── 3. Footer ── */
.footer {
    scroll-snap-align: start;
    scroll-snap-stop: always;
    background-color: var(--color-blue);
    color: #fff;
}

.footer__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 3rem 2rem;
    display: flex;
    gap: 2rem;
    flex-wrap: wrap;
}

.footer__col {
    flex: 1;
    min-width: 180px;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.footer__logo-img {
    height: 76px;
    width: auto;
    display: block;
    align-self: flex-start;
    margin-bottom: 0.25rem;
}

.footer__col a {
    color: #fff;
    text-decoration: none;
    opacity: 0.85;
}

.footer__col a:hover {
    opacity: 1;
}

/* Adresse/Kontakt unter dem Logo links im Footer */
.footer__contact {
    font-size: 0.95rem;
    line-height: 1.7;
    opacity: 0.9;
}

.footer__contact strong {
    font-size: inherit;
    text-transform: none;
    letter-spacing: normal;
    opacity: 1;
}

.footer__contact a {
    color: #fff;
}

/* Mittlere Spalte bleibt bewusst leer – nur zur Wahrung der 3-Spalten-Proportion */
.footer__col--spacer {
    flex: 1;
}

/* Icons + Legal-Zeile am Desktop rechtsbündig zum rechten Content-Rand */
.footer__col--social {
    align-items: flex-end;
}

.footer__col--social .footer__legal {
    text-align: right;
}

/* Mobil bleibt die Social-Spalte linksbündig wie die übrigen Spalten. */
@media (max-width: 1024px) {
    .footer__col--social {
        align-items: flex-start;
    }

    .footer__col--social .footer__legal {
        text-align: left;
    }
}

.footer__social {
    display: flex;
    gap: 0.75rem;
}

.footer__social-icon {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background-color: #fff;
    color: var(--color-blue);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    text-decoration: none;
    transition: background-color 0.2s ease;
}

.footer__col a.footer__social-icon {
    background-color: #fff;
    color: var(--color-blue);
    opacity: 1;
}

a.footer__social-icon:hover,
a.footer__social-icon:focus-visible {
    background-color: var(--color-yellow);
}

.footer__legal {
    font-size: 0.85rem;
    opacity: 0.7;
}

.footer__legal a {
    color: #fff;
    text-decoration: none;
}

.footer__legal a:hover {
    text-decoration: underline;
}

/* ── 4. Slides (Story-Seiten) ── */
.section {
    height: calc(100vh - var(--navbar-height));
    height: calc(100svh - var(--navbar-height)); /* echte sichtbare Höhe (iOS-Safari-Leisten) */
    overflow: hidden;
    position: relative;
    background-color: #f0f0f0; /* blitzt nur durch, wenn ein Foto nicht bis zum Rand reicht */
}

/* Track: natives horizontales Scroll (Scrollbar versteckt). Mausrad wird per JS
   (assets/js/slide-scroll.js) in horizontales Scrollen übersetzt; nach einer Geste rastet
   der Track sanft ein, wenn er bereits nah (Toleranz) an einer Slide-Kante steht. */
.section__track {
    /* position:relative dient als Koordinatensystem für Elemente, die per [data-bleed]
       (siehe slide-scroll.js) zwischen zwei Slides gehängt werden. */
    position: relative;
    display: flex;
    height: 100%;
    overflow-x: auto;
    scrollbar-width: none;
}

.section__track::-webkit-scrollbar {
    display: none;
}

/* Touch: innerhalb einer Geschichte nur horizontal wischen (11.09.2026). Ohne die
   Einschränkung nahm iOS jede schräge Wischgeste auch vertikal mit, die Seite
   schwamm auf und ab (unter dem Slide-Bereich liegt der Footer). Gleiche Logik wie
   der Mausrad-Handler in slide-scroll.js: nur die letzte Slide (Teaser) lässt
   vertikales Wischen zu, damit der Footer erreichbar bleibt. pinch-zoom bleibt
   erlaubt (WCAG 1.4.4). Die mobil an den Track gehängten Ebenen (.is-bleeding,
   .is-layered-text) sind keine Slide-Nachkommen mehr und brauchen die Regel selbst;
   die Teaser-Ebenen sind über data-layer-home ausgenommen. Maus/Tastatur unberührt.
   #teaser statt :last-child: die herausgehobene Teaser-Ebene wird hinter die Slide
   in den Track gehängt, dann ist die Slide nicht mehr das letzte Kind. */
.slide:not(#teaser),
.is-bleeding:not([data-layer-home="teaser"]),
.is-layered-text:not([data-layer-home="teaser"]) {
    touch-action: pan-x pinch-zoom;
}

/* Slides – horizontal nebeneinander im Track */
.slide {
    position: relative;
    /* z-index:0 (statt auto) erzwingt einen EIGENEN Stapelkontext je Slide – sonst
       würden negative z-index-Kinder nicht nur hinter den eigenen Slide-Inhalt
       zurückfallen, sondern bis zum nächsten Vorfahren mit echtem Stapelkontext
       "durchrutschen" und hinter der kompletten Slide bzw. Nachbar-Slides
       verschwinden. */
    z-index: 0;
    flex-shrink: 0;
    width: 100vw;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ── Slide-Inhalt ── */
.slide__inner {
    display: flex;
    flex-wrap: wrap;
    gap: 2rem;
    width: 100%;
    height: 100%;
    padding: 2rem;
    align-items: stretch;
}

.slide__col {
    flex: 1 1 280px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Story-Slides: abwechselnd dunkelgrau/blau, mit leichtem Verlauf wie im Hero. */
.slide--dark {
    background: var(--gradient-dark);
}

.slide--blue {
    background: var(--gradient-blue);
}

.slide--dark,
.slide--blue {
    color: #fff;
}

/* Zweispaltiges Grundlayout: Text + Medium (Foto oder Icon-Grafik), per Modifier
   spiegelbar, damit sich Foto/Icon-Seite von Slide zu Slide abwechselt. */
.story-slide__inner {
    display: flex;
    align-items: center;
    gap: clamp(2rem, 5vw, 4rem);
    width: 100%;
    max-width: 1200px;
    height: 100%;
    margin: 0 auto;
    padding: var(--slide-padding) 2rem;
}

.story-slide__inner--reverse {
    flex-direction: row-reverse;
}

.story-slide__text {
    position: relative;
    max-width: 480px;
}

.story-slide__icon {
    display: block;
    margin-top: 1.25rem;
    animation: icon-float 4.5s ease-in-out infinite;
}

.story-slide__icon svg,
.story-slide__icon img {
    width: 72px;
    height: 72px;
}

/* Subtiles Schweben, gleiches Prinzip wie .swap-card__float auf der Startseite –
   leichter dosiert (kleinere Amplitude), da es eine ruhende Illustration ist. */
@keyframes icon-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-8px); }
}

/* Intro-Illustration (Slide 1): etwas größer und nach rechts/unten versetzt, steht im
   normalen Textfluss nach dem "mehr erfahren"-Link. */
.story-slide__icon--intro {
    margin-left: 3rem;
    margin-top: 4rem;
}

.story-slide__icon--intro svg,
.story-slide__icon--intro img {
    width: 100px;
    height: 100px;
}

.story-slide__icon--intro .story-slide__icon-image--mathea-dog {
    width: 145px;
    height: 145px;
}

/* Schwebende Illustration (Slide 4): oben rechts über dem Text, aus dem Fluss gelöst
   (absolute relativ zu .story-slide__text) und deutlich größer. */
.story-slide__icon--float {
    position: absolute;
    top: -110px;
    right: -50px;
    margin: 0;
}

.story-slide__icon--float svg,
.story-slide__icon--float img {
    width: 140px;
    height: 140px;
}

/* Mathea, Slide 4: Pfote nach rechts versetzt, etwas höher und im Uhrzeigersinn gekippt
   (mobil zurückgesetzt). */
.story-slide__icon--mathea-paw img {
    position: relative;
    left: 120px;
    top: -40px;
    rotate: 12deg;
}

/* Amy-spezifische Illustrationsgrößen und -positionen. */
.story-slide__icon--amy-landing img {
    width: 120px;
    height: 120px;
    rotate: 8deg; /* leicht im Uhrzeigersinn gekippt, mobil zurückgesetzt */
}

.story-slide__icon-lg--amy-filmklappe {
    position: relative;
    top: -20px;
    rotate: 8deg; /* leicht im Uhrzeigersinn gekippt, mobil zurückgesetzt */
}

/* Lilly, Slide 1: Haarband etwas größer und leicht gegen den Uhrzeigersinn gekippt
   (mobil beides zurückgesetzt). */
.story-slide__icon-image--lilly-haarband {
    rotate: -8deg;
}

.story-slide__icon--intro .story-slide__icon-image--lilly-haarband {
    width: 125px;
    height: 125px;
}

/* Maja und Willi, Slide 1: Illustration etwas größer (mobil zurückgesetzt). */
.story-slide__icon--intro .story-slide__icon-image--maja-rollstuhl,
.story-slide__icon--intro .story-slide__icon-image--willi-flagge {
    width: 130px;
    height: 130px;
}

/* Maja, Mathea und Willi, Slide 2: Illustration etwas höher (mobil zurückgesetzt). */
.story-slide__icon-lg--maja-fahrrad,
.story-slide__icon-lg--mathea-halsband,
.story-slide__icon-lg--willi-esb {
    position: relative;
    top: -40px;
}

/* Connor, Slide 2: Geländer etwas größer und höher (mobil zurückgesetzt). Doppelte
   Klasse, damit die Breite gegen die spätere .story-slide__icon-lg-Regel gewinnt. */
.story-slide__icon-lg.story-slide__icon-lg--connor-gelaender {
    position: relative;
    top: -45px;
    width: clamp(260px, 24vw, 390px);
}

@media (min-width: 769px) {
    .story-slide__icon--amy-floating {
        top: -145px;
    }
}

@media (max-width: 768px) {
    .story-slide__icon--amy-landing img {
        width: 90px;
        height: 90px;
    }
}

/* Ben und Luisa teilen sich eine Geschichte. In jedem Illustrationsbereich stehen ihre
   Motive deshalb als Paar nebeneinander; der Abstand verhindert auch während der
   Schwebeanimation eine optische Überlagerung. */
.story-slide__icon-pair,
.story-slide__illustration-pair {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 2vw, 2rem);
}

.story-slide__icon-pair--intro img {
    width: 100px;
    height: 100px;
    object-fit: contain;
    animation: icon-float 4.5s ease-in-out infinite;
}

.story-slide__illustration-pair--large .story-slide__icon-lg {
    width: clamp(135px, 12vw, 190px);
}

/* Giraffe in eigener Schwebe-Phase, sonst ginge sie synchron mit den Turnschuhen. */
.story-slide__illustration-pair--large .story-slide__paired-illu--giraffe {
    animation-duration: 5.9s;
    animation-delay: -3.4s;
}

/* Schwebendes Paar (Slide 4, Ben und Luisa): weiter auseinander, vertikal versetzt und
   jedes Motiv in eigener Schwebe-Phase statt der gemeinsamen Animation am Span. */
.story-slide__icon-pair--floating {
    right: -95px;
    gap: clamp(2rem, 3vw, 3.5rem);
    animation: none;
}

.story-slide__icon-pair--floating img {
    animation: icon-float 4.6s ease-in-out infinite;
    width: 120px;
    height: 120px;
    object-fit: contain;
}

.story-slide__icon-pair--floating .story-slide__paired-illu--loewe {
    animation-duration: 5.8s;
    animation-delay: -2.6s;
}

/* Intro-Paar: jedes Motiv schwebt für sich (eigene Dauer/Phase statt der gemeinsamen
   Animation am Eltern-Span), das T-Shirt sitzt etwas tiefer als der Elefant. */
.story-slide__icon-pair--intro {
    animation: none;
}

.story-slide__paired-illu--elefant {
    rotate: -5deg;
}

.story-slide__paired-illu--tshirt {
    position: relative;
    top: 30px;
    rotate: 5deg;
}

/* Eigene Phase fürs T-Shirt – gleicher Elternselektor wie die animation-Kurzschreibweise
   oben, sonst würde diese die Dauer wieder überschreiben. */
.story-slide__icon-pair--intro .story-slide__paired-illu--tshirt {
    animation-duration: 5.6s;
    animation-delay: -2.1s;
}

.story-slide__paired-illu--turnschuhe {
    position: relative;
    top: -50px;
}

.story-slide__paired-illu--feld {
    position: relative;
    top: -35px;
    rotate: -10deg;
}

.story-slide__paired-illu--loewe {
    position: relative;
    top: 15px;
    left: 40px; /* etwas weiter vom Fußballplatz weg, mobil zurückgesetzt */
    rotate: 10deg;
}

.story-slide__heading {
    font-size: clamp(1.4rem, 2.2vw, 1.9rem);
    font-weight: 700;
    line-height: 1.2;
    margin-bottom: 1rem;
    /* Gleicht die Zeilenlängen bei mehrzeiligen Überschriften automatisch aus (kein
       "Ein Wort allein in der letzten Zeile" mehr) – ohne manuellen Umbruch nötig.
       Wird von Browsern ohne Unterstützung einfach ignoriert (normaler Umbruch). */
    text-wrap: balance;
}

.story-slide__text p {
    margin-bottom: 1rem;
    opacity: 0.85;
    line-height: 1.7;
    font-size: 0.95rem;
    text-wrap: pretty;
}

.story-slide__quote-line--nowrap {
    white-space: nowrap;
}

.story-slide__more {
    /* Ist ein <button> (öffnet das Modal, navigiert nicht): Browser-Standardoptik
       zurücksetzen, damit er aussieht und misst wie der frühere Link. Die Kurzform
       font: inherit muss VOR font-weight stehen, sonst setzt sie es wieder zurück. */
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-top: 0.25rem;
    color: var(--color-yellow);
    font-weight: 700;
    text-decoration: none;
}

/* Button, der nur den gekürzten Slide-Text fortsetzt (kein eigener Modal-Text):
   ohne Kürzung gäbe es nichts zu zeigen, daher nur auf dem Handy sichtbar
   (Einblendung im Excerpt-Block, Suche nach .story-slide__excerpt-rest). */
.story-slide__more--excerpt-only {
    display: none;
}

.story-slide__more svg {
    width: 14px;
    height: 14px;
    stroke-width: 3.4;
    flex-shrink: 0;
}

.story-slide__more:hover {
    text-decoration: underline;
}

.story-slide__media {
    position: relative;
    flex: 1 1 320px;
    height: 100%;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.story-slide__media--icon {
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 2.5rem;
}

/* Zitat (Slide 2 "Nachhaltigkeit") etwas nach rechts, statt bündig mit dem Icon
   abzuschließen. Wert an die kleinere Zitat-Schrift angepasst (war 200px) – sonst
   bleibt der Box zu wenig Restbreite in der Spalte und der Text bricht unnötig um. */
.story-slide__media--icon .story-slide__quote {
    margin-left: 60px;
}

.story-slide__media--center {
    align-items: center;
    perspective: 1000px;
}

/* 3D-Tilt fürs Foto (Slide 3 "Perspektive von Aktion Kindertraum") – gleiches Prinzip wie
   .swap-card__tilt/.swap-card__shine auf der Startseite, nur ohne das Schweben/Stapeln:
   reine Maus-Interaktion (Neigung + Glanzlicht folgen dem Cursor). */
/* Bewusst OHNE height:100% – ein Container mit fester (Prozent-)Höhe zwingt das Bild in
   ein Höhen×Breiten-Verhältnis, das die verfügbare Spaltenbreite oft nicht hergibt (das
   Foto wird dann durch die Breite gedeckelt und bleibt kürzer als der Container – genau
   der leere Rand ober-/unterhalb, in dem der Glanz-Effekt frei schwebte). Stattdessen
   schmiegt sich der Container per Flex-Shrinkwrap exakt an die tatsächliche Bildgröße an. */
.story-slide__tilt {
    position: relative;
    display: flex;
    border-radius: 32px 0 32px 0;
    overflow: hidden;
    transition: transform 0.15s ease-out;
    will-change: transform;
}

.story-slide__tilt .story-slide__photo {
    max-height: 65vh;
    max-width: 100%;
}

.story-slide__shine {
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.25s ease;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.45), transparent 55%);
    mix-blend-mode: overlay;
}

.story-slide__tilt.is-hovering .story-slide__shine {
    opacity: 1;
}

/* ── Bildwechsel im Tilt-Fenster (Slide 3 "Perspektive von Aktion Kindertraum") ──
   Drei Fotos liegen deckungsgleich übereinander und blenden im 3-Sekunden-Takt
   ineinander über. Reine CSS-Animation, bewusst ohne JS-Timer: es gibt keine
   Bedienelemente und keinen Zustand, der sich merken ließe – ein Timer wäre nur
   zusätzlicher Code mit demselben Ergebnis.

   Das Fenster braucht hier – anders als beim vorherigen Einzelbild, siehe Kommentar
   über .story-slide__tilt – eine eigene feste Größe: sobald alle Bilder absolut
   positioniert sind, hat der Container keinen Inhalt mehr im Fluss, an dem er sich
   shrinkwrappen könnte, und würde auf Höhe 0 kollabieren. Der Grund gegen eine feste
   Höhe von damals (leerer Rand, wenn das Bild kleiner bleibt als der Container) entfällt
   zugleich, weil object-fit:cover das Fenster jetzt immer randlos füllt. */
.story-slide__tilt--crossfade {
    width: 100%;
    /* 86.6vh ist die Breite, bei der ein 4:3-Fenster genau 65vh hoch wird – also
       dieselbe Höhenbegrenzung wie beim vorherigen Einzelbild, nur über die Breite
       ausgedrückt. Direkt über height ginge es nicht: height und max-width zusammen
       hebeln aspect-ratio aus, sobald der Deckel greift, und das Fenster verzerrt. */
    max-width: min(620px, 86.6vh);
    aspect-ratio: 4 / 3;
}

/* Die Größenangaben brauchen den Eltern-Selektor davor, nicht weil die Verschachtelung
   nötig wäre, sondern wegen der Kaskade: .story-slide__photo weiter unten (Suche nach
   "width: auto") ist gleich spezifisch und steht später in der Datei – ohne den Zusatz
   gewinnt dort width:auto, und die Bilder behalten trotz cover ihr Originalverhältnis,
   statt das Fenster zu füllen. */
.story-slide__tilt--crossfade .story-slide__crossfade {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* hebt max-height:65vh / max-width:100% der Einzelbild-Regel oben auf – die Größe
       gibt jetzt das Fenster vor, nicht mehr das Bild */
    max-height: none;
    max-width: none;
    opacity: 0;
    animation: story-crossfade 9s linear infinite;
}

/* Sichtbares Bild, wenn keine Animation läuft (prefers-reduced-motion, siehe unten,
   oder falls @keyframes nicht unterstützt werden). */
.story-slide__tilt--crossfade .story-slide__crossfade:first-of-type {
    opacity: 1;
}

/* Zeitrechnung: 3 Bilder à 3s ergeben einen Zyklus von 9s. Alle drei durchlaufen
   dieselbe Kurve, nur zeitversetzt. Der Versatz ist negativ, damit jedes Bild sofort
   mitten in der Animation einsteigt statt erst nach einer Wartezeit zu starten:
     Bild 1:  0s   voll sichtbar 0.0–2.2s, blendet aus bis 3.0s
     Bild 2: -6s   voll sichtbar 3.0–5.2s, blendet aus bis 6.0s
     Bild 3: -3s   voll sichtbar 6.0–8.2s, blendet aus bis 9.0s
   Aus- und Einblenden des jeweiligen Paares laufen dadurch exakt gleichzeitig – ein
   echtes Crossfade, ohne dass zwischendurch kurz der Hintergrund durchscheint.

   object-position: die beiden neuen Fotos sind nicht 4:3 (Bild 2 ist hochkant, Bild 3
   quadratisch), cover schneidet also oben und unten ab. Der Ausschnitt ist hier von Hand
   nach oben gezogen, damit die Gesichter im Bild bleiben – nach Augenmaß gesetzt, nicht
   berechnet. */
.story-slide__tilt--crossfade .story-slide__crossfade:nth-of-type(2) {
    animation-delay: -6s;
    object-position: center 25%;
}

.story-slide__tilt--crossfade .story-slide__crossfade:nth-of-type(3) {
    animation-delay: -3s;
    object-position: center 20%;
}

@keyframes story-crossfade {
    0%     { opacity: 1; }
    24.44% { opacity: 1; }  /* 2.2s */
    33.33% { opacity: 0; }  /* 3.0s – Überblendung dauert 0.8s */
    91.11% { opacity: 0; }  /* 8.2s */
    100%   { opacity: 1; }  /* 9.0s */
}

/* Kein automatischer Wechsel, wenn Bewegung reduziert gewünscht ist – es bleibt beim
   ersten Bild. */
@media (prefers-reduced-motion: reduce) {
    .story-slide__tilt--crossfade .story-slide__crossfade {
        animation: none;
    }
}

.story-slide__icon-lg {
    width: clamp(220px, 20vw, 320px);
    height: auto;
    display: block;
    animation: icon-float 5s ease-in-out infinite;
    animation-delay: -1.6s;
}

/* Zitat als „Textmarker“-Optik: jede Zeile einzeln weiß hinterlegt statt eine
   durchgehende Box, Zuordnung (Zitatgeber) läuft in derselben Zeile wie die letzte Zeile. */
.story-slide__quote {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
}

/* Hält die ursprünglichen Desktop-Zeilenteile als direkte Flex-Kinder. Mobil wird
   der Wrapper zur Zeile und fasst sie zur ersten von zwei Zeilen zusammen. */
.story-slide__quote-first-row-mobile {
    display: contents;
}

.story-slide__mobile-break,
.story-slide__quote--mobile-variant {
    display: none;
}

.story-slide__quote-line {
    display: inline-block;
    background-color: #fff;
    color: var(--color-blue);
    font-weight: 700;
    text-transform: uppercase;
    font-size: clamp(1.5rem, 2.9vw, 2.25rem);
    line-height: 1.25;
    padding: 0.15em 0.35em;
}

.story-slide__quote-row {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* Willis Jan-Teaser: Der Name steht rechts neben der zweiten Zitatzeile, solange
   beides nebeneinander passt. Entscheidend ist das nowrap auf der Zitatzeile selbst:
   Bricht sie um, liegen zwei Textzeilen in EINER weißen Fläche, weil der Hintergrund
   am inline-block hängt – die Zeilen kleben dann optisch zusammen. Wird der Platz zu
   eng, rutscht stattdessen der Name per flex-wrap in eine eigene Zeile, wo ihn
   margin-left:auto rechts hält. Erst ab 900px: Darunter klebt die Schriftgröße am
   clamp-Minimum, während die Textspalte weiter schrumpft – die Zeile liefe dann aus
   der Spalte heraus. Unterhalb von 900px gilt die Umbruchlogik der Tablet-Blöcke
   am Dateiende. */
@media (min-width: 900px) {
    .story-slide__quote-row--cite-right .story-slide__quote-line {
        white-space: nowrap;
    }
}

.story-slide__quote-row--cite-right .story-slide__quote-cite {
    margin-left: auto;
}

.story-slide__quote-cite {
    color: #fff;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-style: normal;
    font-size: 0.85rem;
    white-space: nowrap;
}

/* Echtes Foto (kein Icon, kein Platzhalter): größer und bündig an der Slide-Unterkante,
   durchbricht dafür das Bottom-Padding von .story-slide__inner gezielt per Negativ-Margin. */
.story-slide__media--photo {
    flex: 1.3 1 360px;
    margin-bottom: calc(-1 * var(--slide-padding));
    height: calc(100% + var(--slide-padding));
}

.story-slide__photo {
    max-height: 88%;
    max-width: 100%;
    width: auto;
    object-fit: cover;
    display: block;
}

.story-slide__photo--rounded {
    border-radius: 32px 0 32px 0;
}

/* Portrait-Freisteller (schmaler als hoch) dürfen breiter als ihre Spalte werden, damit
   sie „bündig unten“ groß wirken; normale Rechteckfotos bleiben innerhalb der Spalte. */
.story-slide__media--photo .story-slide__photo {
    max-width: 200%;
    max-height: 100%;
}

/* Slide 4 "Perspektive Unterstützer": Icon entfernt, Foto darf dafür deutlich größer sein.
   Bricht zusätzlich zum unteren auch durchs obere Inner-Padding, da bei einem Hochformat-
   Freisteller die Höhe (nicht die Breite) die eigentlich limitierende Größe ist. */
.story-slide__media--photo-xl {
    flex: 1.8 1 420px;
    margin-top: calc(-1 * var(--slide-padding));
    height: calc(100% + 2 * var(--slide-padding));
}

/* max-height allein reicht hier nicht: die Quelle ist niedrig aufgelöst (516×688px) und
   damit oft kleiner als der Rahmen, wodurch max-height als reine Obergrenze nie greift –
   erzwingt daher aktiv Hochskalieren statt nur zu begrenzen. 100% (nicht mehr), da der
   Rahmen selbst durch das Bleed schon deutlich größer ist als das Originalbild – mehr
   schneidet auf großen Screens sonst den Kopf an. */
.story-slide__media--photo-xl .story-slide__photo {
    max-width: 260%;
    max-height: none;
    height: 90%;
}

/* Familienfotos (Slide 4), Desktop. Die Dateien sind auf den sichtbaren Bereich
   beschnitten (kein transparenter Rand oben mehr, s. _quelldateien), dadurch füllen die
   Personen die 90 % Boxhöhe der Basisregel wirklich aus. Die breiteren Motive würden
   auf hohen Viewports in die Textspalte laufen – der viewportabhängige Rechtsversatz
   (≈0 px bei 1280, ≈45 px bei 1440, ≈150 px bei 1830) hält sie frei vom Text und
   innerhalb des Fensters. Gleicher Elternselektor wie die Basisregel, sonst verliert
   die Einzelklasse. Mobil werden left/height weiter unten zurückgesetzt. */
.story-slide__media--photo-xl .story-slide__photo--amy-supporter,
.story-slide__media--photo-xl .story-slide__photo--connor-supporter,
.story-slide__media--photo-xl .story-slide__photo--kevin-supporter,
.story-slide__media--photo-xl .story-slide__photo--mathea-supporter,
.story-slide__media--photo-xl .story-slide__photo--willi-supporter {
    position: relative;
    left: clamp(0px, 26.9vw - 342px, 180px);
}

/* Schmale Desktop-Fenster: der Rechtsversatz oben läuft unter ~1280px auf 0, deshalb
   hier ein harter Deckel – das Foto bleibt in seiner Spalte (+ Spaltenabstand) und kann
   nicht mehr in den Text ragen. height:auto lässt es entsprechend mitschrumpfen. */
@media (min-width: 641px) and (max-width: 1279px) {
    .story-slide__media--photo-xl .story-slide__photo {
        max-width: calc(100% + 4rem);
        height: auto;
        /* height:auto leitet die Höhe aus der Breite ab. Auf niedrigen Viewports
           (Tablet quer: 700px Slidehöhe) wurde das Motiv dadurch höher als der Slide
           und ragte oben unter der Navbar heraus. Der Deckel entspricht der Boxhöhe,
           lässt also das gewollte Durchbrechen des Innenabstands weiter zu. */
        max-height: 100%;
    }
}

/* Fast quadratische bzw. querformatige Motive etwas niedriger, damit sie bei 1830 px
   Breite nicht an den Text stoßen. */
.story-slide__media--photo-xl .story-slide__photo--amy-supporter {
    height: 88%;
}

.story-slide__media--photo-xl .story-slide__photo--ben-luisa-supporter {
    height: 72%;
    /* Eigener Versatz: das breite Motiv soll rechts knapp am Fensterrand enden
       (1280: ~10px, 1440: ~45px, 1830: ~130px). */
    left: clamp(0px, 21.8vw - 269px, 200px);
}

.story-slide__media--photo-xl .story-slide__photo--willi-supporter {
    height: 86%;
}

.story-slide__photo--kevin-teaser {
    position: relative;
    left: 80px;
}

.story-slide__photo--jan-teaser {
    position: relative;
    left: 20px;
}

.story-slide__photo--lilly-supporter {
    position: relative;
    left: 50px;
}

.story-slide__photo--maja-supporter {
    position: relative;
    left: 80px;
}

.story-slide__label {
    position: absolute;
    top: 6%;
    left: 4%;
    width: clamp(150px, 19vw, 250px);
    height: auto;
    animation: icon-float 4.8s ease-in-out infinite;
    animation-delay: -2.2s;
}

/* Marker auf dem Teaser-Slide (5) anders positioniert als auf Slide 1. */
.story-quote .story-slide__label {
    left: -8%;
    top: 4%;
}

/* Luisas Marker (gemeinsame Ben-und-Luisa-Geschichte) schwebt in eigener Phase, damit
   die beiden Marker nicht synchron auf und ab gehen. Positionen: Desktop im Block
   darunter, mobil bei .is-bleeding weiter unten. */
.story-slide__label--hero-luisa {
    animation-duration: 5.7s;
    animation-delay: -0.6s;
}

.story-slide__label--hero-luisa-mobile {
    display: none;
}

/* ── Hero-Marker (Slide 1) am Foto ausgerichtet, nicht an der Spalte ──
   Das Freisteller-Foto hängt an der Unterkante der Spalte und ist entweder so hoch wie
   die Spalte oder – bei großen Viewports – auf 200 % der Spaltenbreite gedeckelt. Ein
   Marker mit top:6 % blieb dann oben stehen, während das Foto nach unten rutschte.
   Deshalb wird die Fotogröße hier nachgerechnet (--photo-w/--photo-h; Seitenverhältnis
   der Hero-Fotos 2400:1449 = 1.656) und die Marker über bottom/left als Anteil davon
   gesetzt – sie treffen den Kopf so bei jeder Fenstergröße. Die Prozentwerte in den
   Variablen beziehen sich erst am Einsatzort (left = Breite, bottom = Höhe) auf die
   Spalte. Der Deckel für --photo-h nimmt die Spaltenbreite über den Viewport an
   (exakt ab 1264 px, darunter leicht genähert). Mobil bleibt alles bei den
   .is-bleeding-Regeln. */
@media (min-width: 641px) {
    #landingpage .story-slide__media--photo {
        --photo-w: min(200%, calc(1.656 * (100vh - var(--navbar-height) - var(--slide-padding))));
        --photo-h: min(100%, calc(0.5958 * min(100vw - 4rem, 1200px)));
        /* Obergrenze für bottom: Der Marker darf nicht über die Slide-Oberkante hinaus. */
        --label-max-bottom: calc(100% + var(--slide-padding) - 156px);
    }

    /* Standard: Marker links oben über dem Kopf, Punkt rechts unten am Haar. */
    #landingpage .story-slide__media--photo .story-slide__label {
        top: auto;
        bottom: min(calc(0.92 * var(--photo-h)), var(--label-max-bottom));
        left: calc(50% - 0.23 * var(--photo-w));
    }

    /* Ben: etwas weiter links und tiefer, Punkt links neben seinem Haar. */
    #landingpage .story-slide__media--photo .story-slide__label--hero-ben {
        bottom: min(calc(0.96 * var(--photo-h)), var(--label-max-bottom));
        left: calc(50% - 0.303 * var(--photo-w));
    }

    /* Luisa: gespiegelter Marker (Punkt unten links) links neben dem Haar. Der zweite
       min()-Zweig hält den Marker bei schmalen Viewports (1280) im Fenster: rechte Kante
       maximal 10 px vor dem Rand (Spalte beginnt bei 50vw − 24px). */
    #landingpage .story-slide__media--photo .story-slide__label--hero-luisa {
        bottom: min(calc(0.90 * var(--photo-h)), var(--label-max-bottom));
        left: min(calc(50% + 0.135 * var(--photo-w)), calc(50vw - 236px));
        right: auto;
    }
}

/* Bens Marker weit links, Endpunkt links neben seinen Haaren (Text steht dadurch über
   der oberen Sternzacke, kollidiert aber nicht mit dem Zitat). */
.story-quote .story-slide__label--teaser-ben {
    top: calc(4% - 30px);
    left: calc(-10% - 200px);
}

.story-quote .story-slide__label--teaser-luisa {
    right: calc(-8% - 80px);
    left: auto;
}

.story-quote .story-slide__label--teaser-connor {
    left: calc(-8% - 80px);
}

.story-quote .story-slide__label--teaser-lilly {
    left: calc(-8% - 80px);
}

.story-quote .story-slide__label--teaser-mathea {
    left: calc(-8% - 80px);
}

/* Abschließender Zitat-Slide je Geschichte, überleitet zur jeweils anderen Geschichte */
.story-quote {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(2rem, 6vw, 5rem);
    width: 100%;
    max-width: 1200px;
    height: 100%;
    margin: 0 auto;
    /* Vertikales Padding muss exakt zur Bleed-Berechnung von .story-slide__media--photo
       passen (gleiche clamp()-Formel wie .story-slide__inner) – bei abweichendem Wert
       reicht das Foto bei schmaleren Breiten nicht mehr ganz bis zum Rand und die
       .section-Hintergrundfarbe blitzt als Rand durch. */
    padding: var(--slide-padding) 2rem;
}

/* Linke Seite wie der Startseiten-Header: Stern-Silhouette groß im Hintergrund. Das Zitat
   selbst nutzt jetzt dieselbe Komponente wie auf Slide 2 (.story-slide__quote), damit
   Größe/Ausrichtung/Durchschuss garantiert identisch sind statt nur angeglichen. */
.story-quote__stage {
    position: relative;
    flex: 1 1 380px;
    max-width: 540px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    /* Zitat + Stern (Hintergrund) zusammen etwas nach links/unten, auf Wunsch – bewegt
       beide gemeinsam, da der Stern (.story-quote__star) und das Zitat beide Kinder
       dieser Stage sind; der Marker auf dem Foto rechts bleibt davon unberührt. */
    transform: translate(-40px, 40px);
}

/* Zitat nach rechts, damit es im offenen Bereich des Sterns sitzt statt an dessen
   linker Zacke; 18% lässt genug Breite, damit "– Name" neben der letzten Zeile bleibt. */
.story-quote__stage .story-slide__quote {
    margin-left: 18%;
    margin-top: -120px;
}

/* CTA unter dem Zitat/Stern, verlinkt zur Geschichte der porträtierten Person – gleiches
   Text+Pfeil-Prinzip wie .story-slide__more ("mehr erfahren"), nur zweizeilig – gleiches
   Gelb wie überall sonst (var(--color-yellow)). position:absolute statt normaler Flex-Child, da
   .story-quote__stage die Flex-Children per justify-content:center zentriert – als
   zweites Flex-Item hätte das CTA sonst die Zentrierung (und damit die Position) des
   Zitats mitverschoben, sobald sich sein eigener Abstand ändert. So bleibt das Zitat an
   seiner Position, unabhängig davon, wo das CTA sitzt. */
.story-quote__cta {
    position: absolute;
    top: 210px;
    left: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2em;
    margin-left: 18%;
    color: var(--color-yellow);
    font-weight: 700;
    text-decoration: none;
    line-height: 1.3;
}

.story-quote__cta-line {
    font-size: 1rem;
}

.story-quote__cta-line--name {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 1.2rem;
}

.story-quote__cta:hover .story-quote__cta-line--name {
    text-decoration: underline;
}

.story-quote__cta-arrow {
    width: 15px;
    height: 15px;
    stroke-width: 3.4;
    flex-shrink: 0;
    /* Dezentes Wackeln, damit der Pfeil (und damit der ganze CTA) mehr auffällt und zum
       Klicken einlädt, statt als statisches Element leicht übersehen zu werden. */
    animation: story-quote__cta-arrow-wiggle 1.6s ease-in-out infinite;
}

@keyframes story-quote__cta-arrow-wiggle {
    0%, 100% {
        transform: translateX(0);
    }
    50% {
        transform: translateX(6px);
    }
}

.story-quote__star {
    position: absolute;
    top: 50%;
    left: 62%;
    width: 230%;
    max-width: 820px;
    height: auto;
    transform: translate(-50%, calc(-50% + 20px));
    pointer-events: none;
}

/* ── Sticky Bottom-Nav (nur Projekt-Unterseiten): Pfeile zur vorherigen/nächsten
   Slide (per JS, slide-scroll.js) + Link zur Übersicht auf der Startseite.
   Dauerhaft eingeblendet. ── */
.story-jump {
    position: fixed;
    left: 50%;
    bottom: 1.5rem;
    transform: translateX(-50%);
    z-index: 90;
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* Eigenständiger runder Button je Pfeil, statt gemeinsam mit der mittleren Pille in
   einem einzigen Container zu stecken – jedes Element trägt jetzt seinen eigenen
   Hintergrund/Schatten. */
.story-jump__arrow {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--color-yellow);
    color: var(--color-blue);
    text-decoration: none;
    flex-shrink: 0;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

.story-jump__arrow svg {
    width: 18px;
    height: 18px;
    stroke-width: 3.8;
}

/* Scroll-Hinweis: pulsiert dezent, bis der Nutzer zum ersten Mal selbst interagiert
   (siehe slide-scroll.js) – zeigt an, dass es hier weitergeht. */
@keyframes story-jump-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.12); }
}

.story-jump__arrow--pulse {
    animation: story-jump-pulse 1.6s ease-in-out infinite;
}

.story-jump__overview {
    height: 44px;
    display: flex;
    align-items: center;
    padding: 0 1.5rem;
    background-color: var(--color-yellow);
    border-radius: 999px;
    color: var(--color-blue);
    font-weight: 700;
    font-size: 0.9rem;
    text-decoration: none;
    text-transform: uppercase;
    white-space: nowrap;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

.story-jump__overview:hover {
    text-decoration: underline;
}

/* ── 5. Mobil (≤ 640px): Slides bleiben horizontal, der Inhalt INNERHALB eines Slides
   (Text + Foto/Illustration) stapelt sich einspaltig. ── */
@media (max-width: 1024px) {
    .story-slide__desktop-break,
    .story-slide__quote--desktop-variant {
        display: none;
    }

    .story-slide__mobile-break {
        display: inline;
    }

    .story-slide__quote--mobile-variant {
        display: flex;
    }

    .story-slide__inner,
    .story-slide__inner--reverse {
        flex-direction: column;
        align-items: flex-start;
        justify-content: center;
        height: 100%;
        padding: 1.5rem;
        gap: 1rem;
        overflow: hidden;
    }

    /* Mobil zeigt die --reverse-Variante das Bild oben, den Text darunter (statt der
       Desktop-Reihenfolge Foto links / Text rechts per row-reverse). justify-content:
       flex-end statt geerbtem center – sonst wandert bei kürzerer Bildhöhe (16:10 statt
       proportional) der komplette Block als Ganzes weiter nach unten und reißt oben eine
       große, mit der Bildhöhe wachsende Lücke auf, statt dass sich der Abstand dynamisch
       an den tatsächlichen Inhalt anpasst. Achtung: bei column-reverse liegt das Main-Axis-
       "Start" unten – flex-end ist hier also die Kante, die visuell oben andockt. */
    .story-slide__inner--reverse {
        flex-direction: column-reverse;
        justify-content: flex-end;
    }

    .story-slide__text {
        max-width: none;
    }

    .story-slide__icon svg,
    .story-slide__icon img {
        width: 72px;
        height: 72px;
    }

    .story-slide__icon {
        margin-top: 0.5rem;
    }

    .story-slide__icon--intro {
        margin-left: 0;
        margin-top: 0.5rem;
    }

    .story-slide__icon--intro .story-slide__icon-image--mathea-dog {
        width: 95.04px;
        height: 95.04px;
    }

    /* Headlines und Fließtext mobil 5 % kleiner als die ursprüngliche Abstimmung
       (1.2rem/1.2 bzw. 0.9rem/1.411rem), Zeilenabstand entsprechend. */
    .story-slide__heading {
        font-size: 1.14rem;                       /* Fallback ohne svh-Unterstützung */
        /* Steiler als proportional: bei 664px Höhe exakt 1.14rem, darunter schrumpft die
           Schrift überproportional, damit lange Texte + Bild in die Slide passen. */
        font-size: clamp(0.88rem, calc(3.6svh - 5.7px), 1.14rem);
        line-height: 1.14;
    }

    /* Fließtext mobil: 0.9rem ist die Obergrenze, die der Platz auf den Slides hergibt.
       Zeilenhöhe absolut (1.411rem = 22.6px) statt als Faktor, damit die Absätze nicht
       höher werden als bei der früheren kleineren Schrift. */
    .story-slide__text p {
        font-size: 0.855rem;
        font-size: clamp(0.67rem, calc(2.9svh - 5.6px), 0.855rem);   /* 664px → 0.855rem */
        line-height: 1.34rem;
        line-height: clamp(1rem, calc(4.5svh - 8.4px), 1.34rem);
        margin-bottom: 0.6rem;
        margin-bottom: clamp(0.35rem, calc(2.2svh - 5px), 0.6rem);
    }

    .story-slide__media,
    .story-slide__media--icon {
        width: 100%;
        height: 190px;
        align-items: center;
    }

    .story-slide__media--photo {
        flex: initial;
        margin-bottom: 0;
        height: 190px;
    }

    /* Slide 1 (Intro) mobil: Illustration oben rechts über dem Text, Marker darunter,
       Foto groß/randabschneidend bündig unten. */
    .story-slide__inner--intro {
        justify-content: flex-start;
        padding-top: 0.5rem;
    }

    .story-slide__inner--intro .story-slide__text {
        display: flex;
        flex-direction: column;
        width: 100%;
    }

    .story-slide__inner--intro .story-slide__icon--intro {
        order: -1;
        align-self: flex-end;
        margin: 1rem 1.5rem 0.75rem 0;
    }

    /* Headline wird per negativem Margin neben die Illu gezogen; padding-right hält
       sie frei von der Illu (72px + Abstand), auch wenn sie nur eine Zeile lang wäre. */
    .story-slide__inner--intro .story-slide__heading {
        margin-top: -70px;
        padding-right: 110px;
    }

    .story-slide__inner--intro .story-slide__media--photo {
        position: relative;
        max-height: calc(100svh - 330px); /* niedrige Displays: Foto weicht dem Text */
        /* Schiebt die Box im Flex-Column (justify-content:flex-start) auf den gesamten
           verbleibenden freien Platz nach unten – bleibt dadurch bündig mit dem unteren
           Seitenrand, unabhängig davon, wie viel Höhe Text/Headline gerade einnehmen
           (statt auf eine feste, mit dem Textinhalt fein abgestimmte Höhe angewiesen zu sein). */
        margin-top: auto;
        width: calc(100% + 3rem);
        margin-left: -1.5rem;
        margin-right: -1.5rem;
        margin-bottom: -1.5rem;
        height: 440px;
        /* Bei langen Texten schrumpft die Box (flex-shrink) – aber nur bis zu der Höhe,
           die das Foto bei voller Slidebreite ohne Beschnitt hat (Hero-Fotos 2400:1449).
           Ohne diese Angabe hing die Untergrenze am Browser: Chromium rechnete genau
           diesen Wert als Mindestinhalt, Safari ließ die Box gar nicht schrumpfen
           (Foto ragte auf dem Tablet bis 150px über die Slide). Der Wert ist Chromiums
           bisheriges Verhalten, nur explizit – Chromium bleibt pixelgleich. */
        min-height: calc(100vw * 1449 / 2400);
    }

    .story-slide__inner--intro .story-slide__photo {
        width: 100%;
        height: 100%;
        max-height: none;
        max-width: none;
        object-fit: cover;
        object-position: center bottom;
    }

    /* Sobald das Foto per [data-bleed] (slide-scroll.js) zwischen Slide 1 und Slide 2
       hängt, greift der Ancestor-Selektor .story-slide__inner--intro nicht mehr –
       Position/Größe kommen dann per Inline-Style von dort, hier nur noch dieselbe
       Bildoptik (object-fit/-position) wie im Ruhezustand, generisch über .is-bleeding. */
    .is-bleeding.story-slide__media--photo .story-slide__photo {
        /* width:auto statt cover: das Bild rendert in natürlicher Breite und ragt sichtbar
           über die Box hinaus (weiter in Slide 2 hinein), statt beschnitten zu werden. */
        width: auto;
        height: 100%;
        max-height: none;
        max-width: none;
        /* Ausschnitt nach links; transform-origin bottom hält die Unterkante bündig mit
           dem Seitenrand (Skalierung 1.0, vorher 0.9 – Marker sind mobil ausgeblendet). */
        transform-origin: center bottom;
        transform: translateX(-90px) scale(1);
    }

    /* Slide-1-Fotos mobil je Kind abgestimmt: Versatz nach links und Größe (Basis ist
       translateX(-90px) scale(1) in der Regel darüber). */
    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-jan {
        transform: translateX(-120px) scale(1);
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-kevin,
    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-mathea {
        transform: translateX(-120px) scale(1.1);
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-connor {
        transform: translateX(-150px) scale(1.1);
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-amy {
        transform: translateX(-125px) scale(1.1);
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-lilly {
        transform: translateX(-100px) scale(1.1);
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-willi {
        transform: translateX(-145px) scale(1.1);
        scale: none; /* hebt die ältere Einzelkorrektur (.story-slide__photo--willi-hero) auf */
    }

    /* Traum-Marker auf Slide 1 mobil ausgeblendet – das Foto bekommt den Platz. Die
       Foto-Box wird per [data-bleed] umgehängt, daher .is-bleeding statt #landingpage
       (zweiter Selektor deckt den Fall ohne Umhängen ab). Teaser-Marker bleiben. */
    .is-bleeding .story-slide__label,
    #landingpage .story-slide__label {
        display: none;
    }

    /* Ebene 3 (Text/Zitat/Buttons, siehe setupTextLayers in slide-scroll.js): generische
       Basis für JEDES per [data-layer="text"] herausgehobene Element. .slide--blue/
       --dark{color:#fff} greift nach dem Herausheben nicht mehr (kein Nachkomme der
       Slide mehr) – Farbe hier erneut explizit setzen. display:flex + flex-direction
       bleibt nötig, damit z.B. order:-1 auf dem Basketball-Icon (siehe unten) weiter
       innerhalb dieser Box funktioniert. */
    .is-layered-text {
        color: #fff;
        display: flex;
        flex-direction: column;
    }

    /* Slide-spezifische Fortsetzungen der Ancestor-Regeln (.story-slide__inner--intro,
       --nachhaltigkeit …), die nach dem Herausheben nicht mehr greifen – hier über
       [data-layer-home] (von setupTextLayers gesetzt) erneut an die Herkunfts-Slide gebunden. */
    [data-layer-home="landingpage"].story-slide__text .story-slide__icon--intro {
        order: -1;
        align-self: flex-end;
        margin: 1rem 1.5rem 0.75rem 0;
    }

    [data-layer-home="landingpage"].story-slide__text .story-slide__heading {
        margin-top: -70px;
        padding-right: 110px;
    }

    /* Breitere Illus (Ben/Luisa-Paar, Matheas Hündchen) brauchen mehr Freiraum. :has()
       wirkt vor und nach dem Herausheben durch setupTextLayers gleichermaßen. */
    .story-slide__text:has(.story-slide__icon-pair--intro) .story-slide__heading {
        padding-right: 165px;
    }

    .story-slide__text:has(.story-slide__icon-image--mathea-dog) .story-slide__heading {
        padding-right: 135px;
    }

    [data-layer-home="nachhaltigkeit"].story-slide__media--icon {
        gap: 1.75rem;
    }

    [data-layer-home="nachhaltigkeit"] .story-slide__quote {
        margin-left: 0;
        margin-top: 3rem;
        gap: 0.4rem;
    }

    [data-layer-home="nachhaltigkeit"] .story-slide__quote-line {
        font-size: 1.25rem;
        padding: 0.15em 0.3em;
    }

    /* "– Jan" auf Wunsch als eigene Zeile links unter das Zitat statt inline daneben. */
    [data-layer-home="nachhaltigkeit"] .story-slide__quote-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.3rem;
    }

    /* Slide 4 "Perspektive Unterstützer" mobil: Text oben bündig wie auf Slide 2 (statt
       geerbtem center), damit der Text nicht mit wachsender/schrumpfender Restfläche
       herumspringt. */
    #perspektive-unterstuetzer .story-slide__inner {
        justify-content: flex-start;
    }

    #perspektive-unterstuetzer .story-slide__text {
        display: flex;
        flex-direction: column;
        width: 100%;
    }

    /* .story-slide__media--photo-xl erbt vom Desktop flex:1.8 1 420px (Grow) – würde
       mobil dieselbe "wächst über den Fotobedarf hinaus"-Falle wie auf Slide 3 auslösen,
       sobald der Sibling-Freeze in setupTextLayers greift. Analog dort auf 0 gesetzt. */
    #perspektive-unterstuetzer .story-slide__media--photo-xl {
        flex: 0 0 auto;
        /* Bündig mit dem unteren Seitenrand: margin-top:auto schiebt die Box im
           Flex-Column auf den gesamten verbleibenden freien Platz nach unten,
           margin-bottom durchbricht das Bottom-Padding von .story-slide__inner bis zur
           echten Slide-Kante (gleiches Prinzip wie Slide 1). */
        margin-top: auto;
        margin-bottom: -1.5rem;
        height: 280px;
        /* Statt der geerbten Mobil-Zentrierung (siehe .story-slide__media,
           .story-slide__media--icon{align-items:center} weiter oben) hier wieder bündig
           unten – zeigt den Rollstuhl (unterer Bildrand) statt mittig zwischen Kopf und
           Rollstuhl zu beschneiden. */
        align-items: flex-end;
    }

    /* Foto etwas nach rechts, damit links Platz für die ins Bleed wandernde Illustration
       bleibt. Zoom kleiner als die Basisregel (230%), sonst wird oben und unten beschnitten. */
    #perspektive-unterstuetzer .story-slide__media--photo-xl .story-slide__photo {
        margin-left: 70px;
        height: 130%;
        /* 10% größer aus der Mitte heraus, auf Wunsch – Überschuss (auch unten) wird vom
           overflow:hidden auf .story-slide__inner geschnitten. */
        transform: scale(1.1);
    }

    /* Jans Familienfoto etwas weiter rechts (Wunsch 01.09.2026). translateX im
       transform statt margin, damit die vom Sibling-Freeze gemessene Box unberührt
       bleibt. */
    #perspektive-unterstuetzer .story-slide__media--photo-xl .story-slide__photo--jan-supporter {
        transform: translateX(18px) scale(1.1);
    }

    /* Schwebende Illustration (Slide 4) mobil: unten links statt oben rechts, ragt per
       [data-bleed="prev"] (slide-scroll.js) leicht in Slide 3 hinein. Werte hier sind nur
       die Ausgangslage VOR dem Aushängen – danach positioniert JS per Inline-Style.
       bottom weniger negativ = sitzt höher, left weniger negativ = ragt weniger weit hinein. */
    .story-slide__icon--float {
        position: absolute;
        top: auto;
        right: auto;
        bottom: -240px;
        left: -40px;
        margin: 0;
    }

    .story-slide__icon--float svg,
    .story-slide__icon--float img {
        width: 160px;
        height: 160px;
    }

    /* Slide 2 "Nachhaltigkeit" mobil: engerer Abstand Text→Illu, Illu und Zitat verkleinert,
       damit das komplette Zitat innerhalb der Slide sichtbar bleibt. */
    .story-slide__inner--nachhaltigkeit {
        justify-content: flex-start;
        gap: 1.5rem;
    }

    /* Text wuchs bisher per geerbtem flex-grow über die gesamte Resthöhe der Column und
       riss dadurch die Illu weit nach unten – hier auf reine Content-Höhe fixiert. */
    .story-slide__inner--nachhaltigkeit .story-slide__text {
        flex: 0 0 auto;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__media--icon {
        flex: 0 0 auto;
        height: auto;
        gap: 1.75rem;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg {
        width: 270px;
        margin-left: 0px;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__quote {
        margin-left: 0;
        gap: 0.4rem;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__quote-line {
        font-size: 1.25rem;
        padding: 0.15em 0.3em;
    }

    /* Slide 3 "Perspektive von Aktion Kindertraum" mobil: Bildfenster auf 16:9 statt 4:3
       (Desktop), damit es in der schmalen Spalte nicht zu hoch wird – die 4:3-Fotos werden
       dafür oben/unten beschnitten (object-position hält die Gesichter im Bild). Gilt
       auch für Majas Einzelbild (.story-slide__tilt ohne --crossfade), das dafür vom
       Shrinkwrap auf ein festes Fenster mit object-fit:cover wechselt. Beide IDs:
       Bens zweite Slide 3 (#perspektive-akt-ben) ist seit 11.09.2026 auch auf dem
       Handy sichtbar (vorher ausgeblendet). */
    #perspektive-akt .story-slide__tilt,
    #perspektive-akt-ben .story-slide__tilt {
        width: 100%;
        max-width: none;
        aspect-ratio: 16 / 9;
        /* Auf niedrigen Displays (unter ~600px Höhe) flacher als 16:9, damit Headline +
           Text + Galerie zusammen in die Slide passen; die Fotos füllen per cover weiter. */
        max-height: max(110px, calc(100svh - 436px));
    }

    #perspektive-akt .story-slide__tilt .story-slide__photo,
    #perspektive-akt-ben .story-slide__tilt .story-slide__photo {
        width: 100%;
        height: 100%;
        max-height: none;
        max-width: none;
        object-fit: cover;
        object-position: center 30%;
    }

    /* Das Turnhallen-Gruppenfoto in Jans Galerie ist hochformatig - mit dem generischen
       30%-Fenster oben werden die Köpfe der hinteren Reihe angeschnitten. Fenster für
       dieses eine Bild weiter nach oben (Wunsch 01.09.2026). */
    #perspektive-akt .story-slide__tilt .story-slide__photo--jan-akt-gruppe {
        object-position: center 15%;
    }

    /* Hochformatige Galerie-Bilder (Klasse im jeweiligen HTML vergeben): Köpfe sitzen
       nah an der Oberkante, das generische 30%-Fenster schneidet sie an. */
    #perspektive-akt .story-slide__tilt .story-slide__photo--akt-hoch,
    #perspektive-akt-ben .story-slide__tilt .story-slide__photo--akt-hoch {
        object-position: center 12%;
    }

    /* .story-slide__media erbt flex:1 1 320px (Grow:1) – wächst dadurch normalerweise auf
       die volle verbleibende Spaltenhöhe. Der Sibling-Freeze in setupTextLayers (siehe
       slide-scroll.js) friert genau diese gewachsene Höhe ein; das Bild selbst bleibt aber
       shrinkwrapped auf seine tatsächliche (jetzt 16:10-)Größe und wurde dadurch nur noch
       mittig in der zu groß gefrorenen Box "schweben" gelassen. flex-grow hier auf 0, damit
       die eingefrorene Box von vornherein exakt der Bildgröße entspricht – passt sich so
       automatisch an, unabhängig von der gewählten Bildhöhe. */
    #perspektive-akt .story-slide__media--center,
    #perspektive-akt-ben .story-slide__media--center {
        flex: 0 0 auto;
        /* height:auto hebt die generische 190px-Höhe der Regel weiter oben auf. Seit dem
           Bildwechsel ist das Fenster hier 4:3 der Spaltenbreite (bei 342px also 257px)
           und ragte aus der zu niedrigen Box heraus – oben und unten je rund 34px, weil
           .story-slide__media mobil zentriert. Genau dieser Überstand hat die Abstände
           unten aufgefressen: übrig blieben 3px nach oben und 7px zum Text. Mit height:auto
           schmiegt sich die Box wieder an die echte Bildhöhe, und die Margins wirken.

           Sie wirken dabei indirekt: setupTextLayers (slide-scroll.js) misst Position und
           Größe im normalen Fluss, hebt das Element dann absolut positioniert heraus und
           setzt margin:0 inline. Die Margins stecken zu dem Zeitpunkt bereits in der
           gemessenen Position – im fertigen Layout sind sie deshalb nicht mehr als
           margin ablesbar, sondern im top-Wert enthalten. */
        height: auto;
        /* Oben kein eigener Abstand: die 24px, die .story-slide__inner ohnehin als Padding
           mitbringt, sind hier bereits der gewünschte Wert – derselbe wie links und rechts
           neben dem Bild, das Fenster sitzt damit gleichmäßig im Rahmen. Unten kommen zu
           den 16px Grundabstand nochmal 12px dazu, damit die Überschrift nicht am Bild
           klebt. */
        margin-top: 0;
        margin-bottom: 0.75rem;
    }

    /* Slide 4 "Perspektive Unterstützer" mobil: Foto deutlich größer als die generische
       190px-Box, bleedet dafür entsprechend über den Rahmen hinaus (von .story-slide__inner
       überflow-hidden sauber beschnitten). */
    .story-slide__media--photo-xl .story-slide__photo {
        height: 230%;
        max-width: none;
        width: auto;
    }

    .story-quote {
        flex-direction: column;
        justify-content: center;
        height: 100%;
        padding: 1.5rem;
        gap: 1rem;
        overflow: hidden;
    }

    .story-quote__stage {
        max-width: 240px;
    }

    /* Slide 5 (Teaser) mobil: Zitat oben, Marker zwischen Zitat und Foto, Foto groß und
       bündig am unteren Rand (gleicher Bleed-Trick wie Slide 1). */
    .story-quote--teaser {
        justify-content: flex-start;
        padding-top: 0.5rem;
        gap: 0.25rem;
    }

    /* Breite MUSS schon VOR dem Herausheben greifen (.story-quote--teaser .story-
       quote__stage, Ancestor-Selektor), da setupTextLayers die Breite per
       getBoundingClientRect() VOR dem Setzen von [data-layer-home] misst und als Inline-
       Style einfriert – ein Selektor über [data-layer-home] käme dafür zu spät (das
       Attribut existiert erst NACH der Messung) und würde nur für Regeln greifen, die
       nach dem Verschieben noch gebraucht werden (Text-Ausrichtung etc.). */
    .story-quote--teaser .story-quote__stage {
        width: 340px;
        max-width: 340px;
    }

    /* Ab hier alle über [data-layer-home="teaser"] statt .story-quote--teaser ...,
       da .story-quote__stage (mit Stern+Zitat) per [data-layer="text"] (setupTextLayers)
       aus .story-quote--teaser herausgehoben wird – der Ancestor-Bezug bricht dann,
       gleiches Prinzip wie bei den anderen Slides (siehe .is-layered-text weiter oben). */
    [data-layer-home="teaser"].story-quote__stage {
        /* Die generische .story-quote__stage{max-width:240px} (siehe oben) bleibt auch
           nach dem Herausheben aktiv (reine Klassen-Regel, kein Ancestor-Bezug nötig) und
           würde die Inline-Breite (340px, siehe Ancestor-Regel oben) sonst wieder auf
           240px zurückstutzen. */
        max-width: 340px;
        /* Kleiner Ausgleich, da Zitat/CTA nach dem Herausheben (setupTextLayers) ca. 5px
           zu weit links landen (vermutlich Sub-Pixel-Differenz durch die Messung vor dem
           Umhängen) – ohne das säße die erste Zeile minimal über den linken Slide-Rand
           hinaus statt sauber am Padding auszurichten. */
        margin-left: 79px;
    }

    /* Der Rechts-Versatz vom Desktop ist mobil kontraproduktiv (nimmt der ohnehin
       schmalen Zeile Breite weg, "– Zitat" würde dadurch erst recht umbrechen). Der
       negative margin-top von Desktop (zieht das Zitat dort absichtlich höher ins Bild)
       muss hier ebenfalls zurückgesetzt werden, sonst rutscht das Zitat mobil hinter die
       Navbar. Genau wie bei der Stage-Breite oben MUSS das über den Ancestor-Selektor
       (VOR dem Herausheben) laufen, nicht über [data-layer-home] – margin/flex-wrap
       beeinflussen die gemessene Größe/Position, [data-layer-home] existiert zu dem
       Zeitpunkt aber noch nicht. */
    .story-quote--teaser .story-quote__stage .story-slide__quote {
        margin-left: 0;
        margin-top: -30px;
        /* Zweizeilig statt dreizeilig auf Wunsch: row+wrap statt column lässt die
           einzelnen Zeilen-Boxen (statt fest je eine pro Reihe) je nach Platz
           nebeneinander stehen und erst bei Bedarf umbrechen. width:100% nötig, da die
           Stage per align-items:flex-start ihre Kinder sonst nur content-breit lässt
           (shrink-to-fit) statt die volle verfügbare Breite fürs Wrapping zu nutzen. */
        flex-direction: row;
        flex-wrap: wrap;
        width: 100%;
        /* Kein Abstand zwischen "Mein Tipp:" und "Glaub an dich." (selbe Zeile), auf
           Wunsch – row-gap bleibt, damit noch Luft zwischen den beiden Zeilen ist. */
        column-gap: 0;
    }

    /* Gleiche Regel nochmal über [data-layer-home] – die Ancestor-Regel oben greift nur
       VOR dem Herausheben (für die korrekte Messung), das Zitat bleibt aber als
       Nachfahre der Stage bestehen, daher matcht [data-layer-home="teaser"] hier
       zuverlässig auch danach. Ohne das würde das Zitat nach dem Umhängen wieder auf
       flex-direction:column (dreizeilig) zurückfallen. */
    [data-layer-home="teaser"] .story-slide__quote {
        margin-left: 0;
        margin-top: -30px;
        flex-direction: row;
        flex-wrap: wrap;
        width: 100%;
        column-gap: 0;
    }

    /* Stern als Hintergrundelement weiter oben und klein genug, dass er das Foto nicht
       erreicht: Die Zitat-Stage hängt (data-layer="text") auf Track-Ebene ÜBER der ganzen
       Slide, ein z-index auf dem Foto innerhalb der Slide kann das nicht durchbrechen.
       Außerdem muss er komplett zwischen die Slide-Kanten passen – ragt er rechts über die
       Stage hinaus, wächst die Scrollbreite des Tracks und hinter der letzten Slide
       erscheint ein leerer Streifen. Beschneiden geht nicht (das Zitat ragt bewusst aus
       derselben Stage heraus), nach links überstehen auch nicht (Stage liegt über der
       Nachbar-Slide). */
    .story-quote__star {
        /* Fester top-Wert (halbe Stage-Höhe der kürzesten Variante): so bleibt der Stern
           auf allen Teaser-Slides an derselben Bildschirmposition, auch wenn ein längeres
           Zitat die Stage höher macht. */
        top: 188.828px;
        width: 112%;
        max-width: 380px;
        left: 50%;
        transform: translate(-50%, calc(-50% - 180px));
    }

    /* So groß wie das Zitat auf Slide 2 (Nachhaltigkeit) – gleicher Wert wie dort. */
    [data-layer-home="teaser"] .story-slide__quote-line {
        font-size: 1.25rem;
    }

    /* CTA "Zur Geschichte von …" mobil: Desktop-Werte (position:absolute, 18% Einzug)
       zurückgesetzt – sitzt hier stattdessen im normalen Textfluss direkt unter dem
       Zitat, gleiche Breite/Ausrichtung wie dieses. */
    [data-layer-home="teaser"] .story-quote__cta {
        position: static;
        margin-left: 0;
        margin-top: calc(16rem + 40px);
    }

    [data-layer-home="teaser"] .story-quote__cta-line {
        font-size: 0.85rem;
    }

    [data-layer-home="teaser"] .story-quote__cta-line--name {
        font-size: 1rem;
    }

    /* Die Zitat-Bühne muss im Flex-Column schrumpfen dürfen, damit das Foto darunter
       (flex: 0 0 auto) bündig mit dem unteren Rand liegt. Das Bleed-Script misst das
       Foto in genau diesem Zustand. Ohne die Angabe entscheidet der Browser über die
       Mindesthöhe der Bühne: Safari rechnete sie 54px größer als Chromium, das Foto
       samt Marker saß dort entsprechend tiefer (390×664). Chromium bleibt unverändert. */
    .story-quote--teaser .story-quote__stage {
        min-height: 0;
    }

    .story-quote--teaser .story-slide__media--photo {
        position: relative;
        flex: 0 0 auto;
        /* Kleiner und rechtsbündig statt volle Breite, auf Wunsch – lässt links Platz für
           Marker + CTA neben ihrem Kopf. align-self statt align-items am Container, da nur
           dieses eine Kind (nicht auch die Zitat-Stage) nach rechts soll. */
        align-self: flex-end;
        /* Höher als TEXT_LAYER_Z (3, siehe .story-quote__stage/setupTextLayers) – der
           große Stern liegt in der Stage und würde sonst über Amys Foto gemalt, sobald
           beide sich überlappen. So bleibt der Stern klar im Hintergrund, auch hinter
           dem Foto (Zitat/CTA überlappen das Foto räumlich ohnehin nicht). */
        z-index: 4;
        /* Breiter statt margin-right größer: bleibt randbündig rechts, wächst nach links. */
        width: 108%;
        margin-left: 0;
        margin-right: -1.5rem;
        margin-bottom: -1.5rem;
        margin-top: 3.25rem;
        height: 350px; /* nicht höher, sonst seitlicher Zuschnitt */
    }

    .story-quote--teaser .story-slide__photo {
        width: 100%;
        height: 150%;
        max-height: none;
        max-width: none;
        object-fit: cover;
        /* Horizontal von center auf 25% – zeigte bislang zu mittig/rechts vom Quellbild,
           wodurch ihr linker Arm am Rand der (schmaleren) Box abgeschnitten wurde. */
        object-position: 25% top;
    }

    .story-quote--teaser .story-slide__label {
        top: calc(-9rem + 70px);
        /* Fixer px-Wert statt % des Fotos, damit die linke Kante exakt mit Zitat/CTA
           übereinstimmt (beide bei 24px vom Slide-Rand) statt relativ zur (variablen)
           Fotobreite zu schweben. */
        left: 3px;
        width: clamp(130px, 42vw, 170px);
    }

    [data-layer-home="nachhaltigkeit"] .story-slide__quote--amy-pride,
    [data-layer-home="teaser"] .story-slide__quote--two-line-mobile {
        flex-direction: column;
        flex-wrap: nowrap;
    }

    .story-quote--teaser .story-slide__quote--three-line-mobile,
    [data-layer-home="teaser"] .story-slide__quote--three-line-mobile {
        flex-direction: column;
        flex-wrap: nowrap;
    }

    .story-quote--teaser .story-slide__quote-first-row-mobile,
    [data-layer-home="teaser"] .story-slide__quote-first-row-mobile {
        display: flex;
        flex-wrap: nowrap;
    }

    .story-slide__icon-pair--intro {
        gap: 0.75rem;
        position: relative;
        left: 40px;
        top: 8px;
    }

    .story-slide__icon-pair--intro img {
        width: 76px;
        height: 76px;
    }

    .story-slide__illustration-pair--large {
        justify-content: center;
        width: 100%;
        gap: 0.75rem;
    }

    .story-slide__illustration-pair--large .story-slide__icon-lg {
        width: min(36vw, 130px);
    }

    .story-slide__icon-pair--floating {
        gap: 0.5rem;
    }

    .story-slide__icon-pair--floating img {
        width: 105px;
        height: 105px;
    }

    /* Kevins Tor (Slide 4) überdeckte die Gesichter von Mutter und Tochter - weiter
       nach links, ragt dafür stärker in Slide 3 (01.09.2026). Auf .is-bleeding
       gescoped, damit der Versatz nicht doppelt in die Bleed-Messung einfließt. */
    .is-bleeding.story-slide__icon--kevin-goal {
        translate: -55px 8px;
    }
}

/* ── Gekürzter Slide-Text auf dem Handy (Slide 3, seit 11.09.2026) ──
   Damit die Galerie auf jedem Handy sichtbar bleibt, endet der Absatz nach dem
   sichtbaren Teil mit „…“; der Rest steckt im HTML in einem span und wird von
   story-page.js ins „mehr erfahren“-Modal übernommen – zusammen mit einem Klon der
   Galerie. Der Schnitt sitzt im Markup (immer am Satzende), nicht in einer
   Zeichenzahl: CSS kann keine Zeichen zählen, und das Modal muss wissen, wo es
   weitergeht. Bewusst nur bis 640px, nicht bis 1024px wie der Strukturblock oben:
   Auf dem Tablet reicht der Platz für den ganzen Text. ── */
@media (max-width: 640px) {
    .story-slide__excerpt-rest {
        display: none;
    }

    .story-slide__excerpt::after {
        content: " …";
    }

    .story-slide__more--excerpt-only {
        display: inline-flex;
    }
}

/* ── Reduzierter Modus: niedrige Viewports (mobil, unter 750px Höhe) ──
   Auf kleinen Handys reicht die Typo-Skalierung allein nicht. Hier rücken die
   Deko-Ebenen zusammen: Die kleinen Slide-1-Illus werden ausgeblendet, die großen
   Illus auf Slide 2 und 4 bleiben sichtbar und werden auf 0.9 verkleinert, die
   Foto-Galerie auf Slide 3 bleibt – außer bei den vier Kindern mit zu langem Text
   (Connor, Lilly, Maja, Willi). Text, Zitate, Hero-Foto und Familienfoto bleiben.
   Grenze: bei 750px Höhe gilt noch die normale Ansicht, erst darunter der
   reduzierte Modus (Wunsch des Nutzers, 31.08./01.09.2026). Bewusst in Kauf
   genommen: ein iPhone 14 (664px mit / 750px ohne Safari-Leiste) wechselt damit
   beim Ein-/Ausfahren der Leiste den Modus. ── */
@media (max-width: 640px) and (max-height: 749px) {
    .story-slide__icon:not(.story-slide__icon--float) {
        display: none;
    }

    /* Slide-4-Illus (--float, z.B. Jans Pokal) bleiben seit 01.09.2026 sichtbar und
       werden wie die Slide-2-Illus auf 0.9 verkleinert. Origin unten links: Ankerpunkt
       bleibt, der Bleed-Überhang in den Vorgänger-Slide und der Stand am unteren Rand
       gehen beim Skalieren nicht verloren. */
    .story-slide__icon--float {
        scale: 0.9;
        transform-origin: 0% 100%;
    }

    /* Jans Pokal etwas höher (Wunsch 01.09.2026). Auf .is-bleeding gescoped: Die Klasse
       existiert erst NACH der Positionsmessung des Bleed-Scripts, der Versatz fließt
       also nicht doppelt ein. */
    .is-bleeding.story-slide__icon--float {
        translate: 0 -20px;
    }

    /* Connors Matte berührte das Gesicht des linken Jungen - etwas nach links
       (y-Anteil = die -20px der Grundregel oben, translate überschreibt komplett). */
    .is-bleeding.story-slide__icon--connor-matte {
        translate: 0 -20px;
    }

    /* Kevins Tor: reduziert gilt derselbe Links-Versatz, plus die -20px nach oben
       aus der Float-Grundregel. */
    .is-bleeding.story-slide__icon--kevin-goal {
        translate: -55px -12px;
    }

    /* Majas Anhänger-Illu berührte das Ohr des Vaters - etwas nach links. */
    .is-bleeding.story-slide__icon--maja-helmet {
        translate: -20px -20px;
    }

    /* Willis I-love-NY bleibt links neben dem Haar des Vaters. */
    .is-bleeding.story-slide__icon--willi-iloveny {
        translate: -7px -20px;
    }

    /* Jans Familienfoto: etwas kleiner als die Mobil-Grundregel (1.1) und ebenfalls
       nach rechts (Wunsch 01.09.2026). Origin unten: bleibt bündig mit der Unterkante,
       statt beim Schrumpfen einen Spalt zum Slide-Rand zu reißen. */
    #perspektive-unterstuetzer .story-slide__media--photo-xl .story-slide__photo--jan-supporter {
        /* 0.9 statt 1: Kopf ragte bei 650px Höhe noch in die letzte Textzeile
           (Wunsch 01.09.2026). */
        transform: translateX(18px) scale(0.9);
        transform-origin: bottom center;
    }

    /* Amys Familienfoto (4 Personen): Köpfe ragten in "mehr erfahren" - wie bei Jan
       auf 0.9 verkleinert (0.95 reichte nicht, der Vater links ist der höchste Kopf),
       unten verankert. */
    #perspektive-unterstuetzer .story-slide__media--photo-xl .story-slide__photo--amy-supporter {
        transform: scale(0.9);
        transform-origin: bottom center;
    }
    /* Die Slide-3-Galerie bleibt auch im reduzierten Modus sichtbar - ihre Größe
       regelt die generische Mobil-Formel (max-height mit 100svh) weiter oben. Bis
       11.09.2026 flog sie bei Connor, Lilly, Maja und Willi raus (Text zu lang);
       seitdem wird der Text auf dem Handy gekürzt (.story-slide__excerpt, Rest im
       Modal) und die Galerie bleibt überall – Maja über einen Handy-Button
       (.story-slide__more--excerpt-only), weil die Slide keinen Modal-Text hat. */

    /* Die große Slide-2-Illu (icon-lg) bleibt sichtbar, wird aber verkleinert (Wunsch
       des Nutzers, 01.09.2026 - vorher komplett ausgeblendet). scale statt width, weil
       das Bleed-Script Position/Maße einmalig als Inline-Styles einfriert und
       transform von der Schwebe-Animation belegt ist. */
    .story-slide__icon-lg {
        scale: 0.9;
    }

    .story-slide__illustration-pair--large {
        scale: 0.7;
    }

    /* Beim Verkleinern um den Mittelpunkt wanderte die rechte Kante zurück und der
       gewollte Bleed-Überhang in den Folge-Slide (z.B. Jans Rollstuhl auf Slide 3)
       verschwand fast ganz. Origin rechts: die rechte Kante bleibt beim Skalieren
       stehen, der Überhang bleibt erhalten. Gilt nur für herausgehobene
       Bleed-Illus (alle Slide-2-Illus haben data-bleed="next"). */
    .is-bleeding.story-slide__icon-lg,
    .is-bleeding.story-slide__illustration-pair--large {
        transform-origin: 100% 50%;
    }

    .is-bleeding.story-slide__icon-lg {
        translate: 15px -20px;
    }

    .is-bleeding.story-slide__illustration-pair--large {
        translate: 15px -50px;
    }

    /* Amys Filmklappe zusätzlich höher als der generische Wert (Wunsch 01.09.2026) -
       eigene Regel statt Stacking, translate wird von der zweiten Deklaration ersetzt
       statt addiert. */
    .is-bleeding.story-slide__icon-lg--amy-filmklappe {
        translate: 15px -45px;
    }

    /* Teaser-Slide (5): Bei wenig Höhe rückt alles zusammen (Wunsch 01.09.2026) -
       Foto des nächsten Kindes kleiner (Anker unten rechts: bleibt rand- und
       unterkantenbündig), Traum-Marker etwas tiefer, CTA "Zur Geschichte von" etwas
       höher. translate statt top-Overrides, damit die per-Kind-Marker-Positionen
       (--teaser-ben usw.) unangetastet bleiben. */
    .story-quote--teaser .story-slide__photo {
        scale: 0.9;
        transform-origin: 100% 100%;
    }

    .story-quote--teaser .story-slide__label {
        translate: 0 60px;
    }

    /* Das Ben+Luisa-Teaserfoto (Paar, hoeher als Einzelportraets) staerker verkleinern,
       sonst steht der CTA auf Bens Gesicht. */
    .story-quote--teaser .story-slide__photo--ben-luisa-teaser {
        scale: 0.82;
    }

    [data-layer-home="teaser"] .story-quote__cta {
        translate: 0 -60px;
    }

    /* Der Stern soll HINTER dem Foto liegen (Wunsch 01.09.2026), Position unverändert.
       Die Text-Ebene (Stage, z-index 3) schwebt aber über dem ganzen Slide (z 0) -
       innerhalb des Slides kann kein Foto-z-index sie überdecken. Deshalb: Stern in
       der Stage ausblenden und an exakt derselben Position (gemessen: zentriert,
       -28px, 380x250) als Hintergrundbild des Slides zeichnen - das liegt unter
       Foto und Marker. */
    .story-quote--teaser .story-quote__star,
    [data-layer-home="teaser"] .story-quote__star {
        display: none;
    }

    #teaser {
        background: url(../img/hero_star.svg) no-repeat center -28px / 380px 250px, var(--gradient-dark);
    }


    /* Das Slide-2-Zitat wandert im reduzierten Modus zusammen mit der Illu 20px nach
       oben. Selektor greift erst nach dem Herausheben (data-layer-home wird von
       setupTextLayers gesetzt) - die Positionsmessung lief da schon, kein
       Doppel-Versatz. */
    [data-layer-home="nachhaltigkeit"].story-slide__media {
        translate: 0 -20px;
    }

    /* Amys Zitat zusätzlich höher (Wunsch 01.09.2026) - eigene Regel statt Stacking,
       da translate von der zweiten Deklaration ersetzt statt addiert wird. Trifft nur
       den Container mit Amys Zitat-Klasse, andere Kinder bleiben bei -20px. */
    [data-layer-home="nachhaltigkeit"].story-slide__media:has(.story-slide__quote--amy-pride) {
        translate: 0 -40px;
    }

    /* Die Paar-Illus (Ben/Luisa) tragen selbst .story-slide__icon-lg - der Container
       ist schon verkleinert, sonst würden sie doppelt schrumpfen. */
    .story-slide__illustration-pair--large .story-slide__icon-lg {
        scale: none;
    }

    /* Löwenbaby (Ben+Luisa, Slide 5) reduziert: unter dem Text ist kein Platz mehr -
       stattdessen nach rechts oben in die freie Fläche neben die Köpfe. */
    .story-slide__icon-pair--floating .story-slide__paired-illu--loewe {
        translate: 210px -150px;
        scale: 0.85;
        transform-origin: center;
    }

    /* Ohne die Illu oben rechts darf die Headline nicht mehr daneben gezogen werden
       (negativer Margin würde sie unter die Navbar schieben) und braucht auch keinen
       Freiraum rechts. */
    .story-slide__inner--intro .story-slide__heading,
    [data-layer-home="landingpage"].story-slide__text .story-slide__heading,
    .story-slide__text:has(.story-slide__icon-pair--intro) .story-slide__heading,
    .story-slide__text:has(.story-slide__icon-image--mathea-dog) .story-slide__heading {
        margin-top: 0;
        padding-right: 0;
    }

    /* Einheitlicher Abstand zur Logo-Bar: 24px auf allen Text-Slides (abgestimmt
       01.09.2026; 48px und 36px waren dem Nutzer zu viel). Slides 2-4 stehen von Haus
       aus bei 24px, nur Slide 1 (8px) braucht Ausgleich. padding-top statt margin-top,
       weil das Ebenen-Layout (setupTextLayers) die Container-Position einmalig misst
       und als inline top übernimmt - ein Margin würde nach dem Umhängen doppelt
       wirken, Padding verschiebt nur den Inhalt im Container. */
    #landingpage .story-slide__text,
    [data-layer-home="landingpage"].story-slide__text {
        padding-top: 16px;
    }
}

/* ── Normale mobile Ansicht: Komplement zum reduzierten Modus oben (ab 750px Höhe) ──
   Anpassungen, die NUR in der normalen (nicht reduzierten) mobilen Ansicht gelten
   sollen - Gegenstück zu @media (...) and (max-height: 749px). ── */
@media (max-width: 640px) and (min-height: 750px) {
    /* Amys Filmklappe etwas weiter nach rechts, damit sie sichtbarer in Slide 3
       hineinragt (Wunsch 01.09.2026). Nur hier (nicht reduziert), da die Illu dort
       schon einen eigenen, größeren Versatz per translate bekommt (siehe oben). */
    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--amy-filmklappe {
        left: 10px;
    }
}

/* ── 6. Startseite: Hero (nutzt .slide__inner / .slide__col für den Inhalt) ── */
.hero {
    height: calc(100vh - var(--navbar-height));
    height: calc(100svh - var(--navbar-height));
    background: var(--gradient-blue);
    position: relative;
    overflow: hidden;
}

/* Scroll-Hinweis rechts neben der Bildunterschrift – bewusst dasselbe runde
   Button-Element (.story-jump__arrow) wie die Sticky-Nav-Pfeile auf den
   Story-Seiten, damit es als bereits bekanntes UI-Element wiedererkannt wird statt
   ein neues zu erfinden. "Wähle eine Geschichte" liest sich dadurch zugleich als
   Erklärung für den Klick auf den Button. */
.hero__scroll-hint {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
}

.hero__scroll-hint svg {
    width: 16px;
    height: 16px;
}

/* Linke Spalte: Headline + Stern-Silhouette im Hintergrund, kein eigener Kasten-Hintergrund.
   padding-bottom verschiebt die (vertikal zentrierte) Headline etwas nach oben. */
.hero__headline-col {
    justify-content: flex-end;
    padding-bottom: 5rem;
}

.hero__headline {
    position: relative;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

/* Größer als die Spalte selbst und leicht nach rechts versetzt, damit sie bewusst
   überlappt (mit der Headline und Richtung Kartenstapel) statt sauber eingepasst zu sein. */
.hero__star {
    position: absolute;
    top: 50%;
    left: 62%;
    width: 230%;
    max-width: 1060px;
    height: auto;
    /* 40px tiefer als die reine vertikale Zentrierung (Desktop); Mobil bleibt bei 20px,
       siehe Override in der Mobile Media Query weiter unten. */
    transform: translate(-50%, calc(-50% + 40px));
    pointer-events: none;
}

.hero__title {
    position: relative;
    width: 100%;
    text-align: right;
    /* 4.5vw statt 5vw: Der Deckel von 4rem griff ab 1280px, dort braucht „beginnt mit
       Dir." aber 641px und der Block bietet nur 592px (1366px: 635px) – die Zeile brach
       innerhalb ihres weißen Kastens um. Mit 4.5vw greift der Deckel erst ab 1422px;
       darunter skaliert die Schrift mit der Blockbreite, ab 1440px ändert sich nichts. */
    font-size: clamp(1.7rem, 4.5vw, 4rem);
    font-weight: 700;
    line-height: 1.25;
    text-transform: uppercase;
    color: var(--color-blue);
}

.hero__title span {
    display: table;
    margin-left: auto;
    background-color: #fff;
    /* Padding bewusst asymmetrisch: Versalien ohne Unterlängen lassen unterhalb der
       Grundlinie durch die Schriftmetriken (Descent) mehr Leerraum als oberhalb, auch bei
       line-height:1. Mehr Padding oben gleicht das optisch aus, damit der Text im weißen
       Kasten wirklich zentriert wirkt statt nur rechnerisch. */
    padding: 0.20em 0.35em 0.02em;
    line-height: 0.9;
}

.hero__title span + span {
    margin-top: 0.15em;
}

/* Mobil: Headline größer (eigener, höherer Mindestwert statt vw-gebremstem Clamp-Minimum)
   und Stern kleiner, da er sonst den kompletten Viewport dominiert. Obergrenze per Messung
   bestimmt (letzter Wert, bei dem "beginnt mit Dir." in Futura noch einzeilig bleibt). */
@media (max-width: 1024px) {
    /* Navbar mobil niedriger, Logo deutlich kleiner, Claim etwas größer – am Desktop
       dominierte das Logo bislang die Bar, im Verhältnis zum (jetzt einzigen) Claim. */
    :root {
        --navbar-height: 88px;
    }

    .navbar__logo-img {
        height: 56px;
    }

    .hero__title {
        font-size: clamp(1.71rem, 7.6vw, 2rem); /* −5 % */
        line-height: 1.19;
    }

    .hero__star {
        width: 160%;
        max-width: 460px;
        transform: translate(-50%, calc(-50% + 20px));
    }

    /* Claim mobil größer als zuvor, zweizeilig; Ein-/Ausblenden per Scroll siehe JS + body.home
       (dort auch die 25%-Schwelle für Mobil vs. 50% für Desktop). */
    .navbar__claim {
        font-size: 1rem;
        text-align: right;
    }

    .navbar__claim-line2 {
        display: block;
    }

    /* Etwas Luft für die Headline über dem Kartenstapel (dessen mobile Größe steht
       weiter unten bei .swap-stack, nach der Basisregel). */
    .hero__headline-col {
        padding: 1rem 0;
    }

    /* Button-Text auf den Card-CTAs mobil kleiner, damit "Geschichte lesen" einzeilig bleibt
       (0.83rem war die per Messung ermittelte Wrap-Grenze bei der mobilen Card-Breite). */
    /* Höhere Spezifität nötig: die Basisregel .swap-card__link steht später in der Datei
       und würde sonst gewinnen (der Mobilwert griff bislang gar nicht). */
    .swap-card .swap-card__link {
        font-size: 0.7rem;
    }
}

/* Bildunterschrift unter dem Kartenstapel */
.slide__col--cards {
    flex-direction: column;
    gap: 4.5rem;
}

/* Abstand zur Bildunterschrift mobil kleiner, damit der Kartenstapel wachsen kann. */
@media (max-width: 1024px) {
    .slide__col--cards {
        gap: 3rem;
    }
}

.hero__cards-caption {
    width: min(60vw, 340px);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    color: #fff;
}

.hero__cards-caption strong {
    display: block;
    font-size: 1.15rem;
    font-weight: 700;
}

.hero__cards-caption span {
    display: block;
    font-size: 0.95rem;
    opacity: 0.85;
}

/* ── Geschichten-Übersicht (Startseite) ── */
.stories {
    max-width: 1200px;
    margin: 0 auto;
    padding: 4rem 2rem;
}

.stories__title {
    font-size: 1.25rem;
    font-weight: 700;
    margin-top: 3.5rem;
    margin-bottom: 0.5rem;
}

/* Standard-YouTube-Embed mit allen nativen Bedienelementen (Play-Button, Fortschritt,
   Lautstärke, Vollbild, ...) statt einer eigenen Vorschau/Facade – das feste
   width/height="560"/"315" aus dem YouTube-Einbettungscode wird hier durch
   aspect-ratio + width:100% ersetzt, damit der Player die volle Breite der
   .stories-Spalte einnimmt und dabei im 16:9-Format bleibt. */
.stories__video {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 0;
    border-radius: 12px;
    margin: 0 auto 3.5rem;
}

.stories__subtitle {
    font-size: 1.75rem;
    font-weight: 700;
    margin-bottom: 1.5rem;
    /* html{scroll-padding-top} gleicht bereits exakt die Navbar-Höhe aus, wodurch die
       Headline beim Sprung direkt an der Navbar klebt – zusätzlicher Luftraum obendrauf
       (addiert sich zum scroll-padding-top, daher hier nur der Extra-Abstand). */
    scroll-margin-top: 3rem;
}

.stories__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 2rem 1.5rem;
}

@media (max-width: 900px) {
    .stories__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 520px) {
    .stories__grid { grid-template-columns: 1fr; }
}

/* Klassisches Testimonial-Layout statt Link-Liste: das Zitat steht groß oben als
   eigentlicher emotionaler Aufhänger, der Name darunter ist nur noch die kleine
   Signatur – näher an "Zeugnis/Statement" als an "Navigationspunkt". Eigener
   Hintergrund/Padding (statt nur nackter Text), damit die Karte als Ganzes wie eine
   anklickbare Einheit wirkt, nicht wie eine reine Textzeile in einer Liste. */
/* .story-card ist nur noch der Perspective-Container (für den 3D-Tilt unten nötig,
   siehe .story-card__surface) – Hintergrund/Padding/Rundung liegen jetzt auf der
   __surface, da die eigentliche rotateX/rotateY-Transform auf einem KIND von
   perspective sitzen muss, sonst hat perspective keine Wirkung. */
.story-card {
    display: block;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    perspective: 800px;
}

.story-card__surface {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 1.5rem;
    border-radius: 16px;
    background: #f6f6f4;
    transition: background 0.2s ease, transform 0.15s ease-out, box-shadow 0.2s ease;
    will-change: transform;
}

.story-card:hover .story-card__surface {
    background: var(--color-blue);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.15);
}

.story-card:hover .story-card__quote {
    color: #fff;
}

.story-card:hover .story-card__name {
    color: var(--color-yellow);
}

/* Illustration schneidet unten rechts an – bleedet bewusst über den Kartenrand
   hinaus (overflow:hidden auf __surface kappt sie), damit es wie ein angeschnittenes
   Grafikelement wirkt statt wie ein sauber freigestelltes Icon. Bewegt sich beim
   Hover per JS stärker als der Kartenrahmen selbst (siehe home.js) – erzeugt so
   den Parallax-Eindruck einer eigenen, dahinterliegenden Ebene. */
.story-card__illu-wrap {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
}

.story-card__illu {
    position: absolute;
    right: -28px;
    bottom: -28px;
    width: 110px;
    height: auto;
    opacity: 1;
    transition: transform 0.15s ease-out;
}

/* Amy-Preview: Kamera weiter in die Karte hinein und etwas höher positionieren. */
.story-card__illu--amy {
    right: -12px;
    bottom: -10px;
    rotate: 5deg;
}

/* Gemeinsame Vorschau: Elefant und T-Shirt bilden rechts ein enges Illustrationspaar;
   beide Motive bleiben unabhängig positionier- und drehbar. */
.story-card__illu--ben-luisa-elefant {
    right: -34px;
    bottom: -22px;
    width: 102px;
    rotate: 20deg;
}

.story-card__illu--ben-luisa-tshirt {
    right: 57px;
    bottom: -22px;
    width: 96px;
    rotate: 5deg;
}

/* Kleinere Vorschauillustrationen: weit genug innerhalb der Karte, um erkennbar zu
   bleiben, aber kompakt genug, damit die Motive den Text nicht bedrängen. */
.story-card__illu--child-preview {
    right: -10px;
    bottom: -10px;
    width: 92px;
}

.story-card__illu--preview-lower {
    right: -5px;
    bottom: -33px;
}

.story-card__illu--homepage-ball {
    bottom: -38px;
}

.story-card__illu--connor-ball {
    bottom: -43px;
    rotate: -10deg;
}

.story-card__illu--preview-lilly {
    bottom: -28px;
}

.story-card__illu--preview-maja {
    rotate: 10deg;
}

.story-card__illu--preview-mathea {
    right: -20px;
    bottom: -30px;
}

@media (max-width: 640px) {
    .story-card__illu--amy {
        right: -3px;
        bottom: -21px;
        width: 102px;
        rotate: -5deg;
    }

    .story-card__illu--ben-luisa-elefant {
        right: -28px;
        bottom: -28px;
        width: 110px;
        rotate: 5deg;
    }

    .story-card__illu--ben-luisa-tshirt {
        right: 77px;
        bottom: -63px;
        width: 110px;
        rotate: 0deg;
    }

    .story-card__illu--homepage-ball {
        bottom: -28px;
        rotate: 0deg;
    }

    .story-card__illu--connor-ball {
        bottom: -58px;
        rotate: 0deg;
    }

    .story-card__illu--preview-lilly {
        right: -33px;
        bottom: -50px;
        width: 104.5px;
    }

    .story-card__illu--preview-maja {
        rotate: 0deg;
    }

    .story-card__illu--preview-mathea {
        right: -15px;
        bottom: -50px;
    }

    .story-card__illu--preview-lower {
        right: 5px;
        bottom: -13px;
    }
}

/* Kindspezifische Feinjustierung mobil: Desktop-Pixelkorrekturen zurücksetzen und
   je Kind eigene mobile Positionen setzen. */
@media (max-width: 640px) {
    .story-slide__icon--intro .story-slide__icon-image--lilly-haarband,
    .story-slide__icon--intro .story-slide__icon-image--willi-flagge {
        width: 72px;
        height: 72px;
    }

    .story-slide__icon--mathea-paw img {
        left: 0;
        top: -25px;
        rotate: 0deg;
    }

    .story-slide__icon--amy-landing img {
        width: 72px;
        height: 72px;
        translate: 6px -6px;
        rotate: 8deg;
    }

    .story-slide__icon-lg--amy-filmklappe,
    .story-slide__icon-lg.story-slide__icon-lg--connor-gelaender,
    .story-slide__icon-lg--maja-fahrrad,
    .story-slide__icon-lg--mathea-halsband,
    .story-slide__icon-lg--willi-esb,
    .story-slide__paired-illu--tshirt {
        top: 0;
    }

    .story-slide__paired-illu--elefant,
    .story-slide__paired-illu--tshirt {
        rotate: 0deg;
    }

    .story-slide__photo--kevin-teaser,
    .story-slide__photo--jan-teaser,
    .story-slide__photo--lilly-supporter,
    .story-slide__photo--maja-supporter,
    .story-slide__media--photo-xl .story-slide__photo--amy-supporter,
    .story-slide__media--photo-xl .story-slide__photo--ben-luisa-supporter,
    .story-slide__media--photo-xl .story-slide__photo--connor-supporter,
    .story-slide__media--photo-xl .story-slide__photo--kevin-supporter,
    .story-slide__media--photo-xl .story-slide__photo--mathea-supporter,
    .story-slide__media--photo-xl .story-slide__photo--willi-supporter {
        left: 0;
    }

    .is-bleeding .story-slide__label--hero-ben {
        top: 6%;
        left: 2%;
    }

    .is-bleeding .story-slide__label--hero-luisa {
        top: calc(6% - 40px);
        right: calc(2% + 268px);
        left: auto;
    }

    .story-slide__label--hero-luisa-desktop {
        display: none;
    }

    .story-slide__label--hero-luisa-mobile {
        display: block;
    }

    .story-quote--teaser .story-slide__label--teaser-ben {
        top: calc(-9rem + 70px);
        left: 3px;
    }

    .story-quote--teaser .story-slide__label--teaser-luisa {
        top: calc(-9rem + 70px);
        right: 3px;
        left: auto;
    }

    .story-quote--teaser .story-slide__label--teaser-connor,
    .story-quote--teaser .story-slide__label--teaser-lilly,
    .story-quote--teaser .story-slide__label--teaser-mathea {
        left: 3px;
    }

    /* Slide-2-Illus mobil je Kind: kleiner (der data-bleed-Überhang in den nächsten
       Slide bleibt); top wird vom Bleed-Script mitgemessen und gilt daher nur einmal. */
    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--amy-filmklappe {
        width: 225px;
        /* Etwas nach oben (Wunsch 01.09.2026) - position:relative statt der
           Bleed-Inline-Styles, da das Bleed-Script diese Position vor dem Aushängen
           einmalig misst (siehe Kommentar oben). Gilt für normale UND reduzierte
           mobile Ansicht, da beide innerhalb dieser max-width:640px-Regel liegen. */
        position: relative;
        top: -20px;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--kevin-tshirt {
        width: 215px;
        position: relative;
        left: -10px;
        top: -30px;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--maja-fahrrad {
        width: 215px;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--lilly-schloss {
        width: 204px;
        position: relative;
        top: -33px;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--willi-esb {
        width: 200px;
        position: relative;
        top: -30px;
    }

    /* Connor und Mathea: Zitat auf Slide 2 etwas tiefer (Basis: 3rem in der
       [data-layer-home="nachhaltigkeit"]-Regel weiter oben). Mehr als 3.3rem geht nicht,
       sonst rutscht die Namenszeile hinter die Sticky-Navigation (beginnt bei y≈596). */
    [data-layer-home="nachhaltigkeit"] .story-slide__quote--connor-s2,
    [data-layer-home="nachhaltigkeit"] .story-slide__quote--mathea-s2 {
        margin-top: 3.3rem;
    }

    /* Lilly und Willi: Zitat auf Slide 2 etwas höher. */
    [data-layer-home="nachhaltigkeit"] .story-slide__quote--lilly-s2,
    [data-layer-home="nachhaltigkeit"] .story-slide__quote--willi-s2 {
        margin-top: 1.5rem;
    }

    /* Amy, Slide 4: Die Filmrolle soll auf kleinen Bildschirmen früher in den
       folgenden Abschnitt hineinragen. */
    .story-slide__icon--amy-floating {
        bottom: -190px;
    }

    .story-slide__icon--connor-matte {
        bottom: -170px;
    }

    .story-slide__icon--kevin-goal {
        bottom: -160px;
    }

    /* Kevin, Slide 4: Tor in beiden Mobilmodi etwas kleiner; die vertikale
       Verschiebung sitzt auf dem Bleed-Element weiter oben. */
    .story-slide__icon--kevin-goal img {
        scale: 0.92;
        transform-origin: 0% 100%;
    }

    .story-slide__icon--maja-helmet {
        bottom: -190px;
    }

    .story-slide__icon--lilly-fairy {
        bottom: -220px;
        left: -70px;
    }

    /* Slide 4: Familienfotos unter dem Text etwas tiefer. Amy, Connor und Kevin
       zusätzlich 8 % kleiner; die separate scale-Eigenschaft ergänzt die bereits
       vorhandenen Normal-/Reduziert-Transforms, statt sie zu überschreiben. */
    #perspektive-unterstuetzer .story-slide__photo--amy-supporter {
        translate: 0 8px;
        scale: 0.92;
        transform-origin: bottom center;
    }

    #perspektive-unterstuetzer .story-slide__photo--connor-supporter {
        translate: 10px 0;
        scale: 0.75;
        transform-origin: bottom center;
    }

    #perspektive-unterstuetzer .story-slide__photo--lilly-supporter {
        translate: 35px 8px;
        scale: 0.85;
        transform-origin: bottom center;
    }

    .story-quote--teaser .story-slide__photo--lilly-teaser {
        translate: 23px 0;
    }

    .story-quote--teaser .story-slide__photo--mathea-teaser {
        translate: 13px 0;
    }

    .story-slide__label--kevin-teaser,
    .story-quote--teaser .story-slide__label--teaser-mathea {
        z-index: 5;
    }

    /* Slide-1-Illus mobil, Feinjustierung je Kind (translate/rotate als eigene
       Eigenschaften, damit die Schwebe-Animation auf transform unberührt bleibt). */
    .story-slide__icon-image--kevin-ball {
        translate: 10px 0;
    }

    .story-slide__icon-image--lilly-haarband {
        rotate: 8deg;
    }

    /* Ben und Luisa, Slide 2: Der sichtbare Schuh liegt im SVG weiter rechts als
       dessen Box. Der Linksversatz richtet ihn unter der Attribution aus; top sorgt
       für Abstand statt einer Überlagerung. */
    .story-slide__paired-illu--turnschuhe {
        top: 50px;
        left: 0;
        order: 2;
    }

    .story-slide__paired-illu--giraffe {
        position: relative;
        top: -30px;
        left: 25px;
        order: 1;
    }

    /* Mathea, Slide 4: Die Pfote ragt leicht in Slide 3; das Familienfoto nutzt
       statt der schmalen rechten Ecke die komplette mobile Seitenbreite. */
    .story-slide__icon--mathea-paw {
        left: -50px;
        rotate: 10deg;
    }

    #perspektive-unterstuetzer .story-slide__media--mathea-supporter {
        width: calc(100% + 3rem);
        margin-right: -1.5rem;
        margin-left: -1.5rem;
    }

    #perspektive-unterstuetzer .story-slide__media--mathea-supporter .story-slide__photo--mathea-supporter {
        width: auto;
        height: 135%; /* war 165 % vor dem Beschnitt der Datei (×1128/1376) */
        margin-left: 0;
        transform: none;
    }

    /* Willi: mobile Einzelkorrekturen fuer das Titelmotiv und den
       Unterstuetzer-Abschnitt, ohne die gemeinsamen Story-Regeln zu veraendern. */
    .story-slide__photo--willi-hero {
        position: relative;
        top: 5px;
        left: 5px;
        scale: 0.95;
    }

    .story-slide__icon--willi-iloveny {
        bottom: -175px;
        scale: 0.9;
        left: -50px;
    }

    #perspektive-unterstuetzer .story-slide__media--willi-supporter {
        width: calc(100% + 3rem);
        margin-right: -1.5rem;
        margin-left: -1.5rem;
        align-items: flex-end;
        justify-content: center;
    }

    #perspektive-unterstuetzer .story-slide__media--willi-supporter .story-slide__photo--willi-supporter {
        position: relative;
        top: 0;
        width: auto;
        height: 125%; /* war 188.5 % vor dem Beschnitt der Datei (×913/1376) */
        margin-left: 0;
        transform: none;
    }

    /* Ben und Luisa, Slide 5: Beide Motive ragen höher in den Abschnitt; ihre
       gegenläufigen Drehungen bleiben auf die mobile Ansicht beschränkt. */
    .story-slide__paired-illu--feld {
        top: -50px;
        rotate: -5deg;
    }

    .story-slide__paired-illu--loewe {
        top: -40px;
        left: 0;
        rotate: 5deg;
    }

    /* Ben und Luisa, Slide 5: Das Freistellerfoto nutzt die gesamte Bildschirmbreite.
       Die negativen Margins gleichen das 24px-Innenpadding der Slide aus. */
    #perspektive-unterstuetzer .story-slide__media--ben-luisa-supporter {
        width: calc(100% + 3rem);
        margin-right: -1.5rem;
        margin-left: -1.5rem;
    }

    #perspektive-unterstuetzer .story-slide__media--ben-luisa-supporter .story-slide__photo--ben-luisa-supporter {
        width: 100%;
        height: auto;
        margin-left: 0;
        transform: none;
    }

    /* Amy, Slide 5: Das gesamte Teaserbild bleibt horizontal sichtbar und reicht
       trotz des Innenabstands der Section bis an beide Bildschirmkanten. */
    .story-quote--amy-next .story-slide__media--photo {
        width: calc(100% + 3rem);
        margin-right: -1.5rem;
        margin-left: -1.5rem;
    }

    .story-quote--amy-next .story-slide__photo {
        width: 100%;
        height: 100%;
        object-fit: contain;
        object-position: center bottom;
    }

    .story-quote--amy-next .story-slide__label--teaser-ben {
        top: calc(-9rem + 30px);
        left: 1.5rem;
    }

    .story-quote--amy-next .story-slide__label--teaser-luisa {
        top: calc(-9rem + 30px);
        right: 1.5rem;
        left: auto;
    }

    [data-layer-home="teaser"] .story-quote__cta--amy-next {
        transform: translateY(20px); /* -40 → 20: tiefer (Wunsch 11.09.2026); Deckel für
                                        sehr niedrige Displays direkt nach diesem Block */
    }

}

/* Glanzlicht folgt dem Cursor – gleiches Prinzip wie .swap-card__shine/
   .story-slide__shine (radialer Verlauf an --mx/--my, per JS beim mousemove
   gesetzt, siehe home.js). */
.story-card__shine {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.25s ease;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.28), transparent 75%);
    mix-blend-mode: overlay;
}

.story-card:hover .story-card__shine {
    opacity: 1;
}

.story-card__quote,
.story-card__name {
    position: relative;
    z-index: 1;
}

/* Echtes Zitat, keine Kursivschrift – gedeckte Farbe statt Link-Blau signalisiert
   "Aussage", nicht "hier klicken". Die deutschen Anführungszeichen stehen direkt
   im Markup (gleiche Konvention wie bei den Zitaten auf den Story-Slides). */
.story-card__quote {
    font-size: 1rem;
    line-height: 1.45;
    color: #333;
    transition: color 0.2s ease;
}

/* Name + Pfeil als kleine Signatur. Der Pfeil ist der einzige CTA der ganzen Karte
   (ersetzt ein 10x wiederholtes "mehr lesen") und bleibt dezent, bis man über die
   Karte hovert – dann rutscht er sichtbar nach. Auf Touch-Geräten gibt es kein
   Hover, dort bleibt er dauerhaft sichtbar (siehe Media Query unten), sonst gäbe es
   dort gar keinen CTA-Hinweis mehr. */
.story-card__name {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--color-blue);
    transition: color 0.2s ease;
}

.story-card__arrow {
    width: 12px;
    height: 12px;
    stroke-width: 3.4;
    flex-shrink: 0;
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.story-card:hover .story-card__arrow {
    opacity: 1;
    transform: translateX(0);
}

@media (hover: none) {
    .story-card__arrow {
        opacity: 1;
        transform: none;
    }
}

/* ── Kartenstapel (Swap-Stack) ── */
.swap-stack {
    position: relative;
    width: min(60vw, 340px);
    aspect-ratio: 9 / 16;
    max-height: 78vh;
    cursor: pointer;
}

/* Kleiner auf Mobil, damit die Headline darüber mehr Platz bekommt. */
@media (max-width: 1024px) {
    .swap-stack {
        width: min(54vw, 290px);
    }
}

/* Reduzierter Modus (niedrige Höhe, siehe die Story-Slide-Regeln bei max-height:749px):
   Der Kartenstapel + Bildunterschrift ("Erfüllte Träume") ragten sonst unten aus dem
   Hero heraus und wurden vom overflow:hidden abgeschnitten - CTA war unsichtbar
   (Wunsch 01.09.2026). Karten kleiner, Abstände gestrafft. */
@media (max-width: 640px) and (max-height: 749px) {
    .swap-stack {
        width: min(40vw, 175px);
    }

    /* Die reduzierte Karte ist deutlich schmaler als in der normalen Mobilansicht.
       CTA relativ verbreitern und Schrift leicht verkleinern, damit der Button wieder
       dieselben Proportionen hat und „Geschichte lesen“ einzeilig bleibt. */
    .swap-card .swap-card__link {
        left: 8%;
        right: 8%;
        font-size: 0.6rem;
        white-space: nowrap;
        translate: 0 3px;
    }
}


.swap-card {
    position: absolute;
    inset: 0;
    transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.3s ease, filter 0.45s ease;
    will-change: transform, filter;
}

/* Schwebe-Animation im Ruhezustand – bewegt die komplette Karte (inkl. Rahmen/Schatten
   im .swap-card__tilt darunter), eigener Layer, damit die Stack-Position
   (transform auf .swap-card) nicht überschrieben wird */
.swap-card__float {
    width: 100%;
    height: 100%;
    perspective: 900px;
    animation: swap-float 4.5s ease-in-out infinite;
}

.swap-stack > .swap-card:nth-child(1) .swap-card__float { animation-duration: 4.2s; animation-delay: -0.3s; }
.swap-stack > .swap-card:nth-child(2) .swap-card__float { animation-duration: 5s;   animation-delay: -1.6s; }
.swap-stack > .swap-card:nth-child(3) .swap-card__float { animation-duration: 4.6s; animation-delay: -2.7s; }
.swap-stack > .swap-card:nth-child(4) .swap-card__float { animation-duration: 5.3s; animation-delay: -0.9s; }

@keyframes swap-float {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50% { transform: translateY(-14px) rotate(0.6deg); }
}

/* 3D-Tilt-Layer – von der Maus per JS gesteuert (rotateX/rotateY/translate/scale).
   Trägt Rahmen/Schatten der sichtbaren Karte, damit die komplette Karte (nicht nur
   das Bild darin) schwebt und sich neigt. */
.swap-card__tilt {
    position: relative;
    width: 100%;
    height: 100%;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.25);
    transition: transform 0.15s ease-out;
    will-change: transform;
}

.swap-card__tilt img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
    pointer-events: none;
    user-select: none;
}

.swap-card__shine {
    position: absolute;
    inset: 0;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.25s ease;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, 0.45), transparent 55%);
    mix-blend-mode: overlay;
}

.swap-stack.is-hovering .swap-card__shine {
    opacity: 1;
}

/* CTA-Button unten auf jeder Karte, verlinkt zur jeweiligen Geschichte. Eigenständig
   klickbar (siehe JS: pointerdown/click auf diesem Link werden NICHT als Swipe/Swap
   interpretiert), Ziehen/Wischen der Karte bleibt sonst unverändert. */
.swap-card__link {
    position: absolute;
    left: 12%;
    right: 12%;
    bottom: 4.5%;
    z-index: 2;
    background-color: var(--color-yellow);
    color: var(--color-blue);
    font-weight: 700;
    text-transform: uppercase;
    font-size: 0.78rem;
    text-align: center;
    padding: 0.65em 1em;
    border-radius: 999px;
    text-decoration: none;
    pointer-events: auto;
}

/* 5 sichtbare Fan-Positionen (0 = scharfe Mittelkarte, 1/2 = links & rechts klar sichtbar,
   3/4 = knapp hinter der Frontkarte versteckt, füllen die Lücke dahinter).
   Karussell-Fluss: Position 1 rückt von links nach vorn, die Frontkarte fliegt nach rechts raus. */
.swap-card[data-pos="0"] { transform: translate(0, 0) rotate(2deg) scale(1); z-index: 5; filter: blur(0); cursor: grab; touch-action: none; }
.swap-card[data-pos="1"] { transform: translate(-44%, 5%) rotate(-8deg) scale(0.9); z-index: 4; filter: blur(1.5px); }
.swap-card[data-pos="2"] { transform: translate(44%, 8%) rotate(8deg) scale(0.84); z-index: 3; filter: blur(3px); }
.swap-card[data-pos="3"] { transform: translate(-14%, 14%) rotate(-5deg) scale(0.78); z-index: 2; filter: blur(5px); }
.swap-card[data-pos="4"] { transform: translate(14%, 17%) rotate(5deg) scale(0.74); z-index: 1; filter: blur(6px); }

/* Restliche Karten warten unsichtbar in der Warteschlange, bis sie an Position 4 nachrücken.
   visibility:hidden zusätzlich zu opacity:0, damit ihre „Geschichte lesen“-Links nicht
   per Tab erreichbar sind (der Fokus stünde sonst auf einem unsichtbaren Element).
   Optisch ohne Wirkung: Beim Nachrücken auf Position 4 wird die Karte sofort
   sichtbar und blendet wie bisher über die opacity-Transition ein. */
.swap-card[data-pos="5"],
.swap-card[data-pos="6"],
.swap-card[data-pos="7"],
.swap-card[data-pos="8"],
.swap-card[data-pos="9"] {
    transform: translate(18%, 22%) rotate(5deg) scale(0.66);
    z-index: 0;
    opacity: 0;
    visibility: hidden;
    filter: blur(6px);
    pointer-events: none;
}

/* Ausstieg beim Swap (Richtung/Ziel wird per JS relativ zur aktuellen Position berechnet
   und als transform inline gesetzt, damit die Flugstrecke immer gleich lang & smooth wirkt –
   egal ob per Klick aus der Mitte oder nach einem weiten Drag ausgelöst) */
.swap-card--flying {
    transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.4s ease 0.05s, filter 0.3s ease;
    opacity: 0 !important;
    filter: blur(0) !important;
    z-index: 6 !important;
}

.swap-card--resetting {
    transition: none !important;
}

/* Während die Karte am Zeiger/Finger hängt: keine Transition (folgt 1:1), Schwebe-Animation
   pausiert, Schatten etwas kräftiger für einen "angehobenen" Eindruck */
.swap-card--dragging {
    transition: none !important;
    cursor: grabbing;
}

.swap-card--dragging .swap-card__float {
    animation-play-state: paused;
}

.swap-card--dragging .swap-card__tilt {
    box-shadow: 0 22px 46px rgba(0, 0, 0, 0.35);
}

/* Sanftes Zurückfedern in die Mitte, wenn der Drag nicht weit/schnell genug für einen Swap war */
.swap-card--snapback {
    transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ── Swipe-Intro-Overlay ── */
/* Liegt über dem Stack, lässt Klicks/Drags aber ungehindert durch (pointer-events: none),
   damit ein "echter" Swipe während der Intro sie sofort beenden kann. */
.swap-intro {
    position: absolute;
    inset: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    opacity: 1;
    transition: opacity 0.5s ease;
}

.swap-intro--hidden {
    opacity: 0;
}

/* Äußere Ebene: nur Position + Rotation, Drehpunkt unterhalb des Icons (wie ein Handgelenk).
   Ablauf: Mitte -> links (0–14%) -> kurz stehen bleiben, "greifen" (14–21%) -> mit
   gegriffener Hand nach rechts ziehen (21–45%) -> kurz stehen bleiben, "loslassen"
   (45–52%) -> zurück zur Mitte (52–66%) -> Pause (66–100%).
   Gesamtdauer läuft über --autoplay-delay synchron zum Auto-Swap-Takt (per JS gesetzt);
   die Pause am Ende füllt die verbleibende Zeit und wurde bewusst großzügig bemessen. */
.swap-intro__hand {
    transform-origin: 50% 160%;
    /* Dauer synchron zu --autoplay-delay; die genaue Phasen-Ausrichtung zum Auto-Swap
       (Loslassen-Moment = Karte fliegt raus) setzt syncIntroToAutoplay() per JS über
       currentTime, ein reiner CSS-delay würde nicht exakt zum JS-Timer passen. */
    animation: swap-intro-swipe var(--autoplay-delay, 2.8s) ease-in-out infinite;
}

@keyframes swap-intro-swipe {
    0%   { transform: translateX(0) rotate(0deg); }
    14%  { transform: translateX(-32%) rotate(-12deg); }
    21%  { transform: translateX(-32%) rotate(-12deg); }
    45%  { transform: translateX(32%) rotate(12deg); }
    52%  { transform: translateX(32%) rotate(12deg); }
    66%  { transform: translateX(0) rotate(0deg); }
    100% { transform: translateX(0) rotate(0deg); }
}

/* Mittlere Ebene: Skalierung mit eigenem Drehpunkt Richtung Fingerspitze (oben). Schrumpft
   erst NACHDEM links angekommen ("greifen"), bleibt während der ganzen Fahrt nach rechts
   klein, und wird erst wieder groß NACHDEM rechts angekommen ("loslassen"). */
.swap-intro__hand-inner {
    position: relative;
    transform-origin: 50% 22%;
    animation: swap-intro-scale var(--autoplay-delay, 2.8s) ease-in-out infinite;
}

@keyframes swap-intro-scale {
    0%   { transform: scale(1); }
    14%  { transform: scale(1); }
    21%  { transform: scale(0.8); }
    45%  { transform: scale(0.8); }
    52%  { transform: scale(1); }
    100% { transform: scale(1); }
}

.swap-intro__emoji {
    display: block;
    font-size: 3rem;
    line-height: 1;
    /* Emoji in eine reine weiße Silhouette umfärben (unabhängig von Plattform-Hautton) */
    filter: brightness(0) invert(1) drop-shadow(0 8px 14px rgba(0, 0, 0, 0.45));
}

/* "Berührungs"-Strahlen an der Fingerspitze – blenden beim "Greifen" links ein, bleiben
   während der ganzen Fahrt nach rechts sichtbar und blenden beim "Loslassen" rechts
   wieder aus (mit kleinem Aufblähen als "Release"-Effekt). */
.swap-intro__touch {
    position: absolute;
    top: -2px;
    left: calc(50% - 6px);
    width: 26px;
    height: 26px;
    transform: translate(-50%, -46%) scale(0.5);
    opacity: 0;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.35));
    animation: swap-intro-touch var(--autoplay-delay, 2.8s) ease-in-out infinite;
}

@keyframes swap-intro-touch {
    0%, 14%  { opacity: 0; transform: translate(-50%, -46%) scale(0.5); }
    21%      { opacity: 1; transform: translate(-50%, -46%) scale(1); }
    45%      { opacity: 1; transform: translate(-50%, -46%) scale(1); }
    52%      { opacity: 0; transform: translate(-50%, -46%) scale(1.3); }
    100%     { opacity: 0; transform: translate(-50%, -46%) scale(0.5); }
}

/* ── 7. Modal: „mehr erfahren“-Bottom-Sheet (Story-Seiten), fährt von unten hoch ── */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background-color: rgba(20, 22, 30, 0.55);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0s 0.3s;
}

.modal-overlay.is-open {
    opacity: 1;
    visibility: visible;
    transition-delay: 0s;
}

.modal {
    width: 100%;
    max-width: 640px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    background-color: #fff;
    color: #333;
    border-radius: 20px 20px 0 0;
    box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.3);
    transform: translateY(100%);
    transition: transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}

.modal-overlay.is-open .modal {
    transform: translateY(0);
}

.modal__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.75rem 1.75rem 1.25rem;
    border-bottom: 1px solid rgba(35, 82, 154, 0.12);
}

.modal__title {
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--color-blue);
    margin: 0;
    /* Gleicht die Zeilenlängen bei mehrzeiligen Modal-Titeln aus, gleiches Prinzip
       wie bei .story-slide__heading. */
    text-wrap: balance;
}

.modal__close {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: var(--color-blue);
    cursor: pointer;
}

.modal__close svg {
    width: 18px;
    height: 18px;
    stroke-width: 3.8;
}

.modal__close:hover {
    background-color: rgba(35, 82, 154, 0.08);
}

.modal__body {
    padding: 1.25rem 1.75rem 2.25rem;
    overflow-y: auto;
    line-height: 1.7;
}

.modal__body p {
    margin-bottom: 1rem;
    text-wrap: pretty;
}

.modal__body p:last-child {
    margin-bottom: 0;
}

/* Fortsetzung des gekürzten Slide-Texts (Handy, siehe .story-slide__excerpt): Vor dem
   Modal-Text stehen ein Klon der Slide-3-Galerie und der Rest des Absatzes mit „…“
   am Anfang. Die Galerie liegt hier ohne die mobilen #perspektive-akt-Regeln, daher
   eigene Maße: volle Sheet-Breite, 16:9 wie auf der Slide; die Crossfade-Animation
   läuft über die geklonten Klassen weiter. */
.modal__gallery {
    width: 100%;
    max-width: none;
    aspect-ratio: 16 / 9;
    margin-bottom: 1rem;
}

/* Drei Klassen tief, damit die Regeln die :nth-of-type-Ausschnitte der Crossfade-
   Bilder (weiter oben, gleich spezifisch) überstimmen – dieselben Ausschnitte wie
   die #perspektive-akt-Regeln des Handy-Blocks. Gilt auch für Majas Einzelbild. */
.modal__body .modal__gallery .story-slide__photo {
    width: 100%;
    height: 100%;
    max-height: none;
    max-width: none;
    object-fit: cover;
    object-position: center 30%;
}

.modal__body .modal__gallery .story-slide__photo--jan-akt-gruppe {
    object-position: center 15%;
}

.modal__body .modal__gallery .story-slide__photo--akt-hoch {
    object-position: center 12%;
}

body.modal-open {
    overflow: hidden;
    touch-action: none;
}

@media (max-width: 1024px) {
    /* Höher als die 80vh des Desktops: Der Hintergrund ist ohnehin unscharf, oben
       bleibt nur ein schmaler Rand (Wunsch 11.09.2026). svh, damit das Sheet beim
       Ein-/Ausfahren der Safari-Leiste nicht springt; vh als Fallback. */
    .modal {
        max-height: 92vh;
        max-height: calc(100svh - 3rem);
        border-radius: 16px 16px 0 0;
    }

    /* Startseite: Überschriften und Kachel-Zitate mobil 5 % kleiner. */
    .stories__subtitle {
        font-size: 1.66rem;
        line-height: 1.19;
    }

    .stories__title {
        font-size: 1.19rem;
        line-height: 1.19;
    }

    .story-card__quote {
        font-size: 0.95rem;
        line-height: 1.38;
    }

    .modal__header {
        padding: 1.25rem 1.25rem 1rem;
    }

    /* Angeglichen an .story-slide__heading (mobil 1.2rem/1.2), damit sich der Modal-Text
       nicht größer liest als der Slide-Text, aus dem heraus er geöffnet wurde. */
    .modal__title {
        font-size: 1.2rem;
        line-height: 1.2;
    }

    /* Bewusst groesser als der Fliesstext auf den Slides (0.9rem): Das Modal scrollt, hier
       ist der vertikale Platz also keine Grenze, und es sind laengere Texte am Stueck zu
       lesen. Deshalb volle 1rem (16px) und – anders als auf den Slides – ein grosszuegiger
       Zeilenabstand als Faktor, der mit der Schrift mitwaechst. */
    .modal__body {
        padding: 1rem 1.25rem 2rem;
        font-size: 1rem;
        line-height: 1.75;
    }
}
/* ── Mobile Feinjustierung je Kind ───────────────────────────────────────
   Richtungen auf dem Bildschirm (translate):
   +X = rechts, -X = links, +Y = runter, -Y = hoch. Desktop bleibt unberührt. */

.story-slide__label--teaser-luisa-reduced {
    display: none;
}

/* Reduzierter Modus, geprüft bei 395 × 650 px. */
@media (max-width: 640px) and (max-height: 749px) {
    /* Slide 1: Freisteller-Fotos. Nur noch X-Versatz und Größe: Die Y-Versätze
       (Amy/Lilly -23px, Ben/Luisa -33px, Maja -110px) glichen die langen Slide-1-Texte
       aus; seit der Textkürzung (11.09.2026, .story-slide__excerpt) sind die Boxen
       gleich hoch, und der Versatz riss nur noch einen Rand unter dem Foto auf. */
    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-amy {
        transform: translateX(-102px) scale(1.1);
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-ben-luisa {
        transform: translateX(-120px) scale(1.1); /* -82 → -120: Luisa war angeschnitten (11.09.2026) */
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-connor {
        transform: translate(-142px, 0) scale(1.2);
        transform-origin: center bottom;
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-kevin {
        transform: translateX(-120px) scale(1.17);
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-lilly {
        transform: translateX(-97px) scale(1.1);
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-maja {
        transform: translateX(-110px) scale(1.1); /* -72 → -110: Maja stand zu weit rechts (11.09.2026) */
    }

    /* Slide 2: Illustrationen und Zitate. */
    .is-bleeding.story-slide__icon-lg--jan-rollstuhl {
        translate: 15px -43px;
    }

    .story-slide__paired-illu--giraffe {
        translate: -48px -53px;
        transform-origin: center;
    }

    .story-slide__paired-illu--turnschuhe {
        translate: -45px -118px;
        transform-origin: center;
    }

    .story-slide__illustration-pair--large .story-slide__paired-illu--giraffe,
    .story-slide__illustration-pair--large .story-slide__paired-illu--turnschuhe {
        width: 100px;
        height: auto;
        scale: none;
    }

    /* Ben/Luisa Slide 2: Seit der Textkürzung (11.09.2026, .story-slide__excerpt) ist
       unter dem Text Platz – Illu-Paar größer (0.7 → 0.95) und tiefer, Zitat tiefer.
       Grenze: Namenszeile muss bei 375 × 548 über der Pfeilleiste (y≈480) bleiben. */
    .is-bleeding.story-slide__illustration-pair--large {
        translate: 15px 30px;
        scale: 0.95;
    }

    .story-slide__quote--ben-luisa-s2 {
        translate: 0 55px;
    }

    .story-slide__quote--ben-luisa-s2 .story-slide__mobile-break {
        display: none;
    }

    .story-slide__quote--ben-luisa-s2 .story-slide__quote-cite {
        white-space: nowrap;
    }

    /* Connor Slide 2: seit der Textkürzung (11.09.2026) Geländer größer (0.9 → 1.2)
       und tiefer, Zitat tiefer. Grenze wie bei Ben/Luisa: Namenszeile bei 375 × 548
       über der Pfeilleiste (y≈480). */
    .is-bleeding.story-slide__icon-lg--connor-gelaender {
        scale: 1.2;
        translate: 15px 40px;
    }

    .story-slide__quote--connor-s2 {
        translate: 0 60px;
    }

    .is-bleeding.story-slide__icon-lg--kevin-tshirt {
        translate: 0 -55px;
    }

    .is-bleeding.story-slide__icon-lg--lilly-schloss {
        translate: 10px -35px;
        scale: 0.765;
    }

    .is-bleeding.story-slide__icon-lg--maja-fahrrad {
        translate: 33px -43px;
    }

    .story-slide__quote--maja-s2,
    .story-slide__quote--mathea-s2 {
        translate: 0 -23px;
    }

    /* Slide 4: Illustrationen und Familienfotos. */
    #perspektive-unterstuetzer .story-slide__photo--kevin-supporter {
        translate: -20px 13px;
        scale: 0.78;
        transform-origin: bottom center;
    }

    .story-slide__icon--kevin-goal img {
        translate: 0 15px;
    }

    .is-bleeding.story-slide__icon--lilly-fairy {
        translate: 0 -45px;
    }

    .is-bleeding.story-slide__icon--mathea-paw {
        translate: -18px -55px;
    }

    #perspektive-unterstuetzer .story-slide__photo--maja-supporter {
        translate: 0 15px;
        scale: 0.85;
        transform-origin: bottom center;
    }

    #perspektive-unterstuetzer .story-slide__photo--mathea-supporter {
        translate: 0 20px;
    }

    #perspektive-unterstuetzer .story-slide__photo--willi-supporter {
        scale: 0.85;
        transform-origin: bottom center;
    }

    /* Slide 5: Teaser zur nächsten Geschichte. */
    .story-quote--teaser .story-slide__photo--kevin-teaser {
        translate: 18px 0;
    }

    .story-quote--amy-next .story-slide__label {
        translate: 0 108px;
    }

    .story-quote--amy-next .story-slide__photo--ben-luisa-teaser {
        translate: 30px 0;
    }

    #perspektive-unterstuetzer .story-slide__photo--ben-luisa-supporter {
        translate: 10px -30px;
    }

    .story-slide__icon-pair--floating .story-slide__paired-illu--feld {
        translate: 0 -95px;
        scale: 0.85;
        transform-origin: center;
    }

    /* Amy nutzt im reduzierten Modus den alternativen Luisa-Marker. */
    .story-quote--amy-next .story-slide__label--teaser-luisa-standard {
        display: none;
    }

    .story-quote--amy-next .story-slide__label--teaser-luisa-reduced {
        display: block;
        translate: 0 128px;
    }
}

/* Amys Teaser-CTA auf sehr niedrigen Displays (375 × 548): Mit den 20px des
   reduzierten Modus läge er in der Pfeilleiste (beginnt dort bei y≈480). */
@media (max-width: 640px) and (max-height: 600px) {
    [data-layer-home="teaser"] .story-quote__cta--amy-next {
        transform: translateY(-20px);
    }
}

/* Normale mobile Ansicht, geprüft bei 395 × 750 px. */
@media (max-width: 640px) and (min-height: 750px) {
    /* Slide 1. (Majas Sonderregeln – Illu aus, Überschrift nicht neben die Illu,
       30px Polster – waren Platzgewinn für ihren 981-Zeichen-Text; seit der
       Textkürzung am 11.09.2026 entfallen sie, Maja läuft wie die anderen.) */
    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-maja {
        transform: translateX(-120px) scale(1.1); /* -80 → -120, s. reduzierter Modus */
    }

    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-ben-luisa {
        transform: translateX(-130px) scale(1.1); /* -95 → -130, s. reduzierter Modus */
    }

    /* Slide 2. Ben/Luisa: seit der Textkürzung (11.09.2026) Illu-Paar größer
       (0.85 → 1.1) und tiefer, Zitat tiefer – unter dem Text war Leerraum. */
    .is-bleeding.story-slide__illustration-pair--large {
        translate: 0 80px;
        scale: 1.1;
        transform-origin: center;
    }

    .story-slide__paired-illu--giraffe {
        translate: 20px -30px;
        scale: 0.92;
        transform-origin: center;
    }

    .story-slide__paired-illu--turnschuhe {
        translate: 18px -80px;
    }

    .story-slide__quote--ben-luisa-s2 {
        translate: 0 130px;
    }

    /* Connor: Geländer größer und tiefer, Zitat tiefer (11.09.2026, s. reduzierter Modus). */
    .is-bleeding.story-slide__icon-lg--connor-gelaender {
        scale: 1.3;
        translate: 0 90px;
        transform-origin: 100% 50%;
    }

    .story-slide__quote--connor-s2 {
        translate: 0 120px;
    }

    .story-slide__quote--ben-luisa-s2 .story-slide__mobile-break {
        display: none;
    }

    .story-slide__quote--ben-luisa-s2 .story-slide__quote-cite {
        white-space: nowrap;
    }

    .story-slide__quote--kevin-s2 {
        translate: 0 -10px;
    }

    .is-bleeding.story-slide__icon-lg--lilly-schloss {
        translate: 5px 0;
    }

    .is-bleeding.story-slide__icon-lg--maja-fahrrad {
        translate: 34px 0;
    }

    /* Slide 4. */
    #perspektive-unterstuetzer .story-slide__photo--amy-supporter {
        translate: -20px 8px;
    }

    .is-bleeding.story-slide__icon--connor-matte {
        translate: 0 60px;
    }

    #perspektive-unterstuetzer .story-slide__photo--kevin-supporter {
        translate: -27px 5px;
        scale: 0.87;
        transform-origin: bottom center;
    }

    .story-slide__icon--kevin-goal img {
        translate: 0 40px;
    }

    #perspektive-unterstuetzer .story-slide__photo--maja-supporter {
        translate: 0 15px;
    }

    /* Slide 5: Teaser zur nächsten Geschichte. */
    .story-quote--teaser .story-slide__photo--kevin-teaser {
        translate: 28px 0;
    }

    .story-quote--teaser .story-slide__photo--lilly-teaser,
    .story-quote--teaser .story-slide__photo--mathea-teaser {
        scale: 0.92;
        transform-origin: 100% 100%;
    }

    .story-quote--amy-next .story-slide__label {
        translate: 0 30px;
    }

    .story-quote--amy-next .story-slide__label--teaser-ben {
        translate: 0 20px;
    }

    [data-layer-home="teaser"] .story-quote__cta--amy-next {
        transform: translateY(149px); /* 89 → 149: tiefer (Wunsch 11.09.2026) */
    }

    .story-quote--amy-next .story-slide__photo--ben-luisa-teaser {
        translate: 30px 0;
        scale: 1.07;
        transform-origin: 100% 100%;
    }

    .story-slide__icon-pair--floating .story-slide__paired-illu--loewe {
        translate: 170px -115px;
        scale: 0.85;
        transform-origin: center;
    }

    .story-slide__icon-pair--floating .story-slide__paired-illu--feld {
        translate: 0 -90px;
        scale: 0.85;
        transform-origin: center;
    }

    .story-quote--teaser .story-slide__photo--willi-teaser {
        translate: 28px 0;
    }

    .story-quote--teaser .story-slide__photo--connor-teaser {
        translate: 18px 0;
    }

    /* Amy nutzt in der normalen mobilen Ansicht den alternativen Luisa-Marker. */
    .story-quote--amy-next .story-slide__label--teaser-luisa-standard {
        display: none;
    }

    .story-quote--amy-next .story-slide__label--teaser-luisa-reduced {
        display: block;
        translate: 0 70px;
    }
}


/* ══ Tablet quer (1025–1279px) ═══════════════════════════════════════════════
   Zielbild: eine kleinere Desktop-Version. Die Breite ist unkritisch – die
   Textspalte ist ohnehin auf 1200px gedeckelt, ein 1180er iPad schöpft sie fast
   aus. Knapp ist die HÖHE: Bei 820px Fensterhöhe bleiben dem Slide nur 700px
   gegenüber 780px bei 1440x900. Die feste Navbar kostet davon 120px, also 15 %.
   Darum hier dieselbe kompakte Navbar wie mobil; das gibt jedem Slide 32px
   zurück und verhindert, dass lange Texte (Maja) unter die Leiste geraten.
   Die Desktop-Referenzbreiten ab 1280px bleiben unberührt. ── */
@media (min-width: 1025px) and (max-width: 1279px) {
    :root {
        --navbar-height: 88px;
    }

    /* Amys Teaser führt zu Ben UND Luisa. Luisas Marker steht über
       right: calc(-8% - 80px) bewusst über der rechten Kante; der Prozentanteil
       schrumpft mit dem Fenster, der feste Abzug bleibt – bei 1180px ragte die
       Nummer dadurch 91px aus der Slide, sichtbar blieb nur "Traum". Hier ein
       Wert, der ihn wie auf dem Desktop knapp innerhalb hält. */
    .story-quote--amy-next .story-slide__label--teaser-luisa {
        right: 1.5rem;
        left: auto;
    }

    /* Ben und Luisa teilen sich das Freistellerfoto auf Slide 1. Es ragt bewusst
       über die rechte Kante, der Anschnitt wächst zu schmalen Fenstern hin aber
       stark an: 144px bei 1440, 246px bei 1180 – Luisa war dort halb abgeschnitten.
       Etwas niedriger bringt den Anschnitt zurück auf das Maß des Desktops. */
    .story-slide__media--photo .story-slide__photo--hero-ben-luisa {
        height: 82%;
    }

    /* Die Marker hängen über --photo-h an der Fotogröße. Da das Foto hier auf 82
       Prozent verkleinert ist, standen sie 21px über dessen Oberkante und ihre
       Linien endeten im Leeren; auf dem Desktop liegen sie 85px innerhalb des
       Bildes, also über den Köpfen. Die Faktoren sind deshalb um denselben Anteil
       verkleinert wie das Foto. */
    #landingpage .story-slide__media--photo .story-slide__label--hero-ben {
        bottom: min(calc(0.79 * var(--photo-h)), var(--label-max-bottom));
    }

    #landingpage .story-slide__media--photo .story-slide__label--hero-luisa {
        bottom: min(calc(0.74 * var(--photo-h)), var(--label-max-bottom));
    }

    /* Bens Feld-Illustration auf dem Teaser steht auf top:-35px und ragte im
       Querformat 42px über die Slide-Oberkante, weil dort weniger Höhe zur
       Verfügung steht. Auf dem Desktop bleibt sie im Bild. */
    .story-slide__icon-pair--floating .story-slide__paired-illu--feld {
        top: -25px;
    }

    .story-slide__icon-pair--floating .story-slide__paired-illu--loewe {
        top: 50px;
    }

    /* Willis "I love NY" auf Slide 4 sitzt dicht über der Überschrift und rückte
       ihr im Querformat näher als auf dem Desktop (140 statt 125px Überstand).
       Etwas höher gesetzt (Wunsch 08.09.2026). */
    .story-slide__icon--willi-iloveny {
        top: -170px;
    }

    /* Auf Slide 1 liegt das Freistellerfoto im Stapel über dem Text, weil es im
       Markup danach kommt. Seine Sternzacken laufen dadurch über die Zeilen. Auf
       dem Desktop ist das ebenso, im Querformat rückt der Text dem Foto aber
       näher und es stört beim Lesen. Der Text bekommt hier deshalb eine eigene
       Ebene über dem Bild (Wunsch 08.09.2026). */
    #landingpage .story-slide__text {
        position: relative;
        z-index: 2;
    }

    /* Der Stern des Teaser-Slides ragt 100px nach links in die vorhergehende
       Slide. Da der Teaser bereits zur nächsten Geschichte überleitet, gehört er
       dort nicht hinein – er wird am Slide-Rand beschnitten und bleibt innerhalb
       des Teasers wie gehabt angeschnitten sichtbar. Das Freistellerfoto auf
       Slide 1 ragt bewusst 246px nach rechts und bleibt davon unberührt, weil
       hier nur die Teaser-Slide beschnitten wird. Die Regel sitzt auf #teaser und
       nicht auf dem Zitat-Container: Der ist position:static und beschneidet
       absolut positionierte Kinder wie den Stern deshalb nicht. */
    #teaser {
        overflow: hidden;
    }

    /* Das Familienfoto auf Slide 5 ist breiter als seine Box und wird von
       object-fit:cover beidseitig beschnitten – mittig zentriert fiel links ein
       Stück des Vaters weg. Der Ausschnitt sitzt hier weiter links, sodass die
       Personen vollständig bleiben. */
    #perspektive-unterstuetzer .story-slide__photo--ben-luisa-supporter {
        object-position: 22% center;
    }

    /* Der Marker zu Connor auf dem Teaser von Ben und Luisa endet im Leeren –
       gleiche Ursache wie bei Matheas Marker: Der feste Abzug im Basiswert
       calc(-8% - 80px) wirkt bei schmalerem Fenster stärker. */
    .story-quote .story-slide__label--teaser-connor {
        left: -8%;
    }

    /* Connors Geländer auf Slide 2 wirkt in der Fläche zu klein (Wunsch
       08.09.2026). Der Selektor entspricht der Basisregel, weil die Illustration
       per data-bleed ausgehängt wird und Vorfahren dabei verliert. */
    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--connor-gelaender,
    .story-slide__icon-lg--connor-gelaender {
        width: 30vw;
    }

    /* Majas Helm auf Slide 4 steht 19px höher als auf dem Desktop und lässt viel
       Luft zur Überschrift (Wunsch 08.09.2026). */
    .story-slide__icon--maja-helmet {
        top: -70px;
    }

    /* Der Traum-Marker auf Majas Teaser zeigt zu Mathea und endete rund 90px vor
       ihr im Leeren. Der feste Abzug im Basiswert calc(-8% - 80px) wirkt bei
       schmalerem Fenster stärker; hier ohne ihn. */
    .story-quote .story-slide__label--teaser-mathea {
        left: -8%;
    }

    /* Lillys Familienfoto auf Slide 4 nimmt im Querformat zu viel Fläche ein
       (Wunsch 08.09.2026). */
    .story-slide__media--photo-xl .story-slide__photo--lilly-supporter {
        height: 88%;
    }

    /* Majas Text ist der längste der neun und braucht die Fläche links ganz.
       Die Rollstuhl-Illustration darunter entfällt hier deshalb (Wunsch
       08.09.2026); auf allen anderen Ansichten bleibt sie. */
    .story-slide__icon--intro .story-slide__icon-image--maja-rollstuhl {
        display: none;
    }

    /* Der Kartenstapel ist 604px hoch und hält 72px Abstand zur Bildunterschrift.
       Zusammen mit dieser überschreitet er die 668px, die im Querformat zwischen
       den Innenabständen bleiben – die Zeile "Erfüllte Träume" wurde unten
       abgeschnitten. Ein Höhendeckel und der kompaktere Abstand des mobilen
       Layouts schaffen den Platz; die Kartenbreite folgt über das Seitenverhältnis. */
    .swap-stack {
        /* Über die Breite steuern, nicht über max-height: Die Karten liegen als
           absolut positionierte Geschwister im Stapel und folgen dessen Breite,
           ein reiner Höhendeckel schnitt sie oben an. Aus der Breite ergibt sich
           die Höhe über das Seitenverhältnis 9:16. */
        width: min(60vw, 286px);
    }

    .slide__col--cards {
        gap: 2rem;
    }

    /* Die Hero-Überschrift füllt ihre Spalte bis zur vollen Breite aus; ihre
       letzte Zeile lief dadurch unter die vorderste Karte des Stapels und war zu
       7 % verdeckt. Der Deckel hält sie in der freien Fläche links. */
    /* Wie hochkant der ganze Block, damit der Stern dahinter bleibt.
       Per Messung der größte Wert, bei dem die Überschrift die Karten nicht mehr
       berührt: 30rem ergibt drei Zeilen und null Überlappung, ab 32rem läuft die
       letzte Zeile wieder unter die vorderste Karte. Die zwei Zeilen des Desktops
       sind bei dieser Breite nicht erreichbar.
       margin-right verankert den Block links – die Spalte zentriert sonst. */
    .hero__headline {
        /* Nicht fix, sondern mitwachsend: Am unteren Ende des Bereichs ist die
           Spalte selbst schmaler als 30rem, dort berührte die Überschrift sonst
           die Karten. */
        max-width: min(30rem, 40vw);
        margin-right: auto;
    }

    /* Jede Zeile der Überschrift ist ein eigener weißer Kasten. "beginnt mit Dir."
       braucht bei der geerbten Schriftgröße 591px, in den 480px des Blocks brach
       die Zeile deshalb INNERHALB ihres Kastens um – zwei Textzeilen in einer
       Fläche, mit einem einzelnen "DIR." als Treppenstufe darunter. Mehr Breite
       geht nicht, ohne die Karten zu berühren, also die Schrift etwas kleiner:
       Bei 2.9rem braucht die Zeile 465px und bleibt im gesamten Bereich bis
       1279px einzeilig – auch bei 1025px, wo die Spalte selbst schmaler ist als
       der Deckel. */
    .hero__title {
        font-size: clamp(2.4rem, 3.8vw, 2.8rem);
    }

    /* Das Logo hat feste Höhe und ragte sonst unten aus der niedrigeren Leiste.
       Gleicher Wert wie im mobilen Block – nur diese eine Regel wird übernommen,
       die übrigen Anpassungen dort (Claim zweizeilig, kleinerer Hero-Titel) sind
       für Handybreiten gedacht und hier nicht erwünscht. */
    .navbar__logo-img {
        height: 56px;
    }
}


/* ══ Tablet hochkant (641–1024px) ════════════════════════════════════════════
   Das mobile Layout aus dem Block weiter oben gilt hier bereits (einspaltig,
   Ebenen-Umbau, kompakte Navbar). Was fehlt, ist der Maßstab: Die Größen dort
   sind feste Pixelwerte für 390px Breite. Auf 820px Breite und 1180px Höhe
   wirken sie halb so groß – Motive schrumpfen von 65–100 % Slidebreite auf
   28–43 %, und auf Slide 4 blieb die halbe Fläche leer.

   Deshalb hier dieselben Maße in relativen Einheiten:
   - Höhen in svh, mit dem Verhältnis der mobilen Referenz (800px Fensterhöhe).
     Sie wachsen damit exakt proportional zur Slidehöhe.
   - Breiten in vw, aber gedämpft (Faktor ~1,5 statt der linearen 2,1), sonst
     dominieren die Motive die deutlich breitere Fläche.
   Die kindspezifischen Feinwerte für Handybreiten (Blöcke bei max-width:640px)
   bleiben unberührt und greifen hier bewusst nicht. ── */
@media (min-width: 641px) and (max-width: 1024px) {

    /* ── Flächen, die die vertikale Aufteilung bestimmen ── */

    /* Slide 1: Freistellerfoto (mobil 440px bei 800px Fensterhöhe). */
    .story-slide__inner--intro .story-slide__media--photo {
        height: 55svh;
    }

    /* Slide 4: Familienfoto. Mobil 280px – der auffälligste Fall, hier stand
       sonst die halbe Slide leer. Die Quellen sind 1032px breit und tragen die
       größere Darstellung ohne Unschärfe. */
    #perspektive-unterstuetzer .story-slide__media--photo-xl {
        height: 48svh;
    }

    /* Teaser: Foto der nächsten Geschichte (mobil 350px). */
    .story-quote--teaser .story-slide__media--photo {
        height: 44svh;
    }

    /* Generische Bild- und Illustrationsflächen (mobil je 190px). */
    .story-slide__media--icon,
    .story-slide__media--photo {
        height: 24svh;
    }

    /* ── Lesbarkeit des Fließtexts ──
       Der Textblock nimmt die volle Slidebreite ein: bei 820px sind das 772px und
       damit rund 104 Zeichen je Zeile – weit über den 45–75, die sich gut lesen
       lassen. Zugleich blieb die Schrift bei 13.7px, weil ihre clamp-Formel an der
       Breite hängt und hier ihr Minimum erreicht. Beides ist kein Geschmack,
       sondern Lesbarkeit. Der per JS ausgehängte Textblock bekommt seine Breite
       inline gesetzt; max-width sticht das und wird schon bei der Messung im
       Skript berücksichtigt, die Position stimmt also weiterhin.
       Begrenzt wird nur der Absatz, nicht der umgebende Textblock: Die
       Intro-Illustration sitzt in diesem Block und rückte sonst mit nach links,
       womit sie über dem Fließtext lag statt rechts daneben. */
    .story-slide__text p {
        max-width: 34rem;
        font-size: 1rem;
        line-height: 1.65;
    }

    /* ── Startseite: Hero einspaltig ──
       Die beiden Hero-Spalten haben flex:1 1 280px. Auf dem Handy passen zwei
       davon nicht nebeneinander, der Umbruch greift und die Überschrift steht
       über dem Kartenstapel. Bei 820px reicht die Breite rechnerisch für zwei
       Spalten – der Stapel ist aber breiter als seine Spalte und schob sich über
       die Überschrift, die zu 21 % verdeckt war. Deshalb hier derselbe Umbruch
       wie auf dem Handy. */
    .hero .slide__inner {
        flex-direction: column;
        justify-content: center;
    }

    .hero .slide__col {
        flex: 0 0 auto;
        width: 100%;
    }

    /* Die Überschrift ist rechtsbündig gesetzt – ein Merkmal der Kampagne, das
       auch der Claim in der Navigation trägt. Auf Handy und Desktop füllt sie
       ihre Spalte, sodass das nicht auffällt; über die volle Tabletbreite klebte
       sie dagegen am rechten Rand. Der Deckel gibt ihr wieder die Breite, die sie
       auf dem Handy hat.
       Begrenzt wird der ganze Headline-Block, nicht nur die Schrift: Der Stern
       liegt absolut positioniert darin und bezieht seine Lage auf dessen Breite –
       eine Begrenzung allein der Schrift ließ ihn daneben stehen statt dahinter.
       Der Block steht hier mittig statt links (09.09.2026): Der Stern soll auf
       dem Tablet oben mittig sitzen, und weil er im Block verankert ist, wandert
       der Block mit. Ihn links zu lassen und nur den Stern zu zentrieren wurde
       verworfen – der Claim ragte dann über die linke Sternspitze hinaus. */
    .hero__headline {
        max-width: 26rem;
        margin-inline: auto;
    }

    /* Stern mittig im Block (statt der 62 % aus dem mobilen Block, die ihn
       bewusst nach rechts über die Spalte schieben) und größer: 68vw hält das
       Verhältnis zur Fensterbreite über den ganzen Bereich, der Deckel von 560px
       verhindert, dass er am oberen Ende unter die Navigationsleiste läuft.
       Bei 641px ergibt das 436px – dort ist der Claim so breit wie der Stern,
       mehr Größe würde ihn über die Kontur schieben. */
    .hero__star {
        left: 50%;
        max-width: min(68vw, 560px);
    }

    /* Claim größer als auf dem Handy (dort 2rem), damit er den gewachsenen Stern
       füllt. Die rechte Kante bleibt dabei stehen: Der Block ist 26rem breit und
       mittig, der Text rechtsbündig – die Zeilen wachsen also nach links.
       2.5rem ist die per Messung ermittelte Obergrenze: "beginnt mit Dir." braucht
       dann 401 der 416px des Blocks, ab 2.6rem bricht die Zeile INNERHALB ihres
       weißen Kastens um.
       Der vw-Anteil dämpft den Wert nach unten hin: Der Stern skaliert mit der
       Fensterbreite, der Textblock nicht (er misst überall 26rem). Bei 641px ist
       der Stern nur 436px breit, dort füllte der Claim ihn bis an die Kontur.
       4.9vw hält die Zeile bei rund 72 % der Sternbreite, wie bei 820px; das
       Minimum von 2rem entspricht dem Handywert, kleiner wird der Claim also
       nirgends. Ab 817px greift der Deckel. */
    .hero__title {
        font-size: clamp(2rem, 4.9vw, 2.5rem);
    }

    /* ── Slide 1 (Intro): Textblock mittig ──
       Auf dem Handy füllt der Text die Slide, hier lief er über die volle Breite
       von 772px, während der Fließtext bei 34rem umbricht – der Satz klebte
       dadurch am linken Rand. Begrenzt wird jetzt der ganze Block auf die Breite
       des Fließtextes und mittig gestellt; der Satz bleibt linksbündig.
       Die Intro-Illustration sitzt in diesem Block (order:-1, align-self:flex-end)
       und rückt mit nach innen – deshalb steht sie jetzt über dem Textanfang
       statt am Slide-Rand. Das zusätzliche padding-top gibt ihr die Höhe zurück,
       die sie dadurch verliert. */
    .story-slide__inner--intro .story-slide__text {
        max-width: 34rem;
        margin-inline: auto;
    }

    .story-slide__inner--intro {
        padding-top: 2.5rem;
    }

    /* Die Illustration rückt an die obere rechte Ecke des (jetzt schmaleren)
       Textblocks: 1rem höher und 1.5rem weiter nach rechts als auf dem Handy.
       Zwei Selektoren, weil der Textblock per [data-layer="text"] an den Track
       wandert und .story-slide__inner--intro danach nicht mehr greift. */
    .story-slide__inner--intro .story-slide__icon--intro,
    [data-layer-home="landingpage"].story-slide__text .story-slide__icon--intro {
        margin-top: 0;
        margin-right: 0;
    }

    /* Auf dem Handy wird die Überschrift per margin-top:-70px neben die Illustration
       gezogen, weil dort jede Zeile Höhe zählt. Auf dem Tablet ist die Höhe da:
       Der Zug wird auf -30px zurückgenommen, die Illustration rückt damit von der
       Überschrift ab, ohne selbst die Position zu wechseln. Weiter zurück (bis 0)
       ginge nur auf Kosten der langen Texte – bei Maja stößt der Fließtext dann an
       die Foto-Oberkante. */
    .story-slide__inner--intro .story-slide__heading,
    [data-layer-home="landingpage"].story-slide__text .story-slide__heading {
        margin-top: -30px;
    }

    /* ── Traum-Marker auf Slide 1 ──
       Mobil ist er ausgeblendet, weil das Foto dort jeden Pixel braucht. Auf dem
       Tablet ist Platz, und er ist ein prägendes Element der Kampagne. Die
       Positionslogik dafür (--photo-w/--photo-h, Marker über bottom/left als
       Anteil der Fotogröße) steht bereits in einem Block ab 641px und greift
       hier wieder, sobald die Ausblendung aufgehoben ist. */
    /* Zwei Marker liegen als Alternativfassung im HTML und dürfen nie zugleich mit
       ihrem Gegenstück sichtbar sein: die Handy-Fassung von Luisas Hero-Marker und
       die Fassung für den reduzierten Modus auf Amys Teaser. Sie sind hier per
       :not() ausgenommen, statt sie danach wieder auszublenden – eine separate
       Regel mit nur einer Klasse wäre weniger spezifisch als dieser Selektor und
       verlöre, sodass beide Nummern übereinander lägen. */
    .is-bleeding .story-slide__label:not(.story-slide__label--hero-luisa-mobile):not(.story-slide__label--teaser-luisa-reduced),
    #landingpage .story-slide__label:not(.story-slide__label--hero-luisa-mobile):not(.story-slide__label--teaser-luisa-reduced) {
        display: block;
    }

    /* Die Desktop-Formel (--photo-w/--photo-h, Bezug 50 % der Textspalte) greift
       hier nicht: Die Foto-Box wird per [data-bleed] an den Track gehängt und ist
       dann kein Nachkomme von #landingpage mehr. Übrig blieb die Basisregel
       (top:6%; left:4%) – der Marker stand bei allen neun Kindern an derselben
       Stelle weit links, ohne Bezug zum Kopf.
       Die Werte unten sind aus der Desktop-Fassung (1830 × 1100) abgeleitet: Dort
       sitzt der Punkt des Standard-Markers bei 48,1 % der Fotobreite und 8 % der
       Fotohöhe, gemessen am Foto-Rechteck. Weil die Fotos auf dem Tablet je Kind
       unterschiedlich verschoben und skaliert sind (die Köpfe sollen ins Bild),
       ergibt derselbe Punkt am Motiv je Kind einen anderen Wert an der Box –
       daher neun Einzelwerte statt einer Formel. Bezug ist die Foto-Box, weil nur
       sie ohne Ancestor-Selektor erreichbar ist; :has() wirkt vor und nach dem
       Aushängen gleichermaßen.
       Die negativen top-Werte sind kein Fehler: Bei den meisten Kindern ist das
       Foto höher als seine Box und ragt oben heraus, der Kopf liegt entsprechend
       über der Boxkante. */
    .story-slide__media--photo:has(.story-slide__photo--hero-jan) .story-slide__label {
        left: 21.5%;
        top: -2.5%;
    }

    /* Amys Freisteller ist auf dem Handy per scale(1.1) vergrößert; auf dem Tablet
       wirkt er dadurch deutlich größer als die der übrigen Kinder. Zurück auf 1.0.
       transform-origin auf die Unterkante, sonst schrumpft das Bild zur Mitte und
       löst sich unten von der Slidekante – die Freisteller sind bündig gesetzt. */
    .is-bleeding.story-slide__media--photo .story-slide__photo--hero-amy {
        transform: translateX(-125px) scale(1);
        transform-origin: center bottom;
    }

    .story-slide__media--photo:has(.story-slide__photo--hero-amy) .story-slide__label {
        left: 21%;
        top: 3.5%;
    }

    .story-slide__media--photo:has(.story-slide__photo--hero-connor) .story-slide__label {
        left: 18.5%;
        top: -4.5%;
    }

    .story-slide__media--photo:has(.story-slide__photo--hero-kevin) .story-slide__label {
        left: 21.5%;
        top: -1.5%;
    }

    .story-slide__media--photo:has(.story-slide__photo--hero-lilly) .story-slide__label {
        left: 23.5%;
        top: 3.5%;
    }

    .story-slide__media--photo:has(.story-slide__photo--hero-maja) .story-slide__label {
        left: 25%;
        top: 4%;
    }

    .story-slide__media--photo:has(.story-slide__photo--hero-mathea) .story-slide__label {
        left: 21.5%;
        top: -7.5%;
    }

    .story-slide__media--photo:has(.story-slide__photo--hero-willi) .story-slide__label {
        left: 19%;
        top: -5.5%;
    }

    /* Ben und Luisa teilen sich Slide 1 und haben je einen eigenen Marker. Die
       Desktop-Fassung setzt Bens Punkt auf 40,8 % der Fotobreite (links neben
       seinem Haar) und Luisas gespiegelten Marker mit der linken Kante auf 63,5 %.
       Beide Werte hier auf die Box umgerechnet; sie stehen dadurch nebeneinander
       statt übereinander, wie es die frühere Notlösung (3 % / 60 %) erzwang. */
    #landingpage .story-slide__media--photo .story-slide__label--hero-ben,
    .is-bleeding .story-slide__label--hero-ben {
        left: 17.5%;
        right: auto;
        top: 3.5%;
        bottom: auto;
    }

    #landingpage .story-slide__media--photo .story-slide__label--hero-luisa,
    .is-bleeding .story-slide__label--hero-luisa {
        left: 54%;
        right: auto;
        top: 0.5%;
        bottom: auto;
    }

    /* Das Motivpaar auf Slide 1 von Ben und Luisa rückt 20px höher – über
       position/top, nicht über margin: Die Illustration steht als erstes Element
       im Textblock, ein Margin würde die Überschrift und damit den ganzen Text
       mitziehen. So bleibt der Fluss unberührt. */
    .story-slide__icon-pair--intro {
        position: relative;
        top: -20px;
    }

    /* ── Illustrationen und Marker ── */

    .story-slide__icon img {
        width: 13.2vw;
        height: 13.2vw;
    }

    .story-slide__icon--float img {
        width: 29.3vw;
        height: 29.3vw;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg {
        width: 60vw;
    }

    /* Amys Filmklappe ist um 8° gekippt; ihr achsenparalleles Rechteck fällt
       dadurch deutlich größer aus als bei den ungekippten Motiven und lief mit dem
       gemeinsamen Wert über die rechte Slidekante. Eigener, kleinerer Wert.
       Selektor mit __inner davor, sonst gewinnt die Regel darüber. */
    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--amy-filmklappe {
        width: 46vw;
    }

    /* Lillys Schloss ist hoch und breit zugleich und füllte mit dem gemeinsamen
       Wert fast die halbe Slidehöhe. Majas Fahrrad ebenso, das zusätzlich tiefer
       steht (Regel weiter unten) und sonst an die Navigationsknöpfe stößt. */
    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--lilly-schloss {
        width: 48vw;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__icon-lg--maja-fahrrad {
        width: 50vw;
    }

    /* Connors Geländer und Majas Fahrrad liegen sonst über dem Zitat: deutlich
       tiefer. Bei Connor mit doppelter Klasse, damit der Wert die Regel des
       Handy-Blocks (top:0) schlägt. */
    .story-slide__icon-lg.story-slide__icon-lg--connor-gelaender {
        top: 150px;
    }

    .story-slide__icon-lg--maja-fahrrad {
        top: 150px;
    }

    /* Matheas Halsband ist flach und liegt quer über dem Zitat; es braucht mehr
       Weg nach unten als die hohen Motive. */
    .story-slide__icon-lg--mathea-halsband {
        top: 250px;
    }

    /* Etwas nach rechts – über position/left, nicht über translate: Das
       Bleed-Script misst die Lage des Motivs einmalig und schreibt sie inline.
       Ein translate steckt dann schon in der Messung UND wirkt danach erneut, die
       Verschiebung käme doppelt an (gemessen: 60px statt 30px). Das Inline-left
       des Scripts sticht dagegen die Regel hier, sie wirkt nur über die Messung.
       Gleiches Muster wie beim top-Wert der Basisregel. */
    .story-slide__icon-lg--amy-filmklappe {
        left: 30px;
    }

    /* ── Slide 2 (Nachhaltigkeit) ──
       Wie auf Slide 1: Textblock auf die Breite des Fließtextes begrenzt und
       mittig, dazu mehr Luft nach oben. Die Illustration samt Zitat liegt in einer
       eigenen Ebene darunter; der größere gap schiebt beide tiefer, ohne den Text
       zu bewegen. Das Zitat wächst mit der Illustration mit (1.25rem ist der
       Handywert, dort begrenzt die Slidehöhe). */
    .story-slide__inner--nachhaltigkeit .story-slide__text {
        max-width: 34rem;
        margin-inline: auto;
    }

    .story-slide__inner--nachhaltigkeit {
        padding-top: 3rem;
        gap: 3.5rem;
    }

    .story-slide__inner--nachhaltigkeit .story-slide__quote-line,
    [data-layer-home="nachhaltigkeit"] .story-slide__quote-line {
        font-size: 1.5rem;
    }

    /* ── Slide 3 (Perspektive Aktion Kindertraum) ──
       Das Bildfenster lief über die volle Slidebreite, der Text darunter brach
       schon bei 34rem um – zwei verschiedene Kanten übereinander. Beide stehen
       jetzt auf derselben Breite und mittig. Die 16:9-Proportion bleibt, das
       Fenster wird dadurch entsprechend flacher. */
    #perspektive-akt .story-slide__inner,
    #perspektive-akt-ben .story-slide__inner {
        padding-top: 3rem;
    }

    #perspektive-akt .story-slide__text,
    #perspektive-akt .story-slide__tilt,
    #perspektive-akt-ben .story-slide__text,
    #perspektive-akt-ben .story-slide__tilt {
        max-width: 34rem;
        margin-inline: auto;
    }

    /* Ben und Luisa haben eine zusätzliche Slide gleichen Aufbaus, aber mit eigener
       ID (#perspektive-akt-ben). Die Regeln des Handy-Blocks, die das Bildfenster
       auf 16:9 bringen, sind auf #perspektive-akt gebunden und griffen hier nie –
       das Fenster blieb im Desktop-Verhältnis 4:3 und war 465 statt 306px hoch,
       weshalb der lange Text darunter bis unter die Navigationsknöpfe lief.
       Hier nachgezogen; auf dem Handy bleibt es beim Bestand (dort wird dieses
       Fenster ohnehin nicht angezeigt). */
    #perspektive-akt-ben .story-slide__tilt {
        width: 100%;
        aspect-ratio: 16 / 9;
    }

    /* Die Bildspalte wächst hier per flex:1 1 320px über ihren Inhalt hinaus und
       schob das Fenster im column-reverse-Stapel nach unten – auf Slide 3 steht
       dieselbe Box auf 0 0 auto. Damit beginnt das Bild wie dort direkt unter dem
       padding-top. */
    #perspektive-akt-ben .story-slide__media--center {
        flex-grow: 0;
    }

    #perspektive-akt-ben .story-slide__tilt .story-slide__photo {
        width: 100%;
        height: 100%;
        max-height: none;
        max-width: none;
        object-fit: cover;
        object-position: center 30%;
    }

    /* ── Slide 4 (Perspektive Unterstützer) ──
       Textblock wie auf den übrigen Slides mittig und mit mehr Luft nach oben.
       Die Illustration liegt in diesem Block und wird per [data-bleed] ausgehängt;
       verschoben wird sie deshalb über position/top, nicht über transform (das
       gehört der Schwebe-Animation) und nicht über margin (das Bleed-Script misst
       vor dem Aushängen). Sie rückt aus dem Fließtext heraus in die freie Fläche
       neben dem Foto. Nach rechts wandert sie dabei mit dem schmaleren Textblock –
       ihre Ausgangslage wird an dessen linker Kante gemessen. */
    #perspektive-unterstuetzer .story-slide__inner {
        padding-top: 3rem;
    }

    #perspektive-unterstuetzer .story-slide__text {
        max-width: 34rem;
        margin-inline: auto;
    }

    .story-slide__icon--float {
        position: relative;
        top: 260px;
    }

    /* Vier Kinder haben auf Slide 4 mehr Text; dort reicht der gemeinsame Versatz
       nicht und die Illustration lag auf „mehr erfahren". Werte je Kind gemessen:
       Illustrationsoberkante 24px unter dem Ende des Textblocks. */
    /* Das Tor rückt nach rechts und etwas höher: Durch die Verschiebung des Fotos
       (Regel darunter) lägen die Köpfe sonst direkt darunter. */
    .story-slide__icon--kevin-goal {
        top: 220px;
        left: 380px;
    }

    /* Jans Familienfoto etwas größer als der Handywert (1.1). Origin unten, damit
       es bündig mit der Slidekante bleibt statt beim Wachsen unten hinauszulaufen. */
    #perspektive-unterstuetzer .story-slide__media--photo-xl .story-slide__photo--jan-supporter {
        transform: translateX(18px) scale(1.2);
        transform-origin: bottom center;
    }

    /* Kevins Familienfoto steht mittig und lässt links wenig Raum für das Tor;
       beide rücken auseinander. Die Freisteller werden auf dieser Slide ohnehin
       über left positioniert (siehe Handy-Block), der Wert setzt dort an. */
    .story-slide__media--photo-xl .story-slide__photo--kevin-supporter {
        left: -60px;
    }

    /* Ausgangswert ist hier 80px (Basisregel) – anders als bei den übrigen Kindern,
       die der Handy-Block auf 0 setzt. Der Wert unten verschiebt das Foto also um
       60px nach links, nicht um seinen eigenen Betrag. */
    .story-slide__media--photo-xl .story-slide__photo--maja-supporter {
        left: 20px;
    }

    /* Der Helm rückt mit nach links, weil das Familienfoto (Regel weiter unten)
       nach links versetzt ist und sein Riemen sonst über dem Vater liegt. */
    .story-slide__icon--maja-helmet {
        top: 351px;
        left: -35px;
    }

    /* Matheas Pfote: nach links unten, weg vom Fließtext und aus der Mitte, wo
       Hund und Kind stehen. */
    .story-slide__icon--mathea-paw {
        top: 340px;
        left: -120px;
    }

    /* Connors Matte lag über dem Kopf seines Bruders – nach rechts in die freie
       Fläche. left/top, weil die Illustration per data-bleed ausgehängt wird. */
    .story-slide__icon--connor-matte {
        top: 311px;
        left: 200px;
    }

    .story-slide__icon--lilly-fairy {
        top: 337px;
    }

    /* Ben und Luisa haben auf dieser Slide ein Motivpaar statt eines einzelnen
       Motivs. Es ist entsprechend breiter und lag über dem Fließtext – deshalb
       deutlich nach rechts und etwas tiefer als der gemeinsame Wert. left/top,
       nicht translate: Das Paar wird per data-bleed ausgehängt. */
    .story-slide__icon-pair--floating {
        left: 200px;
        top: 320px;
    }

    /* Ben und Luisa haben auf Slide 2 ein Motivpaar statt einer großen
       Illustration. Dessen Breite ist clamp(135px, 12vw, 190px) – bei 820px
       ergibt 12vw nur 98px, es greift also die Untergrenze und die Motive
       wuchsen überhaupt nicht mit: von 28 % Slidebreite auf dem Handy blieben
       16 %. Der Selektor entspricht der Basisregel, weil die Motive per
       data-bleed ausgehängt werden und Vorfahren wie __inner dabei verlieren. */
    .story-slide__illustration-pair--large .story-slide__icon-lg {
        width: clamp(135px, 20vw, 210px);
    }

    /* Das Motivpaar tiefer, weg vom Zitat. Über position/top, weil der Container
       per data-bleed ausgehängt wird: Ein translate steckte schon in der Messung
       des Bleed-Scripts und käme danach ein zweites Mal obendrauf. */
    .story-slide__illustration-pair--large {
        position: relative;
        top: 60px;
    }

    .story-slide__icon-pair--intro img {
        width: 13.9vw;
        height: 13.9vw;
    }

    .story-slide__icon-pair--floating img {
        width: 19.3vw;
        height: 19.3vw;
    }

    /* ── Traum-Marker auf dem Teaser (Slide 5) ──
       Der mobile Wert left:3px ist auf die dortige Lage des Fotocontainers
       gerechnet. Auf dem Tablet beginnt dieser Container links außerhalb der
       Slide, wodurch der Marker angeschnitten wurde – auf allen neun Seiten stand
       "RAUM" statt "TRAUM". Der größere Wert rückt ihn wieder vollständig ins
       Bild. */
    /* Connors Teaser (auf der Seite von Ben und Luisa): Sein Haar steht hoch, der
       Punkt des Markers landet mit dem gemeinsamen Wert mitten darin. 30px weiter
       links. Der Verweis darunter rückt 60px tiefer, weg vom Kopf – er trägt keine
       eigene Klasse, deshalb über das Linkziel angesprochen. */
    .story-quote--teaser .story-slide__label.story-slide__label--teaser-connor {
        left: 114px;
    }

    [data-layer-home="teaser"] .story-quote__cta[href="connor"],
    .story-quote--teaser .story-quote__cta[href="connor"] {
        top: 290px;
    }

    /* Lillys Teaser (auf Kevins Seite) und Matheas (auf Majas Seite): Marker weiter
       links, Verweis tiefer. Beide Kinder haben viel Haar, der Punkt landet mit dem
       gemeinsamen Wert sonst mitten darin. */
    .story-quote--teaser .story-slide__label.story-slide__label--teaser-lilly,
    .story-quote--teaser .story-slide__label.story-slide__label--teaser-mathea {
        left: 114px;
    }

    /* Willis Teaser (auf Matheas Seite): Das Foto ist unten angeschnitten – nach
       oben geschoben, damit mehr vom Motiv sichtbar wird. Sein Marker trägt keine
       eigene Klasse, deshalb über das Foto in derselben Box angesprochen; er wandert
       um dieselben 80px mit nach oben (sonst läge sein Punkt im Gesicht) und
       zusätzlich nach links. */
    .story-quote--teaser .story-slide__photo--willi-teaser {
        translate: 0 -80px;
    }

    .story-quote--teaser .story-slide__media--photo:has(.story-slide__photo--willi-teaser) .story-slide__label {
        left: 114px;
        top: -114px;
    }

    [data-layer-home="teaser"] .story-quote__cta[href="willi"],
    .story-quote--teaser .story-quote__cta[href="willi"] {
        top: 290px;
    }

    [data-layer-home="teaser"] .story-quote__cta[href="lilly"],
    .story-quote--teaser .story-quote__cta[href="lilly"],
    [data-layer-home="teaser"] .story-quote__cta[href="mathea"],
    .story-quote--teaser .story-quote__cta[href="mathea"],
    [data-layer-home="teaser"] .story-quote__cta[href="jan"],
    .story-quote--teaser .story-quote__cta[href="jan"] {
        top: 290px;
    }

    /* Auf 184px korrigiert (09.09.2026): Der Punkt des Markers soll am Haaransatz
       des nächsten Kindes liegen. Auf dem Desktop sitzt er bei 42,5 % der
       Fotobreite; das Teaser-Foto liegt auf dem Tablet bei allen neun Kindern
       gleich (−14…820), daher ein gemeinsamer Wert. */
    .story-quote--teaser .story-slide__label {
        left: 184px;
    }

    /* Amys Teaser führt zu Ben UND Luisa und trägt daher zwei Marker. Sie werden
       nur im Handy-Block auseinandergezogen, weshalb sie hier übereinander lagen.
       Gleiche Aufteilung wie dort: einer links, einer rechts. */
    /* Werte aus der Desktop-Fassung abgeleitet (Punkt am Haaransatz des jeweiligen
       Kindes, gemessen als Anteil am Foto-Rechteck): Bens Punkt bei 17,2 % der
       Fotobreite, Luisas linke Markerkante bei 67,2 %. Die negativen top-Werte
       sind korrekt – das Foto ragt oben über seine Box hinaus, die Köpfe liegen
       entsprechend über deren Oberkante. */
    .story-quote--amy-next .story-slide__label--teaser-ben {
        left: 23px;
        right: auto;
        top: -24.5%;
    }

    .story-quote--amy-next .story-slide__label--teaser-luisa {
        left: auto;
        right: 153px;
        top: -14.5%;
    }

    /* Der Verweis liegt hier sonst auf Bens Gesicht – dieser Teaser trägt zwei
       Köpfe, die Fläche links unten ist schmaler als bei den übrigen. Deshalb
       60px weiter links und 80px tiefer als der gemeinsame Wert. */
    /* Zwei Klassen am selben Element, damit diese Regel die gemeinsame gewinnt:
       Die steht weiter unten in der Datei und hätte bei gleicher Spezifität
       Vorrang. */
    .story-quote--teaser .story-quote__cta.story-quote__cta--amy-next,
    [data-layer-home="teaser"] .story-quote__cta.story-quote__cta--amy-next {
        left: calc(284px - 50vw);
        top: 310px;
    }

    /* Das Teaser-Zitat trägt die Slide und stand mit dem Handywert (1.25rem)
       verloren in der Fläche. Der Desktop setzt hier 36px; 1.75rem liegt
       dazwischen und bleibt in der 340px breiten Bühne dreizeilig. */
    .story-quote--teaser .story-slide__quote-line,
    [data-layer-home="teaser"] .story-slide__quote-line {
        font-size: 1.75rem;
    }

    /* Der Verweis auf die nächste Geschichte stand unter dem Zitat mitten in der
       Bühne und lag nach dessen Vergrößerung auf dem Traum-Marker. Er rückt in die
       freie Fläche links unten: Die Bühne ist 340px breit und in der Slide
       zentriert, ihre linke Kante liegt also bei (100vw − 340px) / 2 – der
       calc-Wert bringt den Verweis von dort auf den Slide-Rand (24px), in jeder
       Breite des Bereichs. */
    .story-quote--teaser .story-quote__cta,
    [data-layer-home="teaser"] .story-quote__cta {
        position: relative;
        left: calc(344px - 50vw);
        top: 230px;
    }

    /* ── Zitat-Bühne und Stern auf dem Teaser ── */

    .story-quote__stage,
    [data-layer-home="teaser"].story-quote__stage {
        width: 43.9vw;
    }

    /* Die Teaser-Bühne war auf 340px gedeckelt (Handywert). Mit dem größeren Zitat
       passten zwei nebeneinanderliegende Kästen einer Zeile nicht mehr hinein und
       die Flex-Zeile brach um – bei Kevin ("Kopftuch? brauche ich") schon ab
       1.4rem, bei Connors Teaser ab 1.6rem. Gemessen über alle neun Zitate ist die
       längste Zeile 428px breit; 440px hält jede von ihnen einzeilig.
       Fester Wert statt vw: Am unteren Ende des Bereichs (641px) ergäbe ein
       relativer Wert wieder zu wenig, und 440px passen dort noch in die Slide.
       Der Selektor greift den ausgehängten Zustand – die Bühne ist nach dem
       Herausheben kein Nachkomme von .story-quote--teaser mehr, weshalb die
       vorhandene 62.2vw-Regel für sie nie galt. */
    .story-quote--teaser .story-quote__stage,
    [data-layer-home="teaser"].story-quote__stage {
        width: 440px;
        max-width: 440px;
    }

    .story-quote--teaser .story-quote__stage,
    [data-layer-home="teaser"].story-quote__stage.story-quote--teaser {
        width: 62.2vw;
    }

    /* Foto und Traum-Marker der Teaser-Slide rücken gemeinsam nach rechts, damit
       links Platz für Zitat und Verweis bleibt. Verschoben wird der Container,
       nicht das Foto – so behält der Marker seine Lage am Kopf, ohne eigenen Wert.
       translate als Einzeleigenschaft, damit transform frei bleibt. */
    .story-quote--teaser .story-slide__media--photo {
        translate: 30px 0;
    }

    /* Der Stern wächst mit dem größeren Zitat mit (380 → 640px), sonst ragen die
       weißen Kästen seitlich über die Kontur hinaus. Die max-width des
       Handy-Blocks muss dabei mit erhöht werden – sie deckelte die vorhandene
       69.5vw-Regel auf 380px, weshalb die nie sichtbar wurde.
       Der top-Wert gleicht das Wachstum aus: Die Basisregel zentriert den Stern
       über translate(-50%), mit der größeren Höhe wäre er sonst um die halbe
       Differenz nach oben gerutscht und hätte in der Navigationsleiste gestanden.
       274px halten ihn an derselben Bildschirmposition wie zuvor.
       Nicht zu verwechseln mit der Fassung im reduzierten Modus (schmale, niedrige
       Handys): Dort ist dieses Bild ausgeblendet und der Stern wird als
       Slide-Hintergrund gezeichnet, damit er hinter dem Foto liegt. Hier gilt das
       nicht – die Bühne steht über dem Foto, aber der Stern überlappt es auf dem
       Tablet gar nicht. */
    .story-quote__star {
        width: 640px;
        max-width: 640px;
        top: 354px;
    }

    /* Zitat und Stern rücken gemeinsam 80px tiefer in die Slide. Das Zitat über
       position/top statt margin, damit der Fluss der Bühne unverändert bleibt und
       der Verweis darunter stehen bleibt, wo er sitzt; der Stern bekommt dieselben
       80px auf seinen eigenen top-Wert (274 → 354). Nebeneffekt: Seine obere
       Spitze steht jetzt vollständig unter der Navigationsleiste statt hinter
       ihr. */
    .story-quote--teaser .story-slide__quote,
    [data-layer-home="teaser"] .story-slide__quote {
        position: relative;
        top: 80px;
    }
}


/* ══ 11. Reduzierte Bewegung (prefers-reduced-motion: reduce) ══════════════════
   Systemeinstellung „Bewegung reduzieren" (macOS/iOS/Windows/Android). Alle
   Animationen, die ohne Zutun endlos laufen, werden abgeschaltet: Schweben der
   Illustrationen, Marker und Karten, Pfeil-Wackeln und -Pulsieren, das
   Wisch-Intro. Der Crossfade der Galerien ist schon in Block 4 abgedeckt; der
   Karten-Autoplay, der Scroll-Hinweis und die Slide-Animationen werden im JS
   an derselben Systemeinstellung abgeschaltet (home.js, slide-scroll.js).
   Bewusst nicht angefasst: kurze Übergänge (transition) auf Nutzeraktionen,
   etwa das Aufklappen des Modals – sie sind Rückmeldung, keine Dekoration.
   Steht am Dateiende, damit die Regeln alle Block-Varianten überstimmen. ── */
@media (prefers-reduced-motion: reduce) {
    .story-slide__icon,
    .story-slide__icon-pair--intro img,
    .story-slide__icon-pair--floating img,
    .story-slide__icon-lg,
    .story-slide__label,
    .story-quote__cta-arrow,
    .story-jump__arrow--pulse,
    .swap-card__float,
    .swap-intro__hand,
    .swap-intro__hand-inner,
    .swap-intro__touch {
        animation: none;
    }

    /* Das Wisch-Intro (Hand + Fingerabdruck) ergibt ohne Animation kein Bild – ganz weg. */
    .swap-intro {
        display: none;
    }
}


/* ══ 12. Consent-Banner, Footer-Button, YouTube-2-Klick ═════════════════════════
   Neuer Block am Dateiende (Reihenfolge ist kaskadenrelevant). Markup und Logik:
   consent.js / home.js, Konzept in _overview/TRACKING-PLAN.md (B2, B5). ── */

/* Banner unten fixiert, über Sticky-Nav (z 90) und Modal (z 100), unter dem Skip-Link.
   Solange er sichtbar ist, setzt consent.js --consent-height; die Sticky-Navigation der
   Story-Seiten rückt um diesen Betrag nach oben (Regel darunter), sonst wären die
   Slide-Pfeile verdeckt. */
.consent {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 150;
    padding: 1rem 1.5rem;
    padding-bottom: max(1rem, env(safe-area-inset-bottom));
    background: #1c1c1c;
    color: #fff;
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.3);
}

.consent__inner {
    max-width: 1100px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.consent__text {
    flex: 1 1 28rem;
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.45;
}

.consent__text a {
    color: var(--color-yellow);
}

.consent__actions {
    display: flex;
    gap: 0.75rem;
    flex: 0 0 auto;
}

/* Ablehnen und Akzeptieren bewusst identisch (gleiche Größe, Farbe, Ebene). */
.consent__button {
    height: 44px;
    padding: 0 1.5rem;
    border: 0;
    border-radius: 999px;
    background: var(--color-yellow);
    color: var(--color-blue);
    font: inherit;
    font-weight: 700;
    font-size: 0.9rem;
    text-transform: uppercase;
    cursor: pointer;
}

.consent__button:hover,
.consent__button:focus-visible {
    background: #fff;
}

@media (max-width: 640px) {
    .consent__actions {
        width: 100%;
    }

    .consent__button {
        flex: 1 1 0;
    }
}

.story-jump {
    bottom: calc(1.5rem + var(--consent-height, 0px));
}

/* „Cookie-Einstellungen“ im Footer: ein Button in Link-Optik (kein href – <base> würde
   ein „#" auf die Startseite umbiegen). */
.footer__legal-button {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: #fff;
    cursor: pointer;
}

.footer__legal-button:hover {
    text-decoration: underline;
}

/* YouTube-2-Klick: Platzhalter in den Maßen des iframes; das echte Video kommt erst
   nach dem Klick (home.js), bis dahin fließt nichts zu Google. */
.video-consent {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    width: 100%;
    aspect-ratio: 16 / 9;
    margin: 0 auto 3.5rem;
    border: 0;
    border-radius: 12px;
    background: var(--gradient-dark);
    color: #fff;
    overflow: hidden;
}

/* Der Button trägt nur Play-Symbol und Titel; der Hinweis mit Link steht daneben
   (ein Link in einem Button wäre ungültiges HTML). */
.video-consent__button {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.video-consent__play {
    width: 88px;
    height: 88px;
    border-radius: 50%;
    background: var(--color-yellow);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.2s ease;
}

.video-consent__play svg {
    width: 36px;
    height: 36px;
    margin-left: 5px;
    fill: var(--color-blue);
}

.video-consent__button:hover .video-consent__play,
.video-consent__button:focus-visible .video-consent__play {
    transform: scale(1.08);
}

.video-consent__title {
    font-weight: 700;
    font-size: 1.25rem;
}

.video-consent__hint {
    max-width: 34rem;
    margin: 0;
    padding: 0 1.5rem;
    font-size: 0.85rem;
    opacity: 0.75;
    text-align: center;
}

.video-consent__hint a {
    color: var(--color-yellow);
}

/* Handy: Der 16:9-Kasten ist bei 390px Breite nur ~190px hoch – Play-Kreis, Titel
   und Hinweis in Desktop-Größe liefen unten heraus (11.09.2026). */
@media (max-width: 640px) {
    .video-consent,
    .video-consent__button {
        gap: 0.5rem;
    }

    .video-consent__play {
        width: 56px;
        height: 56px;
    }

    .video-consent__play svg {
        width: 24px;
        height: 24px;
        margin-left: 3px;
    }

    .video-consent__title {
        font-size: 1rem;
    }

    .video-consent__hint {
        font-size: 0.72rem;
        line-height: 1.4;
        padding: 0 1rem;
    }
}


/* ══ 13. Hinweis: Ausstellungsorte und -termine (Startseite) ═══════════════════
   Gelber Bereich direkt unter dem Hero, vor der Geschichten-Übersicht. ──────── */
.notice {
    background: var(--color-yellow);
    color: #333;
}

.notice__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 4rem 2rem;
}

.notice__title {
    margin: 0 0 1.5rem;
    font-size: 1.75rem;
    font-weight: 700;
}

.notice__title-ending {
    white-space: nowrap;
}

.notice__location + .notice__location {
    margin-top: 1.25rem;
}

.notice__location-title {
    margin: 0 0 0.15rem;
    font-size: 1.3rem;
    font-weight: 700;
    line-height: 1.25;
}

.notice__text {
    margin: 0;
    padding-left: 1rem;
    font-size: 1.05rem;
    line-height: 1.45;
}

@media (max-width: 640px) {
    .notice__title {
        font-size: 1.66rem;
        line-height: 1.19;
    }

    .notice__location-title {
        font-size: 1.15rem;
    }

    .notice__text {
        padding-left: 0;
        font-size: 0.95rem;
        text-wrap: pretty; /* wo unterstützt: keine einzelnen Wörter in der letzten Zeile */
    }
}
