/* ============================================================
   PDF Extender Landingpage
   ============================================================ */

/* ---------- Reset & Tokens ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg: #EDEDF0;
  --surface: #F5F5F7;
  --card: #FFFFFF;
  --ink: #101014;
  --ink-soft: #6B6B74;
  --ink-faint: #9A9AA3;
  --accent: #2563EB;
  --accent-bright: #3B82F6;
  --accent-soft: #DBEAFE;
  --radius-xl: 34px;
  --radius-lg: 22px;
  --radius-md: 14px;
  --radius-pill: 999px;
  --shadow-lg: 0 30px 80px rgba(16, 16, 20, .10), 0 6px 20px rgba(16, 16, 20, .06);
  --shadow-md: 0 14px 40px rgba(16, 16, 20, .08);
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Inter, Roboto, "Helvetica Neue", sans-serif;
}

html { scroll-behavior: smooth; }

body {
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img, svg { display: block; max-width: 100%; }

:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: .5em;
  font-family: inherit; font-weight: 600; text-decoration: none;
  border-radius: var(--radius-pill); border: 0; cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.btn--primary { background: var(--accent); color: #fff; box-shadow: 0 6px 18px rgba(37, 99, 235, .35); }
.btn--primary:hover { background: var(--accent-bright); transform: translateY(-1px); }
.btn--sm { padding: .55em 1.25em; font-size: 1.09rem; }
.btn--lg { padding: .85em 1.8em; font-size: 1.32rem; }

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: .8rem clamp(1.2rem, 4vw, 3rem);
  background: rgba(237, 237, 240, .72);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid rgba(16, 16, 20, .06);
}
.brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; color: var(--ink); }
.brand__logo { width: 36px; height: 36px; border-radius: 9px; }
.brand__name { font-weight: 800; font-size: 1.32rem; letter-spacing: -.02em; }

/* ---------- Outro & Footer ---------- */
.outro {
  max-width: 760px; margin: 0 auto; text-align: center;
  padding: clamp(5rem, 12vh, 9rem) 1.5rem;
}
.outro__title { font-size: clamp(2.3rem, 5.2vw, 3.7rem); font-weight: 800; letter-spacing: -.03em; line-height: 1.05; }
.outro__sub { margin: 1.1rem auto 2rem; max-width: 34em; color: var(--ink-soft); font-size: 1.32rem; }

/* ---- CTA-Morph: Export-Balken wird zum „Jetzt laden"-Button ----
   Nur im Desktop-Journey-Modus (html.mode-pinned); ohne JS, bei Reduced
   Motion und im Stacked-Fallback bleibt es ein normaler Button. */
html.mode-pinned .cta-morph {
  position: relative; overflow: hidden; justify-content: center;
  transition:
    width .55s cubic-bezier(.4, 0, .2, 1),
    height .55s cubic-bezier(.4, 0, .2, 1),
    padding .55s cubic-bezier(.4, 0, .2, 1),
    box-shadow .4s ease, background .4s ease, opacity .35s ease;
}
html.mode-pinned .cta-morph .cta-morph__fill {
  position: absolute; inset: 0; border-radius: inherit;
  background: var(--accent);
  transform: scaleX(0); transform-origin: left center;
}
html.mode-pinned .cta-morph .cta-morph__label {
  position: relative;
  transition: opacity .3s ease .2s;
}
html.mode-pinned .cta-morph.is-bar {
  width: min(30rem, 72vw); height: 8px; padding: 0;
  background: var(--accent-soft); box-shadow: none;
}
html.mode-pinned .cta-morph.is-bar .cta-morph__label { opacity: 0; transition: opacity .15s ease; }
html.mode-pinned .cta-morph.is-button { width: 11.5em; height: 3.15em; padding: 0; }
/* Gehaltenes Finale: das Outro liegt in der Journey, also bleibt die klebende
   iPad-Bühne aktiv (iPad bleibt sichtbar). Die Kopfzeile wird ausgeblendet,
   das Outro liefert nur Scroll-Strecke. Der Balken ist FEST am unteren
   Viewport-Rand verankert (position: fixed) — so bleibt er immer UNTER dem
   iPad und kann nicht darüber wandern; er lädt beim Weiterscrollen durch und
   morpht dort zum „Jetzt laden"-Button. Sichtbar nur, während das Outro läuft. */
/* Finale: Titel, Subline und Balken sind NORMALE Flow-Elemente am Ende der
   Journey — sie scrollen unter dem (geschrumpften, hochgestiegenen) iPad ins
   Bild und stehen dort fest auf der Seite. Kein Fixed-Overlay, kein Fade. */
