/* ==========================================================================
   Wurzelwerk · Startseite V2 — Scroll-Sequenz Leistungen
   Ergaenzung zu leistungen.css. Setzt dessen Tokens voraus.

   Grundzustand ist bewusst STATISCH: Hero und die vier Leistungen stehen als
   Bloecke untereinander, alles lesbar, ohne JavaScript und ohne Sticky. Erst
   die Klasse .is-enhanced, die scroll-scenes.js setzt, macht daraus die
   fixierte Sequenz. Damit ist der Ausfall von JS kein Sonderfall, sondern der
   Ausgangspunkt.
   ========================================================================== */

/* ---------- Sektion ---------- */
.scenes{
  position:relative;
  background:var(--ww-surface-dark);
  color:var(--ww-text-light);
  padding:3.5rem 0;
}
@media (min-width:900px){.scenes{padding:5.5rem 0}}

/* Weicher Abschluss nach unten, damit die Kante zur hellen Folgesektion
   nicht hart bricht. */
.scenes::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:120px;
  background:linear-gradient(180deg,transparent,rgba(255,255,255,.05));
  pointer-events:none;
}

.scenes__stage{position:relative}

/* ---------- Hintergrund der Buehne ----------
   Dieselbe Verlaufslogik wie .ww-section--cta auf den Leistungsseiten, nur
   groesser angelegt und in zwei Ebenen getrennt. Beide wandern gegenlaeufig
   mit dem Scrollfortschritt (--p, vom Skript gesetzt). Das ersetzt die
   bewegte Flaeche, die ein Shader liefern wuerde, kostet aber nichts:
   zwei Kompositor-Ebenen, keine Neuberechnung pro Frame. */
.scenes__bg{
  position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0;
  background:var(--ww-surface-dark);
}
.scenes.is-enhanced .scenes__bg{position:absolute;inset:0}
.scenes__bg::before,
.scenes__bg::after{
  content:"";position:absolute;inset:-25%;
  will-change:transform;
}
/* Gruen: die Markenfarbe traegt die linke Haelfte. */
.scenes__bg::before{
  background:
    radial-gradient(58% 72% at 22% 42%, rgba(59,165,93,.30), transparent 68%),
    radial-gradient(46% 60% at 8% 88%, rgba(110,220,140,.14), transparent 70%);
  transform:translate3d(calc(var(--p,0) * -6%), calc(var(--p,0) * 9%), 0);
}
/* Blau: der Technologie-Akzent laeuft gegenlaeufig durch die rechte Haelfte. */
.scenes__bg::after{
  background:
    radial-gradient(54% 68% at 84% 26%, rgba(77,166,255,.24), transparent 70%),
    radial-gradient(44% 58% at 96% 82%, rgba(77,166,255,.12), transparent 72%);
  transform:translate3d(calc(var(--p,0) * 7%), calc(var(--p,0) * -11%), 0);
}

/* Ueber den Verlaeufen liegt ein ruhiger Schleier, damit der Text auf jeder
   Scrollposition genug Kontrast hat. */
.scenes__scrim{
  position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(
    100deg,
    rgba(21,22,26,.86) 0%,
    rgba(21,22,26,.55) 42%,
    rgba(21,22,26,.28) 70%,
    rgba(21,22,26,.52) 100%
  );
}
@media (max-width:899px){
  /* Auf kleinen Flaechen liegt der Text ueber dem Verlauf statt daneben,
     deshalb gleichmaessiger und dunkler. */
  .scenes__scrim{background:rgba(21,22,26,.72)}
}

/* ---------- Szene: Grundzustand (statisch, ohne JS) ---------- */
.scene{
  position:relative;z-index:2;
  width:100%;max-width:var(--container);margin-inline:auto;
  padding-inline:var(--pad);
  padding-block:2.5rem;
}
.scene + .scene{border-top:1px solid var(--ww-border-dark)}

.scene__text{max-width:52ch}
.scene__name{
  font-family:var(--font-headline);font-size:.75rem;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ww-green);
  margin:0 0 .9rem;
}
.scene__text h2{color:var(--ww-text-light);margin-bottom:.7rem}
.scene__text .lead{color:var(--ww-text-soft);margin-bottom:1.6rem}

