/* ============================================================================
   system-timeline.css — PREVIEW / TESTSEITE  (/system-timeline/)
   Idee: die bestehende "Das System"-Section (3 Module) bekommt den
   Scroll-Fill-Timeline-Effekt der /manifest-Seite. Die Timeline-Punkte sitzen
   auf Höhe der drei Eyebrows (sys-pill: "Relevance Architecture" …).

   WICHTIG — autark & nicht-invasiv:
   - ALLES ist unter der Body-Klasse `.ll-systl` gescoped → styles.css /
     manifest.css / die Live-Section bleiben unberührt.
   - Tokens (Farben/Fonts) kommen aus styles.css.
   ========================================================================== */

body.ll-systl-body {
  margin: 0;
  min-height: 100vh;
  color: #fff;
  background: #000 !important;
  overflow-x: hidden;
}

/* Etwas mehr Luft oben (fixer Header); unten moderater Abstand zu den Testimonials
   statt der 300px-Default-Section-Bottom. */
.ll-systl .system { padding-top: clamp(130px, 16vh, 190px); padding-bottom: clamp(90px, 12vh, 150px); }

/* ---------------------------------------------------------------------------
   1) Modul-"Karte" OHNE Background (Jans Vorgabe). Die dunkle .sys-visual-Box
      bleibt erhalten — nur der radial-gradient-Karten-Background der .sys-module
      verschwindet. Module direkt auf Schwarz (wie die Manifest-Timeline).
   --------------------------------------------------------------------------- */
.ll-systl .sys-module {
  background: none;
  border-radius: 0;
  padding: 0;
  max-width: none;
  margin: clamp(240px, 24vh, 285px) auto;   /* +100px Lücke; Margins kollabieren → Lücke = 1× Margin, daher +100 (nicht +50) */
  /* Visual & Text auseinanderrücken → Platz für die Linie in der Mitte */
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(34px, 5.4vw, 92px);
  position: relative;
  z-index: 1;
  /* Modul-Fade aus styles.css AUS — Reveal passiert jetzt pro Teil (Text hellt auf,
     Visual gleitet von links). Transforms am Visual = kein Reflow → Punkt-Messung exakt. */
  opacity: 1 !important;
  transform: none !important;
}

/* ---- Reveal-Modell (an .sys-tl-reached gekoppelt, reversibel) — angelehnt an die
   Manifest-Timeline. FOUC-Guard html.systl-js: dim-Startzustand greift NUR mit JS. ---- */
/* Textspalte: vorher NICHT da (opacity 0) → kommt beim Erreichen von RECHTS
   abgebremst herein (kein Dauer-Dim mehr). So scheinen darunterliegende Module
   NICHT durch, wenn oben eine Checkliste aufgeklappt ist (sonst zu viel Text). */
.ll-systl .sys-text { transition: opacity 0.45s ease, transform 1.5s cubic-bezier(0.16, 1, 0.22, 1); }
html.systl-js .ll-systl .sys-text { opacity: 0; transform: translateX(48px); }
html.systl-js .ll-systl .sys-module.sys-tl-reached .sys-text { opacity: 1; transform: none; }

/* Visual: vorher UNSICHTBAR. Taucht SCHNELL aus der Transparenz auf (opacity ~0.3s)
   und gleitet dabei LANG & weich von UNTEN rein (transform 2s, starkes Ausbremsen).
   Trigger DESKTOP = .sys-tl-reached → erscheint GLEICHZEITIG mit dem Text (Jans
   Vorgabe; vorher .sys-tl-near = früher). Mobile triggert über .is-visible (Mobile-Block). */
/* align-self:start → Visual behält seine eigene Höhe und wächst NICHT mit, wenn
   die Outcome-Liste aufklappt (sonst streckt align-items:stretch die Box). */
.ll-systl .sys-visual { align-self: start; transition: opacity 0.3s ease, transform 2s cubic-bezier(0.16, 1, 0.22, 1); }
html.systl-js .ll-systl .sys-visual { opacity: 0; transform: translateY(60px); }
html.systl-js .ll-systl .sys-module.sys-tl-reached .sys-visual { opacity: 1; transform: none; }