html.mode-pinned .outro {
  /* 123vh statt 150vh: die Balken-Fill-Strecke haengt linear an der
     Outro-Hoehe (Start = Balken sichtbar, Ende = 'bottom 99%'); −27vh
     kuerzt sie um ~20% -> man muss 20% weniger scrollen, bis der Balken
     voll ist. Finale/Rast (top-basiert) bleiben unberuehrt. */
  min-height: 123vh; max-width: none; padding: 0 1.5rem 8vh;
  position: relative; z-index: 3;
}
/* Der Textblock scrollt hoch, RASTET ein und bleibt dort stehen (sticky) —
   weiteres Scrollen lädt nur noch den Balken durch.
   top: bei hohen Viewports 62vh; bei niedrigen deckelt 100vh−330px die
   Position, damit Titel + Subline + Button + Footer (≈290px) auch am
   Seitenende ohne Hochdrücken unter dem geparkten iPad Platz haben.
   margin-top 50vh: der Block betritt den Viewport erst bei Outro-Top 50vh —
   das iPad ist ab 70vh fertig geparkt (script.js), der Titel kreuzt seine
   Zone also nie. Rastmoment: Outro-Top = top − 50vh (morph-Start ebd.). */
html.mode-pinned .outro__stack {
  position: sticky; top: min(62vh, calc(100vh - 330px)); margin-top: 50vh;
  display: flex; flex-direction: column; align-items: center;
}
html.mode-pinned .outro__title { margin: 0; font-size: clamp(1.84rem, 2.76vw, 2.65rem); }
html.mode-pinned .outro__sub { margin: .8rem auto 1.6rem; font-size: 1.21rem; }

.site-footer {
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding: .55rem clamp(1.2rem, 4vw, 3rem);
  border-top: 1px solid rgba(16, 16, 20, .08);
  color: var(--ink-soft); font-size: .85rem;
  /* Auf index liegt der Footer in der .journey — über der geklebten
     Bühne (z-index 1) und dem Outro (z-index 3) halten. */
  position: relative; z-index: 4; background: var(--bg);
}
.site-footer__links { display: flex; gap: 1.1rem; }
.site-footer__links a { color: inherit; text-decoration: none; }
.site-footer__links a:hover { color: var(--ink); text-decoration: underline; }

/* ---------- Rechtsseiten (Impressum / Datenschutz) ---------- */
.legal {
  max-width: 720px; margin: 0 auto;
  padding: clamp(2.5rem, 7vh, 4.5rem) 1.5rem clamp(4rem, 10vh, 6rem);
}
.legal h1 { font-size: clamp(2rem, 4.5vw, 2.8rem); font-weight: 800; letter-spacing: -.03em; line-height: 1.1; }
.legal__meta { margin-top: .6rem; color: var(--ink-faint); }
.legal h2 { margin-top: 2.4rem; font-size: 1.35rem; font-weight: 700; letter-spacing: -.02em; }
.legal h3 { margin-top: 1.6rem; font-size: 1.08rem; font-weight: 700; }
.legal p { margin-top: .8rem; color: var(--ink-soft); }
.legal ul { margin: .8rem 0 0 1.3rem; color: var(--ink-soft); }
.legal li { margin-top: .35rem; }
.legal a { color: var(--accent); text-decoration: none; }
.legal a:hover { text-decoration: underline; }

/* ---------- Reduced Motion (Basis) ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ============================================================
   App-Mockup (Container-Query-skaliert, Zustände via data-step)
   ============================================================ */