/* Das Video-Rechteck. Feste 16:9-Flaeche, damit nichts springt, waehrend das
   Video laedt. Der helle Rand traegt die Flaeche vor dem dunklen Hintergrund. */
.scene__media{
  position:relative;aspect-ratio:16/9;overflow:hidden;
  border-radius:var(--radius-lg);
  border:1px solid var(--ww-border-dark);
  background:var(--ww-graphite);
  box-shadow:0 30px 80px rgba(0,0,0,.45);
}
.scene__poster,
.scene__video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;
}
/* Das Video liegt ueber dem Poster und wird erst sichtbar, wenn es laeuft.
   So gibt es keinen schwarzen Rahmen zwischen Laden und erstem Frame. */
.scene__video{opacity:0;transition:opacity .5s ease}
.scene__video[data-playing="true"]{opacity:1}

/* ---------- Sequenz (erst mit JavaScript) ----------
   Die Hoehe der Sektion ist die Scrollstrecke: 100svh traegt die Buehne,
   je Szene rund 90svh Weg. Hero und Raster sind kuerzer angesetzt als die
   vier Einzelszenen — sie sind Bruecke, kein Aufenthalt. */
/* Hoehe traegt die Scrollstrecke aller Szenen. Sie muss mitwachsen, wenn eine
   Szene dazukommt — sonst laeuft dieselbe Strecke durch mehr Szenen und jede
   einzelne zieht spuerbar schneller vorbei. Aktuell: Hero + Raster + fuenf. */
.scenes.is-enhanced{padding:0;height:720svh}
@media (max-width:899px){.scenes.is-enhanced{height:630svh}}
.scenes.is-enhanced .scenes__stage{
  position:sticky;top:0;
  height:100svh;min-height:520px;
  overflow:clip;isolation:isolate;
  display:flex;align-items:center;
}
.scenes.is-enhanced .scene{
  position:absolute;inset:0;
  display:flex;flex-direction:column;justify-content:center;
  padding-block:clamp(4.5rem,10svh,7rem) clamp(4rem,9svh,6rem);
  border-top:0;

  /* Vom Skript gesetzt: Deckkraft, Verschiebung, Groesse */
  --o:0;--y:0px;--s:1;
  opacity:var(--o);
  transform:translate3d(0,var(--y),0) scale(var(--s));
  will-change:opacity,transform;
  pointer-events:none;
}
.scenes.is-enhanced .scene[data-active="true"]{pointer-events:auto}

/* Ab 900 px stehen Text und Video nebeneinander.
   Die Buehne ist einen ganzen Bildschirm hoch; mit der regulaeren
   Container-Breite von 1200 px bliebe zu viel Luft. Die Sequenz bekommt
   deshalb als einzige Sektion einen breiteren Rahmen und ein deutlich
   groesseres Bildfeld. */
@media (min-width:900px){
  .scenes.is-enhanced .scene{
    max-width:1320px;
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);
    gap:clamp(2rem,5vw,4rem);
    align-items:center;
  }
  .scene__text{max-width:44ch}
  .scenes.is-enhanced .scene__text h2{font-size:clamp(2rem,3.2vw,2.9rem)}
}
/* Darunter: Video oben, Text darunter. Die Hoehenbegrenzung stellt sicher,
   dass der Button ohne Scrollen erreichbar bleibt. */
