/* ==========================================================================
   leomore W5 Scroll-Story
   Alle Verwandlungs- und Lebendigkeits-Styles der Startseite.
   Prinzip: Endzustand ist Default; Animation ist Enhancement.
   Nur transform / opacity / clip-path animieren.
   ========================================================================== */

/* ---------- Support-Gates als Custom Properties ---------- */
/* .w5-anim wird von w5.js gesetzt, wenn (a) kein prefers-reduced-motion und
   (b) JS läuft. Ohne .w5-anim zeigt alles den Endzustand. */

/* ---------- Scrub-Basis (nur wenn nativ unterstützt) ---------- */
@supports (animation-timeline: view()) {
  html.w5-anim .w5-scrub { /* Marker-Klasse, konkrete Animationen je Beat */ }
}

/* ---------- Einmal-Reveal-Fallback (Firefox/WebKit, ohne Scrub) ---------- */
/* Transition haengt an den Elementen selbst (nicht am pending-Zustand),
   damit sie beim Wegfall der pending-Klasse wirklich weich laeuft. */
html.w5-anim.w5-no-timeline .w5-morph-alt,
html.w5-anim.w5-no-timeline .w5-morph-neu,
html.w5-anim.w5-no-timeline .w5-h1-was,
html.w5-anim.w5-no-timeline .w5-h1-wird {
  transition: opacity 1s ease, clip-path 1s ease, transform 1s ease;
}

/* ---------- Reduced Motion: alles sofort final ---------- */
@media (prefers-reduced-motion: reduce) {
  .w5-scrub, .w5-morph, .w5-morph-alt, .w5-morph-neu, .w5-morph-neu::after, .wm-strich, .wm-strich::after, .wm-page, .w5-chapter-line, .w5-cue, .wc-row, .wc-leo, .wc-kunde { animation: none !important; transition: none !important; }
}

/* ---------- sr-only (existiert nicht in style.css, Standard-Clip-Pattern) ---------- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Beat 1: Hero Satz-Shift ---------- */
/* Bestand .hero clippt seine Glow-Blobs mit overflow:hidden (style.css) - das macht
   .hero zum Scroll-Container und bricht sticky-Pinning + view()-Timeline darunter.
   clip-path clippt die Blobs identisch, erzeugt aber keinen Scroll-Container. */
.w5-hero { overflow: visible; clip-path: inset(0); }

.w5-grad {
  font-style: normal;
  background: linear-gradient(90deg, var(--c1), var(--c4));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.w5-hero-sub { margin-top: 20px; }
.w5-h1-stage { display: grid; }
.w5-h1-stage > span { grid-area: 1 / 1; }
.w5-h1-wird { opacity: 0; }           /* Startzustand nur relevant, wenn animiert wird */
html:not(.w5-anim) .w5-h1-was  { display: none; }   /* Endzustand ohne Animation */
html:not(.w5-anim) .w5-h1-wird { opacity: 1; }

/* Desktop + feiner Pointer: Pinning + Scrub */
/* Wichtig: "contain" statt roher Cover-Prozente. Der Cover-Bereich (0-100%) laeuft
   ueber die GESAMTE Sichtbarkeit von .w5-hero-track (inkl. Rein- und Rausscrollen);
   weil der Track direkt am Seitenanfang sitzt, ist Cover beim Laden (scrollY=0) schon
   ca. 25% durchlaufen - der erste Satz waere dadurch nie in Ruhe scharf sichtbar.
   "contain" markiert dagegen exakt die Phase, in der der Track die gesamte Sticky-Pin-
   Distanz durchlaeuft (0% = Pin rastet ein, 100% = Pin loest sich) - bei scrollY=0
   (Pin noch nicht eingerastet) liegt der Fortschritt vor diesem Fenster, also bei 0%. */
@media (min-width: 1024px) and (pointer: fine) {
  @supports (animation-timeline: view()) {
    html.w5-anim .w5-hero-track { height: 220svh; view-timeline-name: --w5hero; }
    html.w5-anim .w5-hero-pin   { position: sticky; top: 0; min-height: 100svh; display: flex; align-items: center; }

    /* Die frueheren Glow-Blobs (Original .hero + Pin-Verankerung) sind mit
       dem Redesign komplett entfernt - die Hero-Buehne (Grain + Partikel)
       kommt aus redesign.css/js, Verlauf bleibt Linien-Akzent. */
    html.w5-anim .w5-h1-was {
      animation: w5-hero-out linear both;
      animation-timeline: --w5hero;
      animation-range: contain 0% contain 55%;
    }
    html.w5-anim .w5-h1-wird {
      animation: w5-hero-in linear both;
      animation-timeline: --w5hero;
      animation-range: contain 40% contain 78%;
    }
  }
}
/* Mobile / ohne Pinning: gleicher Shift ungepinnt über die eigene Sichtbarkeit */
@media not ((min-width: 1024px) and (pointer: fine)) {
  @supports (animation-timeline: view()) {
    html.w5-anim .w5-hero-track { view-timeline-name: --w5hero; }
    html.w5-anim .w5-h1-was  { animation: w5-hero-out linear both; animation-timeline: --w5hero; animation-range: exit 0% exit 45%; }
    html.w5-anim .w5-h1-wird { animation: w5-hero-in  linear both; animation-timeline: --w5hero; animation-range: exit 20% exit 70%; }
  }
}
/* Mobil/Touch (GSAP-Scrub): kuerzere Pin-Strecke (140svh) fuer denselben
   Satz-Shift wie Desktop - redesign.js scrubt die 'contain'-Timeline. Nur
   .w5-gsap: die native view()- und die no-timeline-Fallback-Pfade behalten
   ihre ungepinnte Geometrie; der reduced-motion-Runtime-Toggle entfernt
   .w5-gsap und raeumt den Pin automatisch mit ab. Media-Query byte-identisch
   zum matchMedia-String in redesign.js (initHeroShift), sonst driftet die
   Pin-Geometrie bei iPad-Landscape (>=1024, pointer coarse). Ausserhalb
   @supports(view()): der GSAP-Pfad braucht keine native Timeline-Stuetze.
   justify-content:flex-start haelt den Hero-Text an der Oberkante (kein
   Re-Center-Sprung beim Klassenwechsel = kein CLS). */
@media not ((min-width: 1024px) and (pointer: fine)) {
  html.w5-gsap .w5-hero-track { height: 140svh; }
  html.w5-gsap .w5-hero-pin {
    position: sticky;
    top: 72px; /* unter der 72px-Sticky-Leiste einrasten, sonst liegt der Hero-
                  Text waehrend des Pins hinter dem Header. Nur die eingerastete
                  Position ist betroffen - Ruhelage bleibt natuerlich (kein CLS). */
    min-height: calc(100svh - 72px);
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
  }
  /* Morph pinnt mobil wie der Hero (M1-Muster): nur .w5-gsap, damit die
     nativen view()-/Fallback-Pfade ihre ungepinnte Geometrie behalten.
     Die Karte steht, waehrend alt -> neu morpht - Ranges in redesign.js
     (initMorph, Mobile-Branch) geben dem Vorher echte Standzeit. */
  html.w5-gsap .w5-morph-track { height: 300svh; }
  html.w5-gsap .w5-morph-pin {
    position: sticky;
    top: 72px;
    min-height: calc(100svh - 72px);
    display: flex;
    align-items: center;
  }
  html.w5-gsap .w5-morph-pin > .wrap { width: 100%; }
}
@keyframes w5-hero-out {
  to { opacity: 0; transform: translateY(-26px) rotate(-1.2deg); }
}
@keyframes w5-hero-in {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: none; }
}
/* Firefox/No-Timeline: beide Sätze nacheinander per Fallback-Transition */
html.w5-anim.w5-no-timeline .w5-hero-track.w5-fallback-pending .w5-h1-wird { opacity: 0; transform: translateY(30px); }
html.w5-anim.w5-no-timeline .w5-hero-track:not(.w5-fallback-pending) .w5-h1-was  { opacity: 0; }
html.w5-anim.w5-no-timeline .w5-hero-track:not(.w5-fallback-pending) .w5-h1-wird { opacity: 1; transform: none; }