.mockup {
  container-type: inline-size;
  aspect-ratio: 4 / 3;
  width: 100%;
  background: var(--surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
  display: grid;
  grid-template-columns: 30% 1fr;
  gap: 2.4cqw;
  padding: 2.6cqw;
  user-select: none;
}

/* ---- Sidebar ---- */
.mockup__side { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.mockup__siderow { display: flex; align-items: center; justify-content: space-between; }
.mockup__applogo { width: 3.4cqw; height: 3.4cqw; border-radius: 22%; }
.mockup__add {
  width: 4.2cqw; height: 4.2cqw; border-radius: 50%;
  background: var(--card); color: var(--ink);
  font-size: 2.4cqw; line-height: 1;
  display: grid; place-items: center;
  box-shadow: 0 2px 10px rgba(16, 16, 20, .08);
  position: relative;
}
.mockup__appname { font-weight: 800; font-size: 2.4cqw; letter-spacing: -.02em; margin-top: 1cqw; }

.mockup__filezone { display: grid; margin-top: 2.2cqw; }
.mockup__filezone > * { grid-area: 1 / 1; }

.filecard {
  background: var(--ink); color: #fff;
  border-radius: 1.6cqw; padding: 1.3cqw 1.5cqw;
  transition: opacity .4s ease, transform .4s ease, box-shadow .35s ease;
}
.filecard__meta { font-size: .95cqw; letter-spacing: .08em; color: rgba(255, 255, 255, .55); }
.filecard__row { display: flex; align-items: center; gap: 1cqw; margin-top: .4cqw; }
.filecard__name { font-size: 1.35cqw; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.filecard__pages { font-size: 1.7cqw; font-weight: 700; }
.filecard__trash { width: 1.4cqw; height: 1.4cqw; color: rgba(255, 255, 255, .6); flex-shrink: 0; }

.fileempty { text-align: center; align-self: center; padding: 2cqw 0; opacity: 0; transition: opacity .4s ease; }
.fileempty__kicker { font-size: .95cqw; letter-spacing: .12em; color: var(--ink-faint); font-weight: 600; }
.fileempty__text { font-size: 1.3cqw; font-weight: 600; margin-top: .5cqw; }

.panel {
  margin-top: auto;
  background: var(--card); border-radius: 2cqw; padding: 1.8cqw;
  transform-origin: left bottom;
  transition: transform .7s cubic-bezier(.3, .9, .3, 1), box-shadow .7s ease;
}
.panel__title { font-size: 1cqw; font-weight: 700; letter-spacing: .14em; margin-bottom: .6cqw; }
.panel__group { transition: opacity .4s ease; }
.panel__label { font-size: .85cqw; font-weight: 600; letter-spacing: .12em; color: var(--ink-faint); margin: 1.1cqw 0 .5cqw; }
.seg {
  display: flex; gap: .2cqw;
  background: #fff; border-radius: var(--radius-pill); padding: .35cqw;
  box-shadow: inset 0 0 0 1px rgba(16, 16, 20, .04), 0 1px 4px rgba(16, 16, 20, .05);
}
.seg__opt {
  position: relative;
  flex: 1; text-align: center; font-size: 1.02cqw; font-weight: 600;
  padding: .55cqw .4cqw; border-radius: var(--radius-pill);
  white-space: nowrap; transition: background .3s, color .3s;
}
.seg__opt--on { background: var(--ink); color: #fff; }

/* ---- Hauptbereich ---- */
.mockup__main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.mockup__topbar { display: flex; align-items: flex-start; justify-content: space-between; gap: 2cqw; margin-bottom: 1.6cqw; transition: opacity .3s ease; }
.mockup__docmeta { min-width: 0; }
.mockup__kicker { font-size: .95cqw; letter-spacing: .1em; color: var(--ink-faint); font-weight: 600; }
.mockup__doctitle { font-size: 2.2cqw; font-weight: 800; letter-spacing: -.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.doctitle-empty { color: var(--ink-faint); display: none; }
.mockup__actions { display: flex; align-items: center; gap: .9cqw; flex-shrink: 0; }
.iconbtn {
  width: 3.2cqw; height: 3.2cqw; border-radius: 50%;
  background: var(--card); display: grid; place-items: center;
  box-shadow: 0 2px 8px rgba(16, 16, 20, .06);
}
.iconbtn svg { width: 45%; height: 45%; color: var(--ink); }
.probadge { background: var(--ink); color: #fff; font-size: 1.15cqw; font-weight: 700; padding: .8cqw 1.7cqw; border-radius: var(--radius-pill); }
.exportbtn {
  position: relative;
  display: inline-flex; align-items: center; gap: .6cqw;
  background: var(--accent); color: #fff;
  font-size: 1.15cqw; font-weight: 700;
  padding: .8cqw 1.6cqw; border-radius: var(--radius-pill);
  box-shadow: 0 4px 14px rgba(37, 99, 235, .4);
  transition: background .35s, color .35s, box-shadow .35s;
}
.exportbtn svg { width: 1.2cqw; height: 1.2cqw; }
.exportcount::after { content: "1"; }

/* ---- Vorschau ---- */
.preview { flex: 1; min-height: 0; display: grid; }
.preview > * { grid-area: 1 / 1; }
.page {
  background: var(--card); border-radius: 1.6cqw;
  display: flex; position: relative; overflow: hidden;
  box-shadow: 0 10px 30px rgba(16, 16, 20, .06);
  transition: opacity .45s ease;
}
.page__doc { flex: 1 1 auto; min-width: 0; padding: 3cqw 2.6cqw; }
.page__heading { font-size: 1.15cqw; font-weight: 700; text-decoration: underline; margin-bottom: 1.4cqw; }
.skl { height: .8cqw; border-radius: .4cqw; background: #D9DAE0; margin-bottom: 1cqw; width: var(--w, 80%); }
.skl--sub { margin-left: 2cqw; background: #E4E5EA; }
.page__margin {
  position: relative; flex: 0 0 auto; width: 42%;
  border-left: 2px dashed var(--accent-bright);
}
.page__rules {
  position: absolute; inset: 0 0 0 2%;
  background-image:
    linear-gradient(to bottom, #DCDEE4 1px, transparent 1px),
    linear-gradient(to right, #DCDEE4 1px, transparent 1px);
  background-size: 2.1cqw 2.1cqw;
  background-position: 0 1.4cqw;
  transition: opacity .4s ease, background-size .45s ease;
}
.page__badge {
  position: absolute; left: 50%; bottom: 3%; transform: translateX(-50%);
  background: var(--ink); color: #fff;
  font-size: .95cqw; font-weight: 600; letter-spacing: .12em;
  padding: .7cqw 1.6cqw; border-radius: var(--radius-pill);
  white-space: nowrap;
  transition: opacity .4s ease;
}
.preview__empty { display: grid; place-content: center; text-align: center; opacity: 0; transition: opacity .4s ease; }
.preview__empty .fileempty__kicker, .preview__empty .fileempty__text { opacity: 1; }

/* ============================================================
   iPad-Rahmen (dunkle Bezel um das App-Mockup)
   ============================================================ */
.ipad-fly { position: relative; container-type: inline-size; }
.ipad {
  background: linear-gradient(150deg, #1E1E24, #131317 55%, #17171B);
  border-radius: 5cqw;
  padding: 2.2cqw;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, .28),
    0 45px 90px rgba(16, 16, 20, .30),
    0 14px 32px rgba(16, 16, 20, .18);
  transform: rotate(-5deg);
  animation: ipadBob 7s ease-in-out infinite;
}
/* Nur vertikales Schweben, KONSTANTE Rotation: so bleibt das im Finale
   gerade gestellte iPad (Fly +5° hebt diese −5° exakt auf) wackelfrei. */
@keyframes ipadBob {
  0%, 100% { transform: rotate(-5deg) translateY(0); }
  50% { transform: rotate(-5deg) translateY(-12px); }
}
/* Screen clippt NICHT (Panel schwebt in Schritt 2 heraus) —
   das Mockup trägt stattdessen den passenden Innenradius. */
.ipad__screen { background: #000; border-radius: 3cqw; }
.ipad__screen > .mockup { border-radius: 3cqw; box-shadow: none; }

@media (prefers-reduced-motion: reduce) {
  .ipad { animation: none; }
}

/* ============================================================
   Mockup-Zustände: data-step auf .scrolly__stage oder .crop
   (ohne data-step = End-Zustand für No-JS)
   ============================================================ */
[data-step="1"] .filecard { opacity: 0; transform: translateY(1cqw); }
[data-step="1"] .fileempty { opacity: 1; }
[data-step="1"] .doctitle-file { display: none; }
[data-step="1"] .doctitle-empty { display: inline; }
[data-step="1"] .mockup__kicker { visibility: hidden; }
[data-step="1"] .page { opacity: 0; }
[data-step="1"] .preview__empty { opacity: 1; }
[data-step="1"] .panel__group--abstand { opacity: .45; }
[data-step="1"] .exportcount::after { content: "0"; }

[data-step="1"] .exportbtn,
[data-step="2"] .exportbtn,
[data-step="3"] .exportbtn {
  background: #C9D6F2; color: rgba(255, 255, 255, .95); box-shadow: none;
}

[data-step="1"] .page__badge,
[data-step="2"] .page__badge { opacity: 0; }

/* Puls-Ring auf dem +-Button in Schritt 1 */
[data-step="1"] .mockup__add::after {
  content: ""; position: absolute; inset: -28%;
  border: .45cqw solid var(--accent-bright); border-radius: 50%;
  animation: ringPulse 1.8s ease-out infinite;
}
@keyframes ringPulse {
  0% { transform: scale(.75); opacity: .9; }
  70%, 100% { transform: scale(1.25); opacity: 0; }
}

/* Auswahl-Ring auf der Dateikarte in Schritt 3 */
[data-step="3"] .filecard { box-shadow: 0 0 0 .5cqw var(--surface), 0 0 0 .95cqw var(--accent-bright); }

/* ---- Schritt 2: Klick-Flow (kumulative .s2-*-Klassen auf der Stage) ----
   Ausgangszustand (Schritt 1/2 vor den Klicks): SEITE Links, PAPIER Blanko,
   ABSTAND 5 mm. Der Rand liegt links der Seite; die blaue gestrichelte
   Linie sitzt dann rechts am Randbereich (sie bleibt IMMER sichtbar). */
[data-step="1"] .page__margin,
[data-step="2"]:not(.s2-rechts) .page__margin {
  order: -1;
  border-left: 0;
  border-right: 2px dashed var(--accent-bright);
}
[data-step="1"] .page__rules,
[data-step="2"]:not(.s2-rechts) .page__rules { inset: 0 2% 0 0; }

[data-step="1"] .page__rules,
[data-step="2"]:not(.s2-kariert) .page__rules { opacity: 0; }
[data-step="2"]:not(.s2-7mm) .page__rules { background-size: 1.5cqw 1.5cqw; }

/* Aktive Pillen vor dem jeweiligen Klick: Ausgangsoption an, Zieloption aus */
[data-step="1"] .panel__group--seite .seg__opt--on,
[data-step="2"]:not(.s2-rechts) .panel__group--seite .seg__opt--on,
[data-step="1"] .panel__group--papier .seg__opt--on,
[data-step="2"]:not(.s2-kariert) .panel__group--papier .seg__opt--on,
[data-step="1"] .panel__group--abstand .seg__opt--on,
[data-step="2"]:not(.s2-7mm) .panel__group--abstand .seg__opt--on {
  background: transparent; color: inherit;
}
[data-step="1"] .panel__group--seite .seg__opt:first-child,
[data-step="2"]:not(.s2-rechts) .panel__group--seite .seg__opt:first-child,
[data-step="1"] .panel__group--papier .seg__opt:first-child,
[data-step="2"]:not(.s2-kariert) .panel__group--papier .seg__opt:first-child,
[data-step="1"] .panel__group--abstand .seg__opt:first-child,
[data-step="2"]:not(.s2-7mm) .panel__group--abstand .seg__opt:first-child {
  background: var(--ink); color: #fff;
}

/* Tap-Indikator: halbtransparenter blauer Kreis mit weißem Ring —
   erscheint, hält kurz, DANN schaltet die Pille (GSAP-Choreo) */
.tap {
  position: absolute; left: 50%; top: 50%;
  width: 2.2cqw; height: 2.2cqw; margin: -1.1cqw 0 0 -1.1cqw;
  border-radius: 50%;
  background: rgba(59, 130, 246, .55);
  box-shadow: 0 0 0 .3cqw rgba(255, 255, 255, .9), 0 .3cqw 1.4cqw rgba(37, 99, 235, .45);
  opacity: 0; transform: scale(.6);
  pointer-events: none;
}

/* Die frisch „getappte" Pille bekommt einen kurzen Push */
[data-step="2"].s2-rechts .panel__group--seite .seg__opt--on,
[data-step="2"].s2-kariert .panel__group--papier .seg__opt--on,
[data-step="2"].s2-7mm .panel__group--abstand .seg__opt--on {
  animation: pillPush .38s cubic-bezier(.34, 1.56, .64, 1);
}
@keyframes pillPush { from { transform: scale(.92); } to { transform: scale(1); } }

/* Während Schritt 2 schwebt das ERWEITERUNG-Panel aus dem iPad heraus */
html.mode-pinned .scrolly__stage[data-step="2"] .panel {
  position: relative; z-index: 5;
  transform: translate(-9%, 1.5%) scale(1.3);
  box-shadow: 0 26px 60px rgba(16, 16, 20, .38);
}

/* Schritt 4: Export-Button wird „gedrückt" (Press) und pulsiert danach */
[data-step="4"] .exportbtn {
  animation:
    exportPress .4s cubic-bezier(.34, 1.56, .64, 1),
    exportPulse 1.6s .5s ease-in-out infinite;
}
@keyframes exportPress {
  0% { transform: scale(1); }
  40% { transform: scale(.92); }
  100% { transform: scale(1); }
}
@keyframes exportPulse {
  0%, 100% { transform: scale(1); box-shadow: 0 4px 14px rgba(37, 99, 235, .4); }
  50% { transform: scale(1.05); box-shadow: 0 6px 24px rgba(37, 99, 235, .55); }
}

@media (prefers-reduced-motion: reduce) {
  [data-step="1"] .mockup__add::after { animation: none; opacity: .7; transform: scale(1); }
  [data-step="4"] .exportbtn { animation: none; }
}

/* ---- Journey: EIN iPad begleitet Hero + Scrolly ---- */
.journey { position: relative; overflow: clip; }

/* Dezente Hintergrund-Deko: weiche blaue Farbflächen über die ganze Journey
   plus kleine Punkt-Raster — liegt hinter allem (z-index -1). */
.journey::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  /* Keine Fläche im Outro-Bereich (unten) — dort läuft der CTA-Balken,
     dessen helle Schiene sonst verfärbt wirkt. */
  background:
    radial-gradient(46rem 46rem at 12% 12%, rgba(37, 99, 235, .09), transparent 68%),
    radial-gradient(54rem 54rem at 88% 38%, rgba(59, 130, 246, .08), transparent 70%),
    radial-gradient(48rem 48rem at 16% 68%, rgba(37, 99, 235, .07), transparent 70%);
}
.hero::after, .scrolly::after {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  width: 11rem; height: 8rem;
  background-image: radial-gradient(rgba(37, 99, 235, .32) 1.5px, transparent 1.6px);
  background-size: 1.35rem 1.35rem;
}
.hero::after { left: clamp(1rem, 6vw, 5rem); bottom: 3rem; }
.scrolly::after { right: clamp(1.5rem, 5vw, 4.5rem); top: 34%; }

/* Zusätzliche Textur: große GEFÜLLTE blasse Formen + wenige kleine Symbole.
   Prozent-Tops skalieren mit der Journey-Höhe. Wichtig: Symbole und Formen
   liegen NICHT auf den Riesen-Nummern (1/2/4 links, 3 rechts) und nicht in
   den Punkt-Rastern; unterhalb von ~80 % (Outro/CTA-Balken) bleibt es leer. */
.bg-decor { position: absolute; inset: 0; z-index: -1; pointer-events: none; color: var(--accent); }
.bg-decor .deco { position: absolute; }
.deco--circle-lg { width: clamp(14rem, 24vw, 22rem); top: 15%; right: -6rem; opacity: .06; }
.deco--square-lg { width: clamp(16rem, 26vw, 24rem); top: 45%; left: -8rem; transform: rotate(14deg); opacity: .05; }
.deco--blob-lg { width: clamp(15rem, 25vw, 23rem); top: 62%; right: -7rem; transform: rotate(-18deg); opacity: .05; }
.deco--plus-1 { width: 2.4rem; top: 8%; left: 55%; transform: rotate(12deg); opacity: .16; }
.deco--plus-2 { width: 1.8rem; top: 40%; right: 9%; transform: rotate(-9deg); opacity: .14; }
.deco--check { width: 2.8rem; top: 5.5%; left: 38%; transform: rotate(-7deg); opacity: .15; }
.deco--spark { width: 1.6rem; top: 70%; right: 10%; transform: rotate(15deg); opacity: .15; }
.deco--dot-sm { width: 2.4rem; top: 78%; right: 16%; opacity: .09; }
/* Schmales Layout: weniger Fläche, die großen Randformen würden stören */
@media (max-width: 1023px) { .deco--circle-lg, .deco--square-lg, .deco--blob-lg { display: none; } }

/* Basis (schmal/gestapelt): Stage statisch zwischen Hero-Text und Steps */
.scrolly__stage { position: relative; padding: 2.5rem clamp(1.2rem, 5vw, 3rem) 3.5rem; }
.scrolly__stage .ipad-fly { width: min(92%, 620px); margin-inline: auto; }

/* Desktop (gilt auch ohne JS): Stage klebt im Viewport, Texte ziehen vorbei */
@media (min-width: 1024px) and (min-height: 640px) {
  html:not(.mode-stacked) .scrolly__stage {
    position: sticky; top: 0; z-index: 1;
    height: 100vh; margin-top: -100vh;
    padding: 0;
    display: flex; align-items: center;
    /* Rein dekorativ: Klicks fallen zum Scrollhinweis dahinter durch */
    pointer-events: none;
  }
  /* Rechts ist die Layout-Ruhelage (Hero, Schritt 1/3);
     nach links fliegt GSAP per xPercent auf den Wrapper. */
  html:not(.mode-stacked) .scrolly__stage .ipad-fly {
    width: min(48vw, calc((100vh - 9rem) * 1.31));
    margin: 0 4vw 0 auto;
  }
  /* Ohne JS ruht das iPad rechts im End-Zustand (mit JS fliegt GSAP) */
  html:not(.mode-stacked):not(.mode-pinned) .ipad-fly {
    transform: rotate(2.5deg);
  }
}

/* ============================================================
   Hero
   ============================================================ */
.hero {
  position: relative;
  padding: clamp(2.5rem, 8vh, 5rem) 1.5rem 5.5rem;
  text-align: center;
}
.hero__copy { max-width: 34rem; margin-inline: auto; }
.hero__title { font-size: clamp(3.1rem, 6.44vw, 5.5rem); font-weight: 800; letter-spacing: -.035em; line-height: .98; }
.hero__sub { margin-top: 1.3rem; color: var(--ink-soft); font-size: clamp(1.21rem, 1.61vw, 1.5rem); max-width: 24em; margin-inline: auto; }
.hero__cta { margin-top: 2rem; }

@media (min-width: 1024px) and (min-height: 640px) {
  /* Hero OHNE eigenen z-index: der Scrollhinweis (z-auto) liegt damit von
     Anfang an HINTER der Stage (z-index 1) — beim Ausblenden/Hochscrollen
     schwebt er nie sichtbar „im iPad". Nur die Copy hebt sich über die Stage. */
  html:not(.mode-stacked) .hero {
    min-height: 100vh;
    display: flex; align-items: center;
    padding: 0 0 0 clamp(2rem, 7vw, 7.5rem);
    text-align: left;
  }
  html:not(.mode-stacked) .hero__copy { max-width: min(30rem, 39vw); margin: 0; position: relative; z-index: 2; }
  html:not(.mode-stacked) .hero__sub { margin-inline: 0; }
}

/* Callout „Mehr Platz für Notizen" — reist am iPad mit (.ipad-fly) */
.hero__callout {
  position: absolute; right: 11%; top: 16%;
  width: clamp(110px, 24cqw, 190px);
  color: var(--accent); font-weight: 700;
  font-size: clamp(.98rem, 1.21vw, 1.15rem); line-height: 1.25;
  text-align: right; pointer-events: none;
}
.hero__callout svg { width: 62%; margin-left: auto; margin-top: .4rem; overflow: visible; }

/* Draw-on-Konvention für alle handgezeichneten Pfeile — EIN Pfad je Pfeil:
   Schwung UND Spitze wachsen als eine durchgehende Linie (dashoffset). */
.draw { stroke-dasharray: 1; stroke-dashoffset: 1; }
.hero__callout .draw { animation: drawPath .9s .6s cubic-bezier(.5, 0, .3, 1) forwards; }
@keyframes drawPath { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  .hero__callout .draw { animation: none; stroke-dashoffset: 0; }
}

/* ============================================================
   Scrollytelling — Steps, Dots, Overlays
   ============================================================ */
.scrolly { width: min(720px, 100%); margin-inline: auto; padding: 1rem 1.5rem 3rem; }
.step__kicker { color: var(--accent); font-weight: 700; letter-spacing: .12em; font-size: .98rem; }
.step__num { display: block; font-size: 7.5rem; font-weight: 800; letter-spacing: -.05em; line-height: .8; color: var(--accent); }
.step__title { font-size: clamp(2.19rem, 3vw, 3.34rem); font-weight: 800; letter-spacing: -.03em; line-height: 1.02; margin: .5rem 0 .9rem; }
.step__text { color: var(--ink-soft); font-size: 1.24rem; max-width: 26em; }
.step { margin-bottom: 3rem; }
.step__visual { display: none; margin-top: 1.4rem; }

/* Desktop-Journey: hohe, alternierende Textblöcke ziehen an der Stage vorbei */
@media (min-width: 1024px) and (min-height: 640px) {
  /* Schichtung: Riesen-Nummer (0) < iPad-Bühne (1) < Step-Text (2).
     .scrolly darf KEINEN eigenen z-index haben (sonst wäre es ein
     Stacking-Context und die Nummer läge zwangsweise ÜBER dem iPad). */
  html:not(.mode-stacked) .scrolly {
    width: 100%; margin: 0; position: relative;
    /* Kurzer Nachlauf: nach dem späten Export-Tap folgt der leere
       CTA-Balken im Outro zügig (Fix „Tap ↔ Balken verzahnen") */
    padding: 0 0 30vh;
  }
  html:not(.mode-stacked) .step {
    min-height: 90vh; margin: 0;
    position: relative; overflow: hidden;
    display: flex; flex-direction: column;
    justify-content: center; align-items: flex-start;
    padding-inline: clamp(2rem, 7vw, 7.5rem);
  }
  html:not(.mode-stacked) .step__body { max-width: 34ch; position: relative; z-index: 2; }
  /* Lesbarkeit über den satten Nummern: Fließtext dicker + dunkler */
  html:not(.mode-stacked) .step__text { color: var(--ink); font-weight: 600; }
  /* Riesige, satte Schritt-Nummer als Hintergrund am Seitenrand (blutet
     leicht über die Kante, .step clippt). Liegt im Stacking UNTER dem iPad
     (0 < Stage 1) — sie kann also nie „durchscheinen"; der Text liegt davor. */
  html:not(.mode-stacked) .step__num {
    position: absolute; top: 50%; transform: translateY(-50%);
    z-index: 0; pointer-events: none; user-select: none;
    font-size: min(80vh, 54vw); line-height: .72; letter-spacing: -.06em;
  }
  html.mode-pinned .step--top .step__num,
  html.mode-pinned .step--left .step__num { left: -2.5vw; }
  html.mode-pinned .step--right .step__num { right: -2.5vw; }
  /* Schritt 1 (Text oben statt mittig): Nummer folgt dem Text nach oben,
     damit die Text↔Nummer-Beziehung in allen Schritten gleich ist. */
  html.mode-pinned .step--top .step__num { top: calc(22vh + 5rem); }
  html.mode-pinned .step--right { align-items: flex-end; }
  /* Schritt 1: Text oben links, iPad schwebt schräg darunter.
     22vh Abstand, damit die 80vh-Nummer dahinter NICHT an der
     Step-Oberkante abgeschnitten wird. */
  html.mode-pinned .step--top { justify-content: flex-start; padding-top: 22vh; }
  /* Schritt 4: iPad rückt zur Mitte — Textspalte etwas schmaler */
  html.mode-pinned .step--tight .step__body { max-width: min(34ch, 26vw); }
}

/* Progress-Dots (nur im Desktop-Journey-Modus sichtbar) */
.progressdots { display: none; }
html.mode-pinned .progressdots {
  display: flex; gap: .55rem;
  position: absolute; left: 50%; transform: translateX(-50%); bottom: 1.6rem;
}
.progressdots__dot { width: 9px; height: 9px; border-radius: 50%; background: #C9C9D2; transition: background .3s, transform .3s; }
.progressdots__dot.is-active { background: var(--accent); transform: scale(1.3); }

/* ---- Overlays (in .ipad-fly, reisen mit dem iPad; GSAP zeichnet,
        positionOverlays() setzt left/top/width per Messung) ---- */
.ov { position: absolute; pointer-events: none; opacity: 0; color: var(--accent); overflow: visible; }

/* Die Step-Pfeile zeichnen sich wie der Hero-Callout per CSS-Keyframe
   (@keyframes drawPath, weiter unten), ausgelöst durch den data-step-Wechsel
   auf der Stage. Erprobte, zuverlässig sichtbare Mechanik — GSAP-Draws waren
   im Live-Betrieb unsichtbar. Beim Verlassen des Schritts greift der Selektor
   nicht mehr → Strich/Opacity fallen auf den Basiszustand zurück (unsichtbar),
   beim erneuten Eintritt zeichnet er sich neu. */
html.mode-pinned .scrolly__stage[data-step="1"] .ov-add,
html.mode-pinned .scrolly__stage[data-step="3"] .ov-select { opacity: 1; }
html.mode-pinned .scrolly__stage[data-step="1"] .ov-add .draw,
html.mode-pinned .scrolly__stage[data-step="3"] .ov-select .draw {
  animation: drawPath .85s ease .1s forwards;
}

/* Der Schritt-3-Pfeil kommt von der Seite (außerhalb des iPads) und soll
   NICHT starr am iPad kleben: eine eigene, langsame Drift mit anderer
   Periode als der iPad-Bob (7s) lässt den Abstand organisch atmen statt
   mechanisch fix zu wirken. Nur im Desktop-Journey-Modus, reduced-motion-frei. */
html.mode-pinned .ov-select { animation: ovDrift 5.5s ease-in-out infinite; }
@keyframes ovDrift {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50% { transform: translate(-9px, 6px) rotate(-1.5deg); }
}
@media (prefers-reduced-motion: reduce) {
  html.mode-pinned .ov-select { animation: none; }
}

/* ============================================================
   Gestapelter Fallback (Mobile/Tablet/Reduced Motion)
   ============================================================ */
/* Die Stage bleibt sichtbar: das eine iPad steht statisch unter dem Hero-Text;
   die Steps zeigen zusätzlich Detail-Ausschnitte (Crops). */
html.mode-stacked .step { margin-bottom: 3.5rem; }
html.mode-stacked .step__visual { display: block; }

.crop {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg);
  aspect-ratio: 16 / 10;
  background: var(--surface);
  box-shadow: var(--shadow-md);
}
.crop .mockup { position: absolute; box-shadow: none; }
.crop--1 .mockup { width: 230%; left: -4%;  top: -6%; }    /* Sidebar oben: +-Button */
.crop--2 .mockup { width: 260%; left: -8%;  bottom: -14%; } /* ERWEITERUNG-Panel */
.crop--3 .mockup { width: 130%; left: -13%; top: -10%; }    /* Dateikarte + Vorschau */
.crop--4 .mockup { width: 210%; right: -6%; top: -4%; }     /* Topbar: Export-Button */