@media (max-width:899px){
  .scenes.is-enhanced .scene__media{margin-bottom:1.75rem;max-height:34svh}
  .scenes.is-enhanced .scene__media{order:-1}
  .scenes.is-enhanced .scene__text h2{font-size:clamp(1.4rem,5.5vw,2rem)}
  .scenes.is-enhanced .scene__text .lead{font-size:.98rem;margin-bottom:1.25rem}

  /* Seit der Text nicht mehr abgeschnitten werden darf (kein line-clamp mehr),
     braucht die Buehne auf kurzen Mobilgeraeten mehr Spielraum als die fuer
     Desktop bemessenen Werte hergeben. Enger gefasste Mindestwerte, damit auf
     einem iPhone SE (667 px Hoehe) nichts an den Buehnenraendern verschwindet. */
  .scenes.is-enhanced .scene{
    /* Der obere Wert muss die Hoehe des fixierten Headers ausgleichen (Logo
       110px + Padding, auf schmalen Geraeten oft ueber 100px). Die alte
       Untergrenze 2.5rem (40px) griff auf kurzen Bildschirmen (iPhone SE:
       375x667) und liess die Ueberschrift unter den Header rutschen. Fest auf
       80px statt einer Untergrenze im clamp(), damit der Abstand nie
       schrumpft, egal wie kurz das Geraet ist. */
    padding-block:100px clamp(2rem,5svh,3rem);
    /* Sicherheitsnetz: die Groessen oben sind auf den heutigen Text getunt
       und decken alle gaengigen Geraete ab 375 px Hoehe ab (gemessen). Faellt
       ein Geraet trotzdem kleiner aus oder wird ein Text spaeter laenger,
       wird die Szene selbst scrollbar statt hart am Buehnenrand
       abzuschneiden — "kein Text abgeschnitten" bleibt dadurch auch dann
       wahr, wenn diese Zahlen nicht mehr aktuell sind. Bei ausreichendem
       Platz greift es nie: kein Overflow, kein sichtbarer Unterschied.

       Kein overscroll-behavior:contain hier. Die Szene ist durch overflow-y
       bereits ein Scrollcontainer — auch dann, wenn sie gar nichts zu scrollen
       hat. `contain` haette die Wischgeste in diesem leeren Container gehalten
       und ihre Weitergabe an das Dokument verboten: die Seite liess sich auf
       Touchgeraeten in der gesamten Sequenz nicht mehr scrollen. Der
       Vorgabewert `auto` reicht die Geste weiter, sobald die Szene selbst am
       Ende ist. */
    overflow-y:auto;
  }
}

/* ==========================================================================
   Ouvertuere: Hero → Raster → Einzelszenen
   ========================================================================== */

/* ---------- Hero wird eingesogen ----------
   Der Hero ist die erste Szene der Buehne, nicht eine Sektion davor. Nur so
   kann er in die Tiefe sinken, waehrend die Kacheln ihn umschliessen — laege
   er davor, wuerde er lediglich hochscrollen.

   Er kippt dabei perspektivisch nach hinten statt nur zu schrumpfen. Das ist
   der Unterschied zwischen "wird kleiner" und "faellt in die Szene hinein".
   --o ist 1, solange er steht, und laeuft beim Einsinken auf 0. */
.scenes.is-enhanced .scene--hero{
  transform:
    perspective(1400px)
    translate3d(0, calc((1 - var(--o,1)) * -6svh), calc((1 - var(--o,1)) * -420px))
    rotateX(calc((1 - var(--o,1)) * 9deg))
    scale(calc(1 - (1 - var(--o,1)) * 0.10));
  transform-origin:50% 30%;
}
/* Der Hero-Text folgt der Szene: man soll ihn schrumpfen und verblassen sehen,
   das ist die Bewegung. Getrennt wird stattdessen die Ueberschrift des Rasters,
   siehe unten — zwei Ueberschriften gleichzeitig sind unlesbar, ein
   schrumpfender Hero neben hereinfahrenden Kacheln ist der Effekt selbst. */

/* ---------- Raster-Szene ----------
   Zeigt alle vier Leistungen gleichzeitig: der Ueberblick, bevor die Sequenz
   sie einzeln aufgreift. Nutzt dieselbe Szenenmechanik, nur mit anderem Inhalt. */
/* Das Raster ist reine Uebergangsdramaturgie. Ohne die Sequenz traegt es keine
   Information, die nicht direkt darunter stuende — im statischen Grundzustand
   und bei reduzierter Bewegung entfaellt es deshalb ganz. */
.scene--grid{display:none}
.scenes.is-enhanced .scene--grid{display:flex}

.scene--grid .scene__text{max-width:none;text-align:center;margin-inline:auto}
.scene--grid h2{margin-bottom:1.5rem}
/* Die Ueberschrift des Rasters kommt spaeter als die Kacheln — erst wenn der
   Hero-Text verschwunden ist. Die Kacheln duerfen sich mit ihm ueberschneiden,
   zwei Ueberschriften duerfen es nicht. */
.scenes.is-enhanced .scene--grid .scene__text{
  opacity:clamp(0, calc((var(--in,1) - 0.78) / 0.22), 1);
}