/* ---------- Beat 2: Baukasten -> Charakter ---------- */
.w5-morph {
  position: relative; background: var(--card);
  border: 1px solid var(--line-strong); border-radius: 14px;
  overflow: hidden; max-width: 720px; margin: 0 auto;
  box-shadow: 0 18px 50px rgba(33, 26, 18, .08);
}
.w5-morph-stage { --w5-stage-h: 430px; display: grid; grid-template-columns: minmax(0, 1fr); height: var(--w5-stage-h); }
.w5-morph-stage > div { min-width: 0; }
.w5-morph-stage > div { grid-area: 1 / 1; }

/* Der Vorher-Zustand ist bewusst eine echte ~2010er-Homepage: glossy
   Web-2.0-Header, Tab-Leiste, Aktuelles-Box, schief gerahmtes Foto. */
.w5-morph-alt { background: #f4f4f4; font-family: Arial, Helvetica, sans-serif; display: flex; flex-direction: column; overflow: hidden; }
.w5-morph-alt .wk-head { background: linear-gradient(#5b9bd5, #2e6da4); padding: 14px 18px 10px; }
.w5-morph-alt .wk-title { display: block; font-size: 22px; font-weight: 700; color: #fff; text-shadow: 1px 2px 2px rgba(0, 0, 0, .45); }
.w5-morph-alt .wk-sub { font-size: 12px; font-style: italic; color: #dce9f7; }
.w5-morph-alt .wk-tabs { display: flex; gap: 3px; padding: 6px 12px 0; background: #2e6da4; }
.w5-morph-alt .wk-tabs span { background: linear-gradient(#fdfdfd, #d5d9df); border: 1px solid #9fb2c6; border-bottom: none; border-radius: 5px 5px 0 0; padding: 5px 13px; font-size: 11.5px; font-weight: 700; color: #23527c; box-shadow: inset 0 1px 0 #fff; }
.w5-morph-alt .wk-tabs .on { background: #fff; color: #d9534f; }
.w5-morph-alt .wk-main { flex: 1; min-height: 0; display: flex; gap: 14px; padding: 14px 18px; background: #fff; }
.w5-morph-alt .wk-left { flex: 1; min-width: 0; }
.w5-morph-alt .wk-h { font-size: 19px; color: #2e6da4; font-weight: 700; margin-bottom: 8px; }
.w5-morph-alt .wk-txt { font-size: 12.5px; color: #333; line-height: 1.5; margin-bottom: 10px; }
.w5-morph-alt .wk-btn { display: inline-block; background: linear-gradient(#ffb84d, #f0820f); border: 1px solid #cf6f0a; border-radius: 5px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6), 0 1px 3px rgba(0, 0, 0, .3); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, .3); font-size: 12px; font-weight: 700; padding: 6px 16px; }
.w5-morph-alt .wk-right { flex: 0 0 168px; display: flex; flex-direction: column; gap: 12px; }
.w5-morph-alt .wk-news { background: #fff8dc; border: 1px solid #e8c76e; border-radius: 4px; padding: 8px 10px; font-size: 11px; color: #6b5814; line-height: 1.45; }
.w5-morph-alt .wk-news b { display: block; color: #b8860b; margin-bottom: 3px; font-size: 11.5px; }
.w5-morph-alt .wk-foto { background: #fff; border: 1px solid #ccc; box-shadow: 2px 3px 6px rgba(0, 0, 0, .3); padding: 5px 5px 3px; transform: rotate(-2deg); }
.w5-morph-alt .wk-foto-inner { display: block; width: 100%; height: 104px; object-fit: cover; }
.w5-morph-alt .wk-foto-cap { display: block; text-align: center; font-size: 10px; color: #777; padding-top: 3px; }
.w5-morph-alt .wk-foot { border-top: 1px solid #d6d6d6; background: #ececec; padding: 7px 16px; font-size: 10.5px; color: #888; text-align: center; }

/* Das Makeover: dieselbe Firma als echte Demo-Site mit mehreren Sektionen.
   .wm-page ist hoeher als die Stage und wird waehrend des Pins per Scrub
   durchgescrollt (translateY, gleiche Timeline wie der Morph). */
.w5-morph-neu { background: var(--ink); color: var(--bg); }
.w5-morph-neu .wm-page { display: flex; flex-direction: column; gap: 16px; padding: 16px 22px 20px; }
.w5-morph-neu .wm-nav { display: flex; align-items: center; gap: 14px; padding-bottom: 12px; border-bottom: 1px solid rgba(251, 248, 243, .14); font-size: 12.5px; color: rgba(251, 248, 243, .72); }
.w5-morph-neu .wm-logo { font-family: 'Clash Display', sans-serif; font-weight: 700; font-size: 17px; color: var(--bg); }
.w5-morph-neu .wm-dot { color: #e8956b; }
.w5-morph-neu .wm-links { display: flex; gap: 14px; margin-left: auto; }
.w5-morph-neu .wm-nav-cta { padding: 6px 14px; border-radius: 999px; background: linear-gradient(90deg, var(--c1), var(--c4)); color: #fff; font-weight: 600; font-size: 12px; }
.w5-morph-neu .wm-hero-row { display: flex; align-items: center; gap: 20px; padding: 12px 0 6px; }
.w5-morph-neu .wm-copy { flex: 1; min-width: 0; }
.w5-morph-neu .wm-brand { font-family: 'Clash Display', sans-serif; font-weight: 700; font-size: clamp(22px, 3vw, 31px); line-height: 1.08; letter-spacing: -.02em; }
.w5-morph-neu .wm-sub { margin-top: 8px; font-size: 13.5px; color: rgba(251, 248, 243, .72); }
.w5-morph-neu .wm-cta { display: inline-block; margin-top: 14px; padding: 9px 20px; border-radius: 999px;
  background: linear-gradient(90deg, var(--c1), var(--c4)); color: #fff; font-weight: 600; font-size: 13px; }
.w5-morph-neu .wm-hero { flex: 0 0 42%; min-width: 0; align-self: stretch; min-height: 150px; height: auto; border-radius: 12px; object-fit: cover; }
.w5-morph-neu .wm-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.w5-morph-neu .wm-chips span { padding: 6px 12px; border-radius: 999px; border: 1px solid rgba(251, 248, 243, .22); font-size: 12px; color: rgba(251, 248, 243, .85); }
.w5-morph-neu .wm-sec { padding-top: 26px; margin-top: 10px; border-top: 1px solid rgba(251, 248, 243, .12); }
.w5-morph-neu .wm-sec-h { font-family: 'Clash Display', sans-serif; font-weight: 700; font-size: 19px; margin-bottom: 14px; }
.w5-morph-neu .wm-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.w5-morph-neu .wm-cards span { border: 1px solid rgba(251, 248, 243, .16); border-radius: 10px; padding: 12px; display: flex; flex-direction: column; gap: 4px; }
.w5-morph-neu .wm-cards b { font-size: 13.5px; }
.w5-morph-neu .wm-cards small { font-size: 11.5px; color: rgba(251, 248, 243, .62); line-height: 1.4; }
.w5-morph-neu .wm-gallery { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
/* Echte Referenzfotos (FLUX, warme Wagner-Palette); die Verlaeufe bleiben
   als Lade-Hintergrund unter den lazy-Images. */
.w5-morph-neu .wm-gallery img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 10px; }
.w5-morph-neu .wm-gallery .g1 { background: linear-gradient(125deg, #6a3d2a, #d99a6c); }
.w5-morph-neu .wm-gallery .g2 { background: linear-gradient(125deg, #8a6f5c, #cfc4b8); }
.w5-morph-neu .wm-gallery .g3 { background: linear-gradient(125deg, #a45f38, #f3c99a); }
.w5-morph-neu .wm-contact { text-align: center; padding: 26px 0 8px; margin-top: 10px; border-top: 1px solid rgba(251, 248, 243, .12); }
.w5-morph-neu .wm-contact-h { font-family: 'Clash Display', sans-serif; font-weight: 700; font-size: 21px; margin-bottom: 4px; }
.w5-morph-neu .wm-contact .wm-cta { margin-top: 10px; }
.w5-morph-neu .wm-foot { border-top: 1px solid rgba(251, 248, 243, .12); margin-top: 8px; padding-top: 12px; font-size: 11px; color: rgba(251, 248, 243, .5); text-align: center; }

/* Schmale Viewports: Seitenspalte/Deko weglassen, Hero stapeln */
@media (max-width: 560px) {
  .w5-morph-stage { --w5-stage-h: 400px; }
  .w5-morph-alt .wk-right { display: none; }
  .w5-morph-alt .wk-tabs span { padding: 5px 9px; font-size: 10.5px; white-space: nowrap; }
  .w5-morph-neu .wm-links { display: none; }
  .w5-morph-neu .wm-hero-row { flex-direction: column; align-items: stretch; }
  .w5-morph-neu .wm-hero { flex: none; width: 100%; height: 120px; min-height: 0; }
  .w5-morph-neu .wm-cards { grid-template-columns: 1fr; }
  .w5-morph-neu .wm-gallery { gap: 8px; }
}

/* Endzustand als Default: neu sichtbar, alt weg */
.w5-morph-alt { opacity: 0; }
.w5-morph-neu { clip-path: none; }

/* ---------- Lichtstrich-Kante: die Signature (Hero-Video, Nav-Linie) als
   Verwandlungs-Kante. Ueber ihr ist schon neu, unter ihr noch alt; sie
   wandert synchron zur clip-path-Aufdeckung (GSAP: Inline-Styles, nativ:
   wm-strich-sweep auf derselben Range wie w5-neu-in). Lichtsprache wie im
   Hero-Poster: fast weisser Kern, Gelb->Rot-Halo, wandernder Glutpunkt.
   Endzustand-Default: unsichtbar. ---------- */
.w5-morph-stage { position: relative; }
.wm-strich {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  border-radius: 2px;
  margin-top: -1px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--c1) 55%, white),
    color-mix(in srgb, var(--c2) 70%, white),
    color-mix(in srgb, var(--c4) 78%, white));
  box-shadow:
    0 0 6px 1px color-mix(in srgb, var(--c1) 85%, transparent),
    0 0 20px 5px color-mix(in srgb, var(--c2) 50%, transparent),
    0 0 48px 14px color-mix(in srgb, var(--c4) 26%, transparent);
}
/* Wandernder Glutpunkt (zeitgesteuert, nicht scroll-gebunden - die Kante
   lebt auch bei langsamem Scroll; background-position = paint-only) */
.wm-strich::after {
  content: "";
  position: absolute;
  inset: -3px 0;
  background-image: radial-gradient(closest-side,
    white,
    color-mix(in srgb, var(--c2) 80%, white) 45%,
    transparent);
  background-repeat: no-repeat;
  background-size: 26px 100%;
  background-position: 0% 50%;
  animation: wm-glut 3.2s ease-in-out infinite alternate;
}
@keyframes wm-glut {
  from { background-position: 3% 50%; }
  to   { background-position: 97% 50%; }
}
/* Warmer Schein der Kante auf die alte Seite darunter */
.wm-strich::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 2%;
  right: 2%;
  height: 74px;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--c2) 22%, transparent),
    transparent);
}
/* Sweep + Sichtbarkeit fuer den nativen Timeline-Pfad (GSAP setzt beides
   inline; Kill-List legt diese Animationen dort still) */
@keyframes wm-strich-sweep {
  from { transform: translateY(0); }
  to   { transform: translateY(var(--w5-stage-h, 430px)); }
}
@keyframes wm-strich-fade {
  0%   { opacity: 0; }
  10%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0; }
}
/* Glanz-Sweep ueber die fertige neue Seite (Abgang; Klasse setzt redesign.js
   beim Vollenden der Verwandlung, nur im GSAP-Pfad) */
.w5-morph-neu::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(105deg,
    transparent 42%,
    color-mix(in srgb, white 16%, transparent) 50%,
    transparent 58%);
  background-size: 260% 100%;
  background-position: 130% 0;
}
.w5-morph.wm-glanz .w5-morph-neu::after {
  animation: wm-glanz-sweep 1.1s ease-out both;
}
@keyframes wm-glanz-sweep {
  0%   { opacity: 1; background-position: 130% 0; }
  85%  { opacity: 1; }
  100% { opacity: 0; background-position: -30% 0; }
}
.w5-morph-neu { position: relative; }

/* Animierter Zustand: Desktop pinnt einen langen Track - die Kack-Seite
   steht erst DEUTLICH (contain 0-35%), dann Verwandlung, dann steht die neue.
   Mobil (kein Pinning, WebKit-Sticky-Bug): Scrub ueber die eigene Sichtbarkeit,
   mit spaeten Ranges, damit das Vorher sichtbar bleibt. */
@media (min-width: 1024px) and (pointer: fine) {
  @supports (animation-timeline: view()) {
    html.w5-anim .w5-morph-track { height: 400svh; view-timeline-name: --w5morph; }
    html.w5-anim .w5-morph-pin { position: sticky; top: 0; min-height: 100svh; display: flex; align-items: center; }
    html.w5-anim .w5-morph-pin > .wrap { width: 100%; }
    html.w5-anim .w5-morph-alt {
      opacity: 1;
      animation: w5-alt-out linear both;
      animation-timeline: --w5morph;
      /* nach der Lichtstrich-Kante (w5-neu-in endet 48%) - unter der Kante
         muss die alte Seite stehen, das Fade raeumt nur den Endzustand auf */
      animation-range: contain 48% contain 52%;
    }
    html.w5-anim .w5-morph-neu {
      clip-path: inset(0 0 100% 0);
      animation: w5-neu-in linear both;
      animation-timeline: --w5morph;
      animation-range: contain 30% contain 48%;
    }
    /* Nach dem Morph scrollt die Demo-Site im Rahmen durch - der Besucher
       sieht eine echte, komplette Seite statt nur eines Heros. */
    html.w5-anim .w5-morph-neu .wm-page {
      animation: w5-page-scroll linear both;
      animation-timeline: --w5morph;
      animation-range: contain 54% contain 92%;
    }
    /* Lichtstrich-Kante synchron zur SICHTBAREN Aufdeckung: w5-neu-in clippt
       ueber die volle neu-Hoehe (~2.5x Stage), im Fenster ist die Kante nach
       ~40% der Clip-Range unten raus - Range deshalb verkuerzt (Naeherung;
       der GSAP-Pfad rechnet exakt ueber neu.offsetHeight). */
    html.w5-anim .wm-strich {
      animation: wm-strich-sweep linear both, wm-strich-fade linear both;
      animation-timeline: --w5morph, --w5morph;
      animation-range: contain 30% contain 37%;
    }
  }
}
@keyframes w5-page-scroll { to { transform: translateY(calc(-100% + var(--w5-stage-h, 430px))); } }
@media not ((min-width: 1024px) and (pointer: fine)) {
  @supports (animation-timeline: view()) {
    /* Mobil (kein Pin): eine gemeinsame Karten-Timeline fuer alle drei
       Animationen. Verwandlung frueh und knackig, waehrend die Karte gut
       sichtbar steht - danach scrollt die Demo im Rahmen durch. */
    html.w5-anim .w5-morph { view-timeline-name: --w5card; }
    html.w5-anim .w5-morph-alt {
      opacity: 1;
      animation: w5-alt-out linear both;
      animation-timeline: --w5card;
      /* nach der Kante, wie im Desktop-Block */
      animation-range: cover 54% cover 58%;
    }
    html.w5-anim .w5-morph-neu {
      clip-path: inset(0 0 100% 0);
      animation: w5-neu-in linear both;
      animation-timeline: --w5card;
      animation-range: cover 38% cover 54%;
    }
    html.w5-anim .w5-morph-neu .wm-page {
      animation: w5-page-scroll linear both;
      animation-timeline: --w5card;
      animation-range: cover 58% cover 96%;
    }
    /* verkuerzte Range wie im Desktop-Block (sichtbare Aufdeckung) */
    html.w5-anim .wm-strich {
      animation: wm-strich-sweep linear both, wm-strich-fade linear both;
      animation-timeline: --w5card, --w5card;
      animation-range: cover 38% cover 44%;
    }
  }
}
@keyframes w5-alt-out { to { opacity: 0; transform: scale(.985); } }
@keyframes w5-neu-in  { to { clip-path: inset(0 0 0 0); } }

/* Firefox/No-Timeline: einmalige Transition beim IO-Eintritt */
html.w5-anim.w5-no-timeline .w5-morph-track.w5-fallback-pending .w5-morph-alt { opacity: 1; }
html.w5-anim.w5-no-timeline .w5-morph-track.w5-fallback-pending .w5-morph-neu { clip-path: inset(0 0 100% 0); }
html.w5-anim.w5-no-timeline .w5-morph-track:not(.w5-fallback-pending) .w5-morph-alt { opacity: 0; }
html.w5-anim.w5-no-timeline .w5-morph-track:not(.w5-fallback-pending) .w5-morph-neu { clip-path: inset(0 0 0 0); }

/* ---------- Beat 3: Formular -> Gespräch ---------- */
.w5-swap { max-width: 560px; margin: 0 auto 26px; view-transition-name: w5swap; }
.w5-swap-form .wf-line { display: block; height: 42px; border: 1px solid var(--line-strong); border-radius: 10px; background: var(--card); margin-bottom: 10px; }
.w5-swap-form .wf-line.w-60 { width: 60%; }
.w5-swap-form .wf-btn { display: inline-block; padding: 10px 22px; border-radius: 10px; background: #d8d2c8; color: #55493c; font-weight: 600; }
.wc-row { display: flex; align-items: flex-end; gap: 10px; }
.wc-row img { border-radius: 50%; }
.wc-bubble { padding: 13px 17px; border-radius: 16px; max-width: 80%; }
.wc-leo { background: var(--ink); color: var(--bg); border-bottom-left-radius: 4px; }
.wc-kunde { background: var(--card); border: 1px solid var(--line-strong); border-bottom-right-radius: 4px; margin: 12px 0 0 auto; }

/* Sequenz nach dem Swap: leos Frage zieht sich auf wie getippt, dann die Antwort.
   Nur im Anim-Pfad; Endzustand (No-JS/reduced-motion) zeigt beide sofort. */
html.w5-anim .w5-swap.w5-swapped .wc-row {
  opacity: 0; animation: w5-bubble-in .45s ease-out .15s forwards;
}
html.w5-anim .w5-swap.w5-swapped .wc-leo {
  clip-path: inset(0 100% 0 0 round 16px);
  animation: w5-type-open .8s ease-out .4s forwards;
}
html.w5-anim .w5-swap.w5-swapped .wc-kunde {
  opacity: 0; animation: w5-bubble-in .5s ease-out 1.5s forwards;
}
@keyframes w5-bubble-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes w5-type-open { to { clip-path: inset(0 0 0 0 round 16px); } }
::view-transition-old(w5swap) { animation-duration: .35s; }
::view-transition-new(w5swap) { animation-duration: .45s; }

/* Zustaende: Endzustand (Chat) ist Markup-Default - No-JS/reduced-motion sehen ihn
   direkt und semantisch (kein hidden-Attribut im Markup). Nur der JS-Anim-Pfad
   versteckt den Chat, bis der Swap (View Transition) ihn freigibt. */
html:not(.w5-anim) .w5-swap-form { display: none; }
html.w5-anim .w5-swap:not(.w5-swapped) .w5-swap-chat { display: none; }
html.w5-anim .w5-swap.w5-swapped .w5-swap-form { display: none; }

.w5-process-h { text-align: center; margin: 34px 0 18px; font-size: 20px; }

/* ---------- Beat 4: Referenz-Chips + Bild-Zoom ---------- */
.w5-chips { list-style: none; padding: 0; margin: 18px 0; display: flex; flex-wrap: wrap; gap: 8px; }
.w5-chip { padding: 8px 14px; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--card); font-size: 14px; }
@supports (animation-timeline: view()) {
  html.w5-anim .w5-chip {
    animation: w5-chip-in linear both;
    animation-timeline: view();
    animation-range: entry 10% entry 60%;
  }
  html.w5-anim .w5-chip:nth-child(2) { animation-range: entry 20% entry 70%; }
  html.w5-anim .w5-chip:nth-child(3) { animation-range: entry 30% entry 80%; }
}
@keyframes w5-chip-in { from { opacity: 0; transform: translateX(-14px); } }

/* Lebendigkeit: langsamer Bild-Zoom beim Durchscrollen */
@supports (animation-timeline: view()) {
  html.w5-anim .w5-zoom {
    animation: w5-zoom linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
}
@keyframes w5-zoom { from { transform: scale(1); } to { transform: scale(1.06) translateY(-8px); } }

/* ---------- Beat 6: Finale ---------- */
.w5-finale-card { position: relative; }
.w5-leo { display: block; margin: 0 auto 6px; width: auto; height: 150px; }
.w5-finale-config { margin: 26px auto 0; max-width: 460px; text-align: left; }
/* Bestand faerbt .cta-band-card p hell (dunkles Band, Spezifitaet 0,2,1) - die
   verschachtelte Karte ist aber weiss: Texte zurueck auf dunkle Tinte.
   p im Selektor haelt die Spezifitaet gleich; w5.css laedt spaeter und gewinnt. */
.w5-finale-config p.hc-title { color: var(--ink); }
.w5-finale-config p.hc-note { color: var(--ink-faint); }
@supports (animation-timeline: view()) {
  html.w5-anim .w5-finale-config {
    animation: w5-rise linear both;
    animation-timeline: view();
    animation-range: entry 5% entry 55%;
  }
  html.w5-anim .w5-leo {
    animation: w5-rise linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 40%;
  }
}
@keyframes w5-rise { from { opacity: 0; transform: translateY(26px); } }

/* ---------- Lebendigkeits-Layer ---------- */
/* Hero-Abgang: verwandelter Satz zoomt leicht weg */
@media (min-width: 1024px) and (pointer: fine) {
  @supports (animation-timeline: view()) {
    html.w5-anim .w5-hero-pin .w5-hero-inner {
      animation: w5-hero-leave linear both;
      animation-timeline: --w5hero;
      animation-range: contain 96% exit 100%;
    }
  }
}
@keyframes w5-hero-leave { to { opacity: .25; transform: scale(.96) translateY(-12px); } }

/* Sektions-Übergang: Verlaufs-Lichtkante wischt einmal quer.
   --w5-sweep als Zwischengröße: der native Pfad braucht sie nicht (Keyframe
   setzt scaleX direkt), redesign.js (GSAP-Pfad) kann sie aber animieren -
   ::before ist kein direktes Tween-Ziel, die Custom Property schon. */
.w5-sweep { position: relative; }
.w5-sweep::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--c1), var(--c4));
  transform: scaleX(var(--w5-sweep, 0)); transform-origin: left; pointer-events: none;
}
@supports (animation-timeline: view()) {
  html.w5-anim .w5-sweep::before {
    animation: w5-sweep-in linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 35%;
  }
}
@keyframes w5-sweep-in { to { transform: scaleX(1); } }

/* Pfoten-Detail (dosiert, Finale) */
.w5-paws { display: flex; gap: 14px; justify-content: center; margin: 0 0 8px; }
.w5-paws svg { width: 20px; height: 20px; opacity: .8; }
.w5-paws svg:nth-child(odd) { transform: rotate(12deg); }
.w5-paws svg:nth-child(even) { transform: rotate(-10deg) translateY(4px); }
@supports (animation-timeline: view()) {
  html.w5-anim .w5-paws svg { animation: w5-rise linear both; animation-timeline: view(); }
  html.w5-anim .w5-paws svg:nth-child(1) { animation-range: entry 0% entry 30%; }
  html.w5-anim .w5-paws svg:nth-child(2) { animation-range: entry 15% entry 45%; }
  html.w5-anim .w5-paws svg:nth-child(3) { animation-range: entry 30% entry 60%; }
}

/* ---------- Wow-Upgrade (Spec §3b) ---------- */

/* E1: Scroll-Cue - Default statisch sichtbar (reduced-motion/No-JS: unkritisch,
   dort pinnt nichts). Im Desktop-Anim-Pfad erscheint er erst nach dem Satz-Shift.
   w5.js setzt w5-cue-done beim ersten Weiterscrollen -> dauerhaft aus. */
/* Nur im gepinnten Desktop-Pfad sichtbar - ungepinnte Layouts (mobil,
   reduced-motion, no-timeline) brauchen keinen Scroll-Hinweis. */
.w5-cue {
  position: absolute; bottom: 26px; left: 50%; transform: translateX(-50%);
  display: none; flex-direction: column; align-items: center; gap: 2px;
  font-size: 13px; color: var(--ink-faint); pointer-events: none;
}
.w5-cue img, .w5-cue picture { width: auto; height: 56px; }
.w5-hero-pin { position: relative; } /* Anker fuer den Cue auch ohne sticky (mobil) */
html.w5-anim .w5-cue img { animation: w5-cue-puls 1.4s ease-in-out infinite alternate; }
@keyframes w5-cue-puls { from { transform: translateY(0); } to { transform: translateY(7px); } }
/* Mobil-Cue: Chevron-Lauflicht im Marken-Verlauf statt Leo (M1 pinnt mobil -
   der alte "ungepinnt braucht keinen Hinweis"-Grund gilt dort nicht mehr).
   Nur unter .w5-gsap = nur wo wirklich gepinnt wird; der reduced-motion-
   Runtime-Toggle raeumt die Klasse und damit den Cue automatisch mit ab. */
.w5-cue .cue-pfeil { display: none; }
@media not ((min-width: 1024px) and (pointer: fine)) {
  /* bottom 72: Pin ragt in Ruhelage ~70px unter den Fold - so ist der Pfeil
     vor dem ersten Scroll UND waehrend des Pins im Viewport */
  html.w5-gsap .w5-cue { display: flex; bottom: 72px; }
  html.w5-gsap .w5-cue picture { display: none; }
  html.w5-gsap .w5-cue .cue-pfeil { display: block; width: 30px; height: auto; animation: w5-cue-puls 1.4s ease-in-out infinite alternate; }
}
html.w5-anim .cue-pfeil path { opacity: .25; animation: w5-cue-chevron 1.5s ease-in-out infinite; }
html.w5-anim .cue-pfeil path:nth-of-type(2) { animation-delay: .18s; }
html.w5-anim .cue-pfeil path:nth-of-type(3) { animation-delay: .36s; }
@keyframes w5-cue-chevron {
  0%, 60%, 100% { opacity: .25; }
  25% { opacity: 1; }
}
@media (min-width: 1024px) and (pointer: fine) {
  @supports (animation-timeline: view()) {
    html.w5-anim .w5-cue {
      display: flex;
      opacity: 0;
      animation: w5-cue-in linear both;
      animation-timeline: --w5hero;
      animation-range: contain 80% contain 92%;
    }
  }
}
@keyframes w5-cue-in { to { opacity: 1; } }
html.w5-cue-done .w5-cue { opacity: 0 !important; visibility: hidden; transition: opacity .3s, visibility .3s; }
@media (prefers-reduced-motion: reduce) { .w5-cue img, .w5-cue .cue-pfeil, .cue-pfeil path { animation: none !important; } }

/* E2: Beat-2-Vollformat - der Rahmen waechst waehrend des Scrubs zur Buehne
   und kehrt zurueck. Nur transform, gleiche Timeline wie der Morph. */
:root { --w5-stage-scale: 1.06; }
/* Mobil/Touch sichtbarer machen: der Morph-Rahmen fuellt fast die Breite,
   1.06 war kaum wahrnehmbar; 1.10 liest sich, ohne die Karte ueber die
   Sektionskante (clip-path:inset(0) auf [data-kapitel]) hinaus zu treiben. */
@media (max-width: 1023px) { :root { --w5-stage-scale: 1.10; } }
@media (min-width: 1024px) { :root { --w5-stage-scale: 1.35; } }
@media (min-width: 1440px) { :root { --w5-stage-scale: 1.6; } }
@media (min-width: 1024px) and (pointer: fine) {
  @supports (animation-timeline: view()) {
    html.w5-anim .w5-morph {
      z-index: 1;
      animation: w5-stage linear both;
      animation-timeline: --w5morph;
      animation-range: contain 0% contain 100%;
    }
  }
}
@media not ((min-width: 1024px) and (pointer: fine)) {
  @supports (animation-timeline: view()) {
    html.w5-anim .w5-morph {
      z-index: 1;
      transform-origin: 50% 8%;
      animation: w5-stage linear both;
      animation-timeline: view();
      animation-range: entry 25% exit 75%;
    }
  }
}
@keyframes w5-stage {
  0%   { transform: scale(1); }
  24%  { transform: scale(var(--w5-stage-scale)); }
  92%  { transform: scale(var(--w5-stage-scale)); }
  100% { transform: scale(1); }
}

/* E3: Kapitel-Momente - vollbreite Atempausen zwischen den Beats,
   der Sweep (Lichtkante) laeuft durch sie hindurch. */
.w5-chapter { padding: clamp(56px, 9vw, 120px) 0; text-align: center; }
.w5-chapter-line { font-size: clamp(20px, 2.6vw, 28px); color: var(--ink-soft); letter-spacing: -.01em; }
.w5-chapter-line strong { color: var(--ink); }
.w5-chapter .w5-paws { margin-bottom: 14px; }
@supports (animation-timeline: view()) {
  html.w5-anim .w5-chapter-line {
    animation: w5-rise linear both;
    animation-timeline: view();
    animation-range: entry 10% entry 60%;
  }
}

/* ---------- Scroll-Container-Fixes fuer view()-Timelines ---------- */
/* view() bindet an den naechsten Scroll-Container - overflow:hidden auf einem
   Vorfahren friert die Animation ein (gleiche Ursache wie beim Hero-Fix oben).
   In den Anim-Pfaden uebernimmt clip-path das Clipping inkl. runder Ecken. */
@supports (animation-timeline: view()) {
  html.w5-anim .w5-morph { overflow: visible; clip-path: inset(0 round 14px); }
  html.w5-anim .split-visual { overflow: visible; clip-path: inset(0 round var(--r-lg)); }
  html.w5-anim .w5-finale-card { overflow: visible; clip-path: inset(0 round clamp(24px, 4vw, 40px)); }
}

/* ---------- Perf: Below-fold-Sektionen ---------- */
/* content-visibility:auto ENTFERNT (Plan 11, R1a). Zwei Gruende:
   (1) ScrollTrigger (GSAP-Pfad) misst absolute Pixel-Positionen - die
   contain-intrinsic-size-Schaetzungen verschieben Start/End aller Trigger,
   bis jede Sektion einmal echt gerendert wurde. (2) In eingebettetem
   WebKit blieben die Sektionen nach Anker-Spruengen wiederholt unbemalt
   (Paint ausgesetzt trotz korrektem DOM). Die drei Sektionen sind klein;
   das Lighthouse-Gate (>=95) verifiziert, dass der Verzicht traegt. */

/* ---------- WebKit: Scrub-Pfad hart abschalten ---------- */
/* Safari/WebKit besteht den @supports-Test, treibt view()-Timelines aber
   nicht scroll-synchron (iOS: Progress haengt bei 0). w5.js setzt dort
   w5-no-timeline; da @supports in WebKit wahr bleibt, muessen die Scrub-
   Animationen explizit weg - die einmaligen IO-Fallback-Transitionen
   (gleicher Pfad wie Firefox) uebernehmen die Verwandlungen.
   Gleiche Liste, gleicher Grund fuer .w5-gsap: redesign.js baut dieselben
   Beats als ScrollTrigger-Timelines nach (inkl. Safari-fest) - der native
   Scrub-Pfad muss dafuer ebenso weg, sonst fighten beide um dieselben
   Properties. Struktur (Pin/Sticky, Basis-Opacity/Clip-Path) bleibt aktiv,
   nur die animation-Deklaration selbst wird stillgelegt. */
html.w5-anim.w5-no-timeline .w5-h1-was,
html.w5-anim.w5-gsap .w5-h1-was,
html.w5-anim.w5-no-timeline .w5-h1-wird,
html.w5-anim.w5-gsap .w5-h1-wird,
html.w5-anim.w5-no-timeline .w5-hero-pin .w5-hero-inner,
html.w5-anim.w5-gsap .w5-hero-pin .w5-hero-inner,
html.w5-anim.w5-no-timeline .w5-morph,
html.w5-anim.w5-gsap .w5-morph,
html.w5-anim.w5-no-timeline .w5-morph-alt,
html.w5-anim.w5-gsap .w5-morph-alt,
html.w5-anim.w5-no-timeline .w5-morph-neu,
html.w5-anim.w5-gsap .w5-morph-neu,
html.w5-anim.w5-no-timeline .w5-morph-neu .wm-page,
html.w5-anim.w5-gsap .w5-morph-neu .wm-page,
html.w5-anim.w5-no-timeline .wm-strich,
html.w5-anim.w5-gsap .wm-strich,
html.w5-anim.w5-no-timeline .w5-chip,
html.w5-anim.w5-gsap .w5-chip,
html.w5-anim.w5-no-timeline .w5-zoom,
html.w5-anim.w5-gsap .w5-zoom,
html.w5-anim.w5-no-timeline .w5-finale-config,
html.w5-anim.w5-gsap .w5-finale-config,
html.w5-anim.w5-no-timeline .w5-leo,
html.w5-anim.w5-gsap .w5-leo,
html.w5-anim.w5-no-timeline .w5-sweep::before,
html.w5-anim.w5-gsap .w5-sweep::before,
html.w5-anim.w5-no-timeline .w5-paws svg,
html.w5-anim.w5-gsap .w5-paws svg,
html.w5-anim.w5-no-timeline .w5-cue,
html.w5-anim.w5-gsap .w5-cue,
html.w5-anim.w5-no-timeline .w5-chapter-line,
html.w5-anim.w5-gsap .w5-chapter-line { animation: none; }
/* Der Cue hat seine opacity:0-Basis in der Desktop-Query - ohne Scrub
   direkt sichtbar zeigen; w5-cue-done blendet ihn wie gehabt aus.
   Nur fuer w5-no-timeline: der GSAP-Pfad treibt opacity selbst per Scrub,
   die opacity:0-Basis ist dort der korrekte Start- (nicht End-)Zustand. */
html.w5-anim.w5-no-timeline .w5-cue { opacity: 1; }

/* ---------- Fallback-Inszenierung (WebKit/Firefox, ohne Scrub) ---------- */
/* Ohne Scroll-Bindung rauscht Mobile am Beat vorbei - deshalb spielt die
   Makeover-Seite ihre Scroll-Fahrt nach der Verwandlung selbst ab
   (gleicher Keyframe wie der Desktop-Scrub, nur zeitgesteuert). */
html.w5-anim.w5-no-timeline .w5-morph-track:not(.w5-fallback-pending) .wm-page {
  animation: w5-page-scroll 5.5s ease-in-out 1.5s both;
}