/* Modul-2 Visual: align-self:start (oben, gegen Wachsen beim Aufklappen) bricht die
   Prozent-Höhe von .m2-scene (height:100%) → die Scene fällt auf ihre min-height
   zurück und wird kürzer als im Index (660 statt 740). Dadurch rutscht der Funnel
   hoch und die Social-Logos schauen darunter hervor. Fix: Scene-Höhe per
   --m2-scene-min auf die Index-Höhe setzen (Visual-Contentbox 770 − Padding 30 =
   740) → Funnel sitzt tiefer, Logos haben Raum darüber. Nur Desktop; Mobile (≤860px)
   behält seine eigene 570er-Höhe aus styles.css. */
@media (min-width: 861px) {
  .ll-systl .sys-visual--m2 .m2-scene { --m2-scene-min: 740px; }
}

/* Textspalte näher an die Linie rücken (linkes Padding klein), rechts/oben/unten
   moderat — Eyebrow sitzt dann dicht neben dem Punkt (wie Jahr↔Punkt im Manifest) */
.ll-systl .sys-text {
  /* OBEN ausgerichtet: beim Aufklappen wächst die Liste nur nach unten, der
     angeklickte Punkt bleibt fix, der Abstand zum nächsten Modul bleibt gleich. */
  justify-content: flex-start;
  padding: clamp(22px, 5vw, 60px) clamp(20px, 4vw, 52px)
           clamp(22px, 5vw, 60px) clamp(10px, 1.6vw, 24px);
}

/* Die alten Pfeile zwischen den Modulen entfallen — die Timeline-Linie ist der
   neue Verbinder. (Im HTML bleiben sie stehen → 1-Zeilen-Revert.) */
.ll-systl .sys-arrow { display: none; }

/* ---------------------------------------------------------------------------
   2) Timeline-Track + zentrale Linie (1:1 Logik aus manifest.css)
      Rail liegt mittig (left:50%) im Gutter zwischen Visual & Text.
      top/height werden per JS auf den ersten → letzten Eyebrow gesetzt.
   --------------------------------------------------------------------------- */
.ll-systl .sys-tl-track {
  position: relative;
  max-width: 1120px;
  margin: 0 auto;
}

.ll-systl .sys-tl-rail {
  position: absolute;
  top: 0;
  height: 100%;
  left: 50%;
  width: 2px;
  transform: translateX(-50%);
  background: rgba(255, 255, 255, 0.1);
  border-radius: 2px;
  z-index: 0;
  pointer-events: none;
  /* Beide Enden laufen TRANSPARENT aus (Linie + grüne Füllung): oben blendet sie
     weich EIN (kurz unter der Sub-Headline, Start via JS bis [data-sys-tl-start]),
     unten löst sie sich in die Outro-Headline auf (Ende bis [data-sys-tl-end]). */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 clamp(120px, 16vh, 180px), #000 calc(100% - clamp(120px, 16vh, 180px)), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 clamp(120px, 16vh, 180px), #000 calc(100% - clamp(120px, 16vh, 180px)), transparent 100%);
}
/* Gefüllter Teil — Höhe kommt GEDÄMPFT per JS (läuft nach / bremst aus).
   Kein Punkt/Kopf am Ende — nur die Linie selbst (wie Manifest). */
.ll-systl .sys-tl-rail__fill {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0;
  background: linear-gradient(180deg,
    rgba(var(--c-accent-rgb), 0.3) 0%, var(--c-accent) 16%, var(--c-accent) 100%);
  border-radius: 2px;
  will-change: height;
}

/* ---- Outro: die Linie läuft über den letzten Punkt hinaus weiter und mündet
   transparent auslaufend in diese Headline (Ergebnis der „Zeitreise"). ---- */
.ll-systl .sys-tl-outro {
  --outro-pad: clamp(120px, 17vh, 210px);
  position: relative;
  text-align: center;
  max-width: 900px;
  margin: 0 auto;
  padding: var(--outro-pad) var(--pad) 0;
}
.ll-systl .sys-tl-outro-title {
  font-family: var(--serif); font-weight: 500;
  font-size: clamp(34px, 4.8vw, 60px); line-height: 1.12;
  letter-spacing: -0.02em; color: #fff; margin: 0;
}
.ll-systl .sys-tl-outro-title em { font-style: normal; color: var(--c-accent); }
/* Headline blendet DANACH soft von unten ein (Index-Pattern), getriggert von der
   Engine (`is-revealed`), sobald die Füll-Linie den Check/Endpunkt erreicht hat.
   FOUC-Guard html.systl-js → ohne JS ist die Headline normal sichtbar. */