/* Flex statt Grid: fuenf Kacheln gehen in keiner Spaltenzahl glatt auf, es
   bleibt immer eine unvollstaendige letzte Reihe. Im Grid klebt sie
   linksbuendig, im zentrierten Flexbereich sitzt sie mittig — und zwar in
   jeder Spaltenzahl, ohne Sonderregel fuer eine bestimmte Kachelzahl. */
.scene-grid{
  --grid-gap:clamp(.6rem,1.6vw,1.1rem);
  display:flex;flex-wrap:wrap;justify-content:center;
  gap:var(--grid-gap);
  width:100%;
}
.scene-grid__item{flex:0 1 calc((100% - var(--grid-gap)) / 2);min-width:0}

/* Ab Tablet drei nebeneinander: mit fuenf Kacheln waeren es zweispaltig drei
   Reihen, und die dritte laeuft unten in den Video-Schalter. Dreispaltig sind
   es zwei Reihen, die sicher in die Buehne passen. */
@media (min-width:640px){
  .scene-grid__item{flex-basis:calc((100% - 2 * var(--grid-gap)) / 3)}
}

/* Unter 640px bleiben es zwei Spalten und damit drei Reihen. Der Schalter
   sitzt absolut am Buehnenboden, deshalb hier zusaetzlicher Fussraum — die
   Szene ist vertikal zentriert, die Wirkung ist also die halbe Angabe. */
@media (max-width:639px){
  .scenes.is-enhanced .scene--grid{padding-bottom:9rem}
}

@media (min-width:900px){
  /* Das Raster ist einspaltig: Ueberschrift oben, die Kacheln darunter.
     Deshalb kein Zweispalten-Grid wie bei den Einzelszenen, aber weiterhin
     vertikal zentriert in der Buehne. */
  .scenes.is-enhanced .scene--grid,
  .scenes.is-enhanced .scene--hero{
    display:flex;flex-direction:column;justify-content:center;max-width:1320px;
  }
  .scene--grid .scene__text{margin-bottom:2rem}
  /* Fuenf nebeneinander brauchen Breite, sonst werden die Kacheln zu schmal.
     Darunter bricht das Raster auf 3+2 um — das passt vertikal in die Buehne. */
  .scene-grid{max-width:1080px;margin-inline:auto}
  .scene-grid__item{flex-basis:calc((100% - 2 * var(--grid-gap)) / 3)}
}
@media (min-width:1360px){
  .scene-grid{max-width:1500px}
  .scene-grid__item{flex-basis:calc((100% - 4 * var(--grid-gap)) / 5)}
}

/* Die Kacheln fahren von ausserhalb des Bildes herein und richten sich beim
   Ankommen gerade — dieselbe Bewegung, die den Hero in die Tiefe kippen laesst,
   nur andersherum. Jede Kachel bekommt ihre Startposition per --fx / --fy / --fr
   im HTML; --in laeuft dabei von 0 auf 1 und bleibt dann stehen. */
.scene-grid{perspective:1400px}
.scene-grid__item{
  position:relative;
  --fx:0; --fy:0; --fr:0;
  /* Reichweite der Einfahrt. Auf dem Desktop stehen vier Kacheln nebeneinander,
     da tragen weite Wege. Im 2×2-Raster auf dem Handy ragen dieselben Wege halb
     aus dem Bild und die Kacheln verdecken sich gegenseitig — dort deutlich
     kuerzer und flacher. */
  --reach:1;
  transform:
    translate3d(
      calc((1 - var(--in,1)) * var(--fx) * var(--reach) * 1%),
      calc((1 - var(--in,1)) * var(--fy) * var(--reach) * 1%),
      calc((1 - var(--in,1)) * var(--reach) * -260px)
    )
    rotateY(calc((1 - var(--in,1)) * var(--fr) * var(--reach) * 1deg))
    rotateX(calc((1 - var(--in,1)) * var(--reach) * 8deg));
  will-change:transform;
}
@media (max-width:899px){
  .scene-grid__item{--reach:.42}
}
.scene-grid__item .scene__media{
  aspect-ratio:16/10;
  box-shadow:0 14px 40px rgba(0,0,0,.4);
}
.scene-grid__label{
  display:block;margin-top:.6rem;
  font-family:var(--font-headline);font-size:1.4375rem;font-weight:500;
  color:var(--ww-text-light);letter-spacing:.01em;line-height:1.25;
  /* "Prozessautomatisierung" ist breiter als die Kachel und liefe sonst rechts
     heraus. Die Trennstelle steht als &shy; im HTML, weil hyphens:auto ein
     deutsches Trennwoerterbuch voraussetzt, das nicht jeder Browser mitbringt —
     ohne Woerterbuch braeche break-word das Wort ohne Trennstrich um.
     break-word bleibt als letzte Absicherung stehen. */
  hyphens:manual;overflow-wrap:break-word;
}
@media (max-width:640px){
  /* 1.325rem liess "automatisierung" nach der Trennung noch aus der 170px
     breiten Kachel laufen — dann bricht break-word ein zweites Mal und es
     bleibt ein einzelnes "g" stehen. */
  .scene-grid__label{font-size:1.15rem}
  .scene--grid h2{font-size:clamp(1.3rem,5.2vw,1.8rem)}
}