.ll-systl .sys-tl-outro-title { transition: opacity 1.15s ease, transform 1.15s cubic-bezier(0.16, 1, 0.3, 1); }
html.systl-js .ll-systl .sys-tl-outro-title { opacity: 0; transform: translateY(50px); }
html.systl-js .ll-systl .sys-tl-outro-title.is-revealed { opacity: 1; transform: none; }
/* Endpunkt der Linie: am Abschluss-Check (knapp in dessen Oberkante) — die Linie
   löst sich auf der Anfahrt transparent auf und „mündet" in den Check. */
.ll-systl .sys-tl-end {
  position: absolute; left: 50%; top: calc(var(--outro-pad) + 12px);
  width: 1px; height: 1px; transform: translateX(-50%);
}

/* Abschluss-Check über der Headline — 1:1 vom CTA-Umfrage-Check (Akzent-Haken
   zeichnet sich ein, grauer Kreis dahinter, Pop-Scale). Trigger: .is-done beim
   Reinscrollen (IntersectionObserver in system-timeline.js). Keyframes ctaCheckPop
   / ctaChartDraw kommen aus styles.css. */
.ll-systl .systl-done {
  width: clamp(76px, 9vw, 94px);
  height: clamp(76px, 9vw, 94px);
  margin: 0 auto clamp(26px, 4vh, 46px);
  transform-origin: center;
  opacity: 0;                                  /* versteckt bis .is-done */
}
.ll-systl .systl-done svg { width: 100%; height: 100%; display: block; }
.ll-systl .systl-done circle { fill: rgba(255, 255, 255, 0.1); }   /* grauer Kreis auf Schwarz */
.ll-systl .systl-done path {
  stroke: var(--c-accent); stroke-width: 1.2; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 1;   /* zeichnet sich ein */
}
.ll-systl .systl-done.is-done { animation: ctaCheckPop 1.6s cubic-bezier(0.16, 1, 0.3, 1) both; }
.ll-systl .systl-done.is-done path { animation: ctaChartDraw 1.6s 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
@media (prefers-reduced-motion: reduce) {
  .ll-systl .systl-done { opacity: 1; animation: none; }
  .ll-systl .systl-done path { stroke-dashoffset: 0; animation: none; }
  html.systl-js .ll-systl .sys-tl-outro-title { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------------------
   Testimonials-Indikator: Story-Progress statt Dots. Aktives Segment ist ~2×
   breit mit einer Füll-Linie (links→rechts), die parallel zur Verweildauer läuft;
   am Ende springt es automatisch aufs nächste Segment (JS in der Section). */
.ll-systl .systl-seg {
  position: relative; height: 1px; width: 16px; border-radius: 999px;
  padding: 0; border: 0; cursor: pointer; background: var(--c-ink-faint);
  transition: width 0.8s cubic-bezier(0.33, 1, 0.68, 1), background 0.5s ease;   /* Breiten-Wechsel aktiv↔inaktiv: softer + langsamer (war 0.5s) */
}
/* Unsichtbarer, höherer Klick-/Touch-Bereich: 10px ÜBER + UNTER der 1px-Linie
   (Treffer-Zone ~21px hoch) — die sichtbare Linie bleibt 1px. Kein overflow:hidden
   mehr (würde dieses ::after wegschneiden); die Füll-Linie liegt ohnehin in der Box. */
.ll-systl .systl-seg::after {
  content: ''; position: absolute; left: 0; right: 0; top: -10px; bottom: -10px;
}
.ll-systl .systl-seg:hover { background: var(--c-ink-soft); }
.ll-systl .systl-seg.is-active { width: 72px; background: rgba(255, 255, 255, 0.18); }
.ll-systl .systl-seg__fill {
  position: absolute; left: 0; top: 0; height: 100%; width: 0;
  border-radius: 999px; background: var(--c-accent);
}
.ll-systl .systl-seg:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 3px; }

/* ---------------------------------------------------------------------------
   Testimonial-Zitat (Caveat-Handschrift) schreibt sich „rein": Text voll da in
   Dunkelgrau, das Weiß wischt zügig von links→rechts rein. Trigger: .is-writing
   per JS bei Card-Aktivierung (Viewport-Erreichen + Card-Wechsel). */
/* Slider-Inhalte oben andocken (nicht vertikal zentriert) → alle Cards starten am
   selben oberen Rand; nur die Pagination bleibt dadurch unten fix. */
.ll-systl .ks-quote { justify-content: flex-start; }
/* Reihenfolge in der Card (Jans Vorgabe): rundes Foto (1) GANZ OBEN → Handschrift (2)
   → Name/Unternehmen (3) unten. Foto zuerst = „man sieht ein Gesicht", persönliche Ebene. */
.ll-systl .ks-quote__photo { order: 1; margin: 0 0 24px; }
.ll-systl .ks-quote__text  { order: 2; font-size: clamp(43px, 5.4vw, 57px); margin-bottom: 5px; }   /* Name/Subline knapp drunter (5px tiefer) — line-height der Handschrift als Grundabstand */
.ll-systl .ks-quote__meta  { order: 3; margin-bottom: 0; gap: 0; line-height: 1.3; }
/* Name + Jobbezeichnung GLEICH groß (Name 1px kleiner = 17px, Rolle genauso); Abstand
   dazwischen NUR über die line-height der Meta (kein gap mehr). */
.ll-systl .ks-quote__name,
.ll-systl .ks-quote__role { font-size: 17px; }

/* ---- Foto-Slide-Bühne (Option ①): aktives Foto gleitet GERICHTET rein/raus — alt schnell
   links raus, neu abgebremst von rechts rein (transform+opacity setzt das JS asymmetrisch).
   Greift NUR, wo .ks-photo-stage im DOM existiert (Testseite) → Live unberührt. ---- */
.ll-systl .ks-photo-stage { position: relative; width: 150px; height: 150px; margin: 0 auto 24px; transition: opacity .8s ease; }
html.systl-js .ll-systl .ks-quotes:not(.is-revealed) .ks-photo-stage { opacity: 0; }   /* blendet mit der Section ein */
.ll-systl .ks-cf-photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border-radius: 50%; object-fit: cover;   /* KEIN background: das deckende JPEG füllt den Kreis; ein dunkler bg rendert mit will-change+border-radius als schwarzes Quadrat über das vorherige Foto */
  opacity: 0; transform: translateX(0) scale(1); transform-origin: center center;
  will-change: transform, opacity;
}
@media (max-width: 560px) { .ll-systl .ks-photo-stage { width: 132px; height: 132px; } }
.ll-systl .ks-quote__text .systl-word { white-space: nowrap; }   /* Buchstaben eines Worts brechen nicht (inline-block würde sonst mitten im Wort umbrechen) */
.ll-systl .ks-quote__text .systl-char {
  display: inline-block;
  transition: opacity 0.55s ease;      /* SOFT einblenden (kein harter Clip → nicht abgehackt) */
}
/* verborgen NUR mit JS (FOUC-Guard): fällt die Engine aus und systl-js wird entfernt,
   sind die Buchstaben sichtbar statt unsichtbar. */
html.systl-js .ll-systl .ks-quote__text .systl-char { opacity: 0; }
/* is-writing MUSS die versteckt-Regel überbieten → ebenfalls html.systl-js davor
   (sonst ist der Verstecken-Selektor spezifischer und der Typewriter bleibt unsichtbar). */
html.systl-js .ll-systl .ks-quote__text.is-writing .systl-char { opacity: 1; }

/* Name + Foto kommen direkt nach dem Schreiben — NUR Fade, KEINE Bewegung:
   Handschrift fertig → Name (is-name-in), direkt danach Foto (is-photo-in). */
.ll-systl .ks-quote__meta,
.ll-systl .ks-quote__photo {
  transition: opacity 0.8s ease;
}
html.systl-js .ll-systl .ks-quote__meta,
html.systl-js .ll-systl .ks-quote__photo { opacity: 0; }
html.systl-js .ll-systl .ks-quote.is-name-in .ks-quote__meta { opacity: 1; }
html.systl-js .ll-systl .ks-quote.is-photo-in .ks-quote__photo { opacity: 1; }

/* Reveal-Gate der ganzen Section: Eyebrow + Pagination vorher unsichtbar, faden beim
   Reinscrollen (NACH der Outro-Headline) soft von unten ein — zeitgleich schreibt
   sich das erste Zitat rein. Trigger: .is-revealed via IO im Section-Skript.
   FOUC-Guard html.systl-js → ohne JS ist alles normal sichtbar. */
html.systl-js .ll-systl .ks-quotes__eyebrow,
html.systl-js .ll-systl .ks-quotes__dots {
  opacity: 0; transform: translateY(24px);
  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
html.systl-js .ll-systl .ks-quotes.is-revealed .ks-quotes__eyebrow,
html.systl-js .ll-systl .ks-quotes.is-revealed .ks-quotes__dots { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .ll-systl .ks-quote__text .systl-char { opacity: 1; }
  html.systl-js .ll-systl .ks-quote__meta, html.systl-js .ll-systl .ks-quote__photo { transition: none; opacity: 1; transform: none; }
  html.systl-js .ll-systl .ks-quotes__eyebrow, html.systl-js .ll-systl .ks-quotes__dots { transition: none; opacity: 1; transform: none; }
}
/* Startpunkt der Linie: kurz UNTER der Sub-Headline (im Intro, über dem 1. Punkt).
   Absolut positioniert → kein Layout-Einfluss; JS misst die Y-Position. */
.ll-systl .system-intro { position: relative; }
.ll-systl .sys-tl-start {
  position: absolute; left: 50%; bottom: -40px;
  width: 1px; height: 1px; transform: translateX(-50%);
}

/* ---- Knoten (Punkt) auf der Linie — vertikal per JS auf den Eyebrow gesetzt.
   Immer sichtbar (nur zu erahnen), leuchtet grün sobald erreicht (reversibel). */
.ll-systl .sys-tl-node {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.ll-systl .sys-tl-dot {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: #0a0a0c;
  border: 2px solid rgba(255, 255, 255, 0.13);
  transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1),
              background-color 0.45s ease, border-color 0.45s ease, box-shadow 0.45s ease;
}
.ll-systl .sys-tl-node.is-active .sys-tl-dot {
  background: var(--c-accent);
  border-color: var(--c-accent);
  transform: scale(1.2);
  box-shadow: 0 0 0 6px rgba(var(--c-accent-rgb), 0.14),
              0 0 22px 2px rgba(var(--c-accent-rgb), 0.55);
}

/* Eyebrow-Chip: ohne Karten-Background eine eigene dezente Fläche (sonst
   schwarz-auf-schwarz). Helligkeit kommt über .sys-text (dim → hell). */
.ll-systl .sys-pill { background: rgba(255, 255, 255, 0.05); }

/* ---------------------------------------------------------------------------
   Outcome-Liste pro Modul — klappt beim Klick auf die CTA nach unten auf; die
   folgenden Module + die Timeline rücken nach (ResizeObserver → remeasure in JS).
   Höhen-Animation via grid-template-rows 0fr→1fr (smooth, ohne JS-Höhenmessung).
   --------------------------------------------------------------------------- */
/* CTA „Benefits im Überblick": weiße Schrift + feiner Chevron (breites V) im Kreis,
   der sich beim Aufklappen um 180° dreht (V nach unten → gespiegelt nach oben). */
.ll-systl .sys-cta { cursor: pointer; color: var(--c-ink); gap: 12px; }
.ll-systl .sys-cta-chevron {
  flex: 0 0 32px; width: 32px; height: 32px; border-radius: 50%;
  /* vertikaler Gradient: oben heller, unten dunkler (Kippschalter-Optik) */
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.19), rgba(255, 255, 255, 0.035));
  color: var(--c-accent);
  display: inline-flex; align-items: center; justify-content: center;
  transform: perspective(260px) rotateX(0deg);
  transition: transform 0.5s cubic-bezier(0.45, 0, 0.25, 1);
}
.ll-systl .sys-cta-chevron svg { width: 25px; height: 25px; display: block; }
/* Klick = echter Kippschalter-Flip um die horizontale Achse (3D, perspektivisch
   abgebremst). Chevron ist im SVG vertikal zentriert (Pfad-Mitte = SVG-Mitte 12),
   daher kein Versatz beim Kippen; der Gradient dreht sich mit (oben↔unten). */