/* ---------- Fortschritt ----------
   Vier Segmente statt Ziffern an den Ueberschriften: die Reihenfolge ist eine
   Eigenschaft des Scrollens, nicht der Leistungen. */
/* z-index 3: die aktive Szene liegt auf 2 und wuerde Leiste und Schalter
   sonst verdecken — der Schalter waere dann nicht anklickbar. */
.scenes__progress{
  position:absolute;left:var(--pad);right:var(--pad);bottom:clamp(1.5rem,4svh,2.5rem);
  z-index:3;
  display:none;gap:.5rem;max-width:1320px;margin-inline:auto;
  pointer-events:none;
}
.scenes.is-enhanced .scenes__progress{display:flex}
.scenes__progress span{
  flex:1;height:2px;background:rgba(255,255,255,.14);border-radius:2px;overflow:hidden;
}
.scenes__progress span::after{
  content:"";display:block;height:100%;width:100%;
  background:var(--ww-green);
  transform:scaleX(var(--fill,0));transform-origin:left;
  transition:transform .15s linear;
}

/* ---------- Schalter fuer die Videowiedergabe ----------
   Nur sichtbar, wenn das Skript entschieden hat, dass Videos zunaechst nicht
   geladen werden (schmaler Viewport, Datensparmodus, langsame Verbindung). */
.scenes__optin{
  position:absolute;left:50%;transform:translateX(-50%);
  bottom:clamp(2.75rem,7svh,4rem);z-index:3;
  display:none;align-items:center;gap:.6rem;
  padding:.5rem .9rem;min-height:44px;
  background:rgba(255,255,255,.07);
  border:1px solid var(--ww-border-dark);
  border-radius:999px;
  color:var(--ww-text-light);
  font-family:var(--font-headline);font-size:.8125rem;font-weight:500;
  cursor:pointer;white-space:nowrap;
}
.scenes__optin[data-visible="true"]{display:inline-flex}
.scenes__optin:hover{background:rgba(255,255,255,.12)}
.scenes__optin small{color:var(--ww-text-light-muted);font-weight:400}

/* ---------- Weniger Bewegung ----------
   Sticky wird vollstaendig aufgehoben. Die Szenen stehen dann so untereinander
   wie im Grundzustand ohne JavaScript. */
@media (prefers-reduced-motion:reduce){
  .scenes.is-enhanced{padding:3.5rem 0;height:auto}
  .scenes.is-enhanced .scenes__stage{
    position:static;height:auto;min-height:0;display:block;overflow:visible;
  }
  .scenes.is-enhanced .scene{
    position:relative;inset:auto;
    display:block;padding-block:2.5rem;
    opacity:1;transform:none;pointer-events:auto;will-change:auto;
  }
  .scenes.is-enhanced .scene + .scene{border-top:1px solid var(--ww-border-dark)}
  .scenes.is-enhanced .scene__media{max-height:none;margin-bottom:1.75rem}
  .scenes.is-enhanced .scenes__progress,
  .scenes.is-enhanced .scene--grid,
  .scenes__optin{display:none}
  .scene__video{transition:none}
  /* Kein Einsaugen des Heros, kein wandernder Verlauf. */
  [data-hero-shrink]{transform:none;opacity:1}
  .scenes__bg::before,.scenes__bg::after{transform:none}
}