.ll-systl .sys-module.is-expanded .sys-cta-chevron { transform: perspective(260px) rotateX(180deg); }

.ll-systl .sys-outcome {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  margin-top: 0;
  transition: grid-template-rows 0.5s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.4s ease, margin-top 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.ll-systl .sys-outcome-inner { overflow: hidden; min-height: 0; }
.ll-systl .sys-module.is-expanded .sys-outcome { grid-template-rows: 1fr; opacity: 1; margin-top: 24px; }

.ll-systl .sys-outcome-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 16px;
}
/* Typo = Body-/Index-„NEW"-Liste (22px, 500). Check = globales .mc-item-icon--new
   (#icon-check, 24px Akzent) → 1:1 wie die Checkliste auf der Startseite. */
.ll-systl .sys-outcome-list li {
  display: flex; align-items: flex-start; gap: 8px;
  font-family: var(--sans); font-size: 22px; font-weight: 500;
  letter-spacing: -0.1px; line-height: 1.15; color: var(--c-ink);
}

/* ---------------------------------------------------------------------------
   3) Mobile — Module stapeln wie live (Visual oben/Text unten). Die mittige
      Linie ergibt einspaltig keinen Sinn → Rail + Punkte aus. (Eigene Mobile-
      Timeline ggf. später, analog manifest Links-Rail.)
   --------------------------------------------------------------------------- */
@media (max-width: 860px) {
  /* Section ist hier die ERSTE auf der Seite → Top-Abstand für den fixen Header.
     Muss die Live-Regel `.system{padding:10px!important}` überschreiben.
     Bottom: 140px = +100px Abstand zur Testimonials-Section danach. */
  .ll-systl .system { padding: clamp(92px, 15vw, 132px) 14px 140px !important; }

  /* LINKS angedockt: Timeline läuft ganz links, alle Inhalte (Visual, Text, Check,
     Headline) docken 10px rechts daneben an. Modul-Abstand 100px (unterhalb des
     Textblocks) — Margins kollabieren → 100px Margin = 100px Lücke. */
  .ll-systl .sys-module {
    grid-template-columns: 1fr;
    column-gap: 0;
    max-width: none;
    width: auto;                      /* sonst erzwingt eine Live-Regel volle Track-Breite → Margin-left ließe das Visual rechts überlaufen/beschneiden */
    margin: 100px 0 100px 26px;       /* links 26px → 10px neben der Rail (left:15px + 1px halbe Breite) */
  }
  .ll-systl .sys-tl-rail { left: 15px; transform: none; }
  .ll-systl .sys-tl-node { left: 15px; width: 18px; height: 18px; transform: translate(-50%, -50%); }
  .ll-systl .sys-tl-dot { width: 12px; height: 12px; }

  /* Outro (Check + Headline) ebenfalls LINKS angedockt — nicht mehr zentriert. */
  .ll-systl .sys-tl-outro { text-align: left; max-width: none; margin: 0; padding: var(--outro-pad) 14px 0 26px; }
  .ll-systl .systl-done { margin-left: 0; margin-right: auto; }

  /* Visual blendet auch auf Mobile von unten ein — ENGINE-getrieben über .sys-vis-in
     (Modul-Oberkante erreicht die VIS_IN-Linie in system-timeline.js), NICHT der Eyebrow
     (liegt gestapelt unter dem Visual). Zuverlässiger als der separate Inline-IO. Reversibel. */
  html.systl-js .ll-systl .sys-module.sys-vis-in .sys-visual { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .ll-systl .sys-tl-dot { transition: none; }
  /* Keine Glide-/Dim-Bewegung — alles sofort sichtbar/an Ort */
  html.systl-js .ll-systl .sys-text { opacity: 1; transform: none; }
  html.systl-js .ll-systl .sys-visual { opacity: 1; transform: none; }
}

/* Mobile-Outro: Check horizontal mittig (wie Desktop), die Linie laeuft LINKS
   WEITER nach unten parallel zum Text und loest sich ueber die letzten 170px
   transparent auf. Check + Headline sitzen hoeher. */
@media (max-width: 600px) {
  .ll-systl .sys-tl-outro { --outro-pad: 98px; }
  .ll-systl .systl-done { margin-left: auto; margin-right: auto; margin-bottom: 20px; position: relative; left: -6px; /* Padding-Asymmetrie 26/14 ausgleichen -> exakt Viewport-Mitte */ }
  .ll-systl .sys-tl-end { left: 16px; top: calc(var(--outro-pad) + 240px); }
  .ll-systl .sys-tl-rail {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 340px), rgba(0,0,0,0) 100%);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 340px), rgba(0,0,0,0) 100%);
  }
}
