/*
  ke-process-timeline: der Ablauf der Zusammenarbeit, was wann passiert, wenn
  man mit uns arbeitet. Bewusste Abgrenzung zu ke-method-flow (die eigene
  Methode): dieselbe Grundform aus Markierung, Verbindungslinie und
  Textkörper, aber eine andere Markierung. ke-method-flow markiert mit einem
  Icon in einem umrandeten Kreis, dieses Modul mit einer gesetzten Ziffer
  ohne Rahmen, siehe Qualitätsgrundlage Abschnitt 1: "Nummerierung ist ein
  Ordnungs- und Gestaltungsmittel", am Referenzbeispiel mit acht nummerierten
  Schritten (01 bis 08) belegt. Dazu ein eigenes Feld für Termin oder
  Zeitraum je Schritt: erst der Zeitbezug macht aus einer Liste eine
  Zeitachse.

  Dieselbe gemessene Regel wie bei ke-method-flow gilt hier unveraendert:
  eine waagerechte Achse vertraegt keinen ungleichen Inhaltsumfang, bei vier
  Schritten bleiben am gerenderten Dokument rund 230 Pixel je Schritt. Die
  Umschaltung ab dem vierten Schritt (":has()" weiter unten) und der
  Hilfetext beim Feld "layout" sind wortgleich aus ke-method-flow uebernommen,
  siehe dort fuer die vollstaendige Begruendung, warum keine der beiden
  Zusagen allein genuegt.

  Quer zu den drei Achsenlagen steht eine vierte Wahl, das Feld
  "station_card": ob eine Station frei auf der Sektionsflaeche steht oder auf
  einer eigenen Kartenflaeche liegt, deren Kopf der Termin ist. Sie ist eine
  Option und ersetzt nichts, ihre Begruendung steht am Regelblock weiter
  unten, samt der Abgrenzung zur Tafel von ke-method-flow.

  Farben: keine einzige neu gebildete Mischung, dieselben Werte wie bei
  ke-method-flow. Achse, Ziffer und Termin lesen var(--sec-accent), gemessen
  11,52:1 hell, 10,58:1 abgesenkt, 5,65:1 invertiert gegen die
  Sektionsfläche, also über der Textschwelle 4,5:1 auf allen drei Flächen.

  Die Ziffer las vorher var(--brand). Sie ist eine Nummer, und Nummern trägt
  der Akzent: die Marke gehört dem Handlungsaufruf, dem Link und der
  Hervorhebung im Text, siehe die Arbeitsteilung an --accent in tokens.css.
  Der Termin las vorher --sec-ink-muted und ist damit genau das Element in
  Grau gewesen, das dieses Modul überhaupt von ke-method-flow trennt ("erst
  der Zeitbezug macht aus einer Liste eine Zeitachse"). Er trägt jetzt den
  Akzent wie die Ziffer, beide markieren die Station.
*/

.ke-process-timeline__header {
  max-width: 42rem;
}

.ke-process-timeline__intro {
  color: var(--sec-ink-muted);
  font-size: var(--fs-lg);
}

.ke-process-timeline__steps {
  /* Bezugsrahmen des mitscrollenden Pfeils: er spannt ueber die volle Hoehe
     der Schrittfolge und nicht ueber einen einzelnen Schritt. */
  position: relative;

  /* Die Linienfarbe einmal für beide Achsenlagen, dieselbe Aufteilung wie
     bei ke-method-flow: sie steht am Container, weil sie zwei Verbraucher
     hat, die durchgehende Achse der waagerechten Lage (Container) und die
     Stücke der senkrechten (Schritt, erbt sie von hier). --sec-accent statt
     einer Graumischung aus --sec-ink, siehe die Arbeitsteilung der beiden
     Themefarben an --accent in tokens.css. */
  --flow-line: var(--sec-accent);

  display: flex;
  flex-direction: column;
  gap: var(--s-8);
}

.ke-process-timeline__step {
  /* Bezugsrahmen des Achsenstücks weiter unten: es spannt über die volle
     Höhe des Schritts und sitzt deshalb nicht an der Markierung, die nur
     so hoch ist wie ihre Ziffer. */
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--s-5);
}

/* Kein Rahmen, kein Kreis: die Markierung traegt hier ausschliesslich die
   Ziffer, keine umschliessende Form. Das ist der sichtbare Unterschied zu
   ke-method-flow und zugleich, warum hier kein "Kreis mit Symbol" als
   zweite Instanz derselben Formensprache entsteht. */
.ke-process-timeline__marker {
  position: relative;
  flex-shrink: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  min-width: var(--s-12);
  padding-block-start: var(--s-1);

  /* Die deckende Fläche gilt in JEDER Achsenlage, nicht nur waagerecht: die
     Achse läuft senkrecht durch die Markierung hindurch (siehe das
     Achsenstück unten) und würde ohne diese Fläche quer durch die Ziffer
     laufen. Es ist die Fläche der Sektion selbst, also nur als Aussparung
     in der Achse sichtbar, nicht als Kasten. Ein Rahmen entsteht dadurch
     nicht, der bleibt ke-method-flow. */
  background: var(--sec-bg);
}

.ke-process-timeline__index {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  line-height: 1;
  color: var(--sec-accent);
}

/*
  Die durchgehende Achse der senkrechten Lage, wortgleich dieselbe Bauart wie
  bei ke-method-flow, siehe dort für die vollständige Begründung: das Stück
  sitzt am SCHRITT und spannt vom Anfang des eigenen Schritts bis zum Anfang
  des nächsten, sodass die Stücke aneinanderstossen und EINE Linie bilden,
  unabhängig von der Höhe des Textkörpers.

  Vorher hing es an der Markierung und war 32px lang. Gemessen (1440px, fünf
  Schritte) lief es von 217,7 bis 249,7, die nächste Markierung begann bei
  308,7: 59px Nichts dahinter. Die Markierung ist hier nur so hoch wie ihre
  Ziffer (gemessen 36px), der Textkörper daneben trägt Termin, Titel und
  Absatz, deshalb war die Lücke noch grösser als bei ke-method-flow.

  Die Achse erscheint nur, wenn es Markierungen gibt, die sie verbinden kann.

  Vorher zeichnete sie unbedingt. Bei abgeschalteter Nummerierung
  (show_numbers false) blieb die Markierung aber leer, und damit lief eine
  zwei Pixel starke Akzentlinie als nackter Streifen an fuenf Textbloecken
  vorbei, waehrend der Text daneben um die 48 Pixel der leeren
  Markierungsspalte eingerueckt stand. Der Auftraggeber hat das am Beleg
  "Fuenf Termine mit Medium" als sloppige Striche beanstandet, und das war
  auch genau der Beleg, bei dem es auffallen musste: er ist der einzige mit
  abgeschalteter Nummerierung.

  Eine Achse ist eine Verbindung zwischen Knoten. Ohne Knoten hat sie
  nichts zu verbinden und ist bloss ein Strich, also genau das Merkmal, das
  Gesetz Null verbietet. Die Markierung selbst wird im Markup nur noch
  ausgegeben, wenn sie eine Nummer traegt, deshalb genuegt hier :has() auf
  ihre Anwesenheit: die Nummerierung schaltet damit BEIDES gemeinsam, die
  Knoten und ihre Verbindung, und die Einrueckung entfaellt gleich mit.
*/
.ke-process-timeline__steps:has(.ke-process-timeline__marker)
  .ke-process-timeline__step:not(:last-child)::before {
  content: "";
  position: absolute;
  inset-block: 0 calc(-1 * var(--s-8));
  inset-inline-start: calc(var(--s-12) / 2 - var(--line-strong) / 2);
  width: var(--line-strong);
  background: var(--flow-line);
}

.ke-process-timeline__body {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  padding-block-start: var(--s-2);
}

.ke-process-timeline__termin {
  color: var(--sec-accent);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

/* Der Titel traegt das Symbol des Schritts. inline-flex, nicht flex: der
   Titel ist ein strong und soll ein strong bleiben, und in der waagerechten
   Lage steht er in einem Koerper mit text-align: center, wo ein Blockelement
   mit voller Breite die Zentrierung des Zeichenpaars aufheben wuerde.
   align-items: center haelt das Symbol auf der Mitte der Titelzeile. */
.ke-process-timeline__title {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--sec-ink);
}

/* Der Akzent, nicht die Marke: die Marke gehoert dem Handlungsaufruf, dem
   Link und der Texthervorhebung, Symbole tragen den Akzent (tokens.css ab
   --accent). Dieselbe Farbe wie die Ziffer der Markierung und der Termin,
   damit Ziffer, Termin und Symbol als ein Satz Zeichen lesbar bleiben und
   nicht als drei verschiedene Systeme.

   --s-6 als Kantenlaenge, knapp unter der Titelgroesse (--fs-lg): das
   Symbol steht neben dem Titel, es ersetzt ihn nicht. Dasselbe Mass wie das
   Symbol an der Frage in ke-faq, das dieselbe Aufgabe an derselben Stelle
   erfuellt. */
.ke-process-timeline__icon {
  flex-shrink: 0;
  line-height: 0;
}

.ke-process-timeline__icon svg {
  display: block;
  width: var(--s-6);
  height: var(--s-6);
  fill: var(--sec-accent);
}

/* white-space: pre-line, weil das Feld ein Textfeld mit allow_new_line ist
   (HubSpot kennt keinen Feldtyp "textarea", siehe fields.json): ein
   Absatz Prosa trägt dadurch echte Zeilenumbrüche, ohne diese CSS-Regel
   würde der Browser sie zu Leerzeichen zusammenziehen und die Redaktion
   verlöre jede Gliederung, die sie im Editor eingegeben hat. */
.ke-process-timeline__text {
  margin: 0;
  color: var(--sec-ink);
  font-size: var(--fs-base);
  white-space: pre-line;
}

.ke-process-timeline__cta {
  margin-top: var(--s-2);
}

/*
  Waagerechte Achse, nur ab 992px: unterhalb bleibt jede Achse (auch
  --horizontal) die senkrechte Grundform von oben.
*/
@media (min-width: 992px) {
  /* position: relative ist der Bezugsrahmen der durchgehenden Achse
     weiter unten, dieselbe Aufteilung wie bei ke-compare-table
     (.ke-compare-table__body traegt relative, .__axis absolute). */
  .ke-process-timeline__steps--horizontal {
    position: relative;
    flex-direction: row;
    align-items: flex-start;
  }

  .ke-process-timeline__steps--horizontal .ke-process-timeline__step {
    flex: 1 1 0;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }

  /* Waagerecht kreuzt die Achse die Markierung quer: dieselbe
     Markierungshöhe wie bei ke-method-flow (var(--s-12)), die Ziffer darin
     senkrecht zentriert, dazu Luft links und rechts, damit die Aussparung in
     der Achse breiter ist als die Ziffer. Die deckende Fläche selbst steht
     schon in der Grundform, sie gilt in beiden Achsenlagen. */
  .ke-process-timeline__steps--horizontal .ke-process-timeline__marker {
    align-items: center;
    justify-content: center;
    min-height: var(--s-12);
    padding-block-start: 0;
    padding-inline: var(--s-3);
  }

  .ke-process-timeline__steps--horizontal .ke-process-timeline__body {
    align-items: center;
    padding-block-start: 0;
  }

  /* Waagerecht trägt die Achse der Container, nicht der Schritt: das
     senkrechte Stück bleibt hier aus. Begründung direkt darunter. */
  .ke-process-timeline__steps--horizontal .ke-process-timeline__step:not(:last-child)::before {
    display: none;
  }

  /*
    Die durchgehende Achse, dieselbe Bauart wie .ke-compare-table__axis:
    eine eigene, absolut positionierte Flaeche auf dem CONTAINER, nicht
    ein Fragment am Kind. Der Unterschied ist keine Geschmacksfrage,
    sondern der Grund, warum die alte Fassung defekt war: senkrecht ist
    der Abstand zweier Markierungen genau der gap (var(--s-8)), ein
    Stueck dieser Laenge an der Markierung reicht dort exakt bis zur
    naechsten. Waagerecht ist der Abstand zweier Markierungsmitten
    dagegen gap PLUS eine halbe Spalte auf jeder Seite, am gerenderten
    Dokument bei drei Schritten auf 1440px 397px statt 32px: das Stueck
    war ein 32px-Stummel mit 321px Leerraum dahinter. Derselbe Defekt
    ist am entfernten Diagramm-Layer schon einmal bezahlt worden
    (Diagnose damals: Kruemel je Luecke statt einer durchgehenden
    Achse), und die dortige Loesung ist diese hier.

    Die Achse laeuft von der Mitte der ersten bis zur Mitte der letzten
    Markierung. Dieser Einzug ist eine halbe Spalte, und eine Spalte ist
    bei flex: 1 1 0 gleich breit: (100% - (n-1) * gap) / n, halb also
    (100% - (n-1) * gap) / (2n). n steht nicht in CSS zur Verfuegung,
    also entscheidet die Kindanzahl darueber, derselbe :has()-Mechanismus
    wie bei der Umschaltung ab vier Schritten weiter unten. Mehr als die
    beiden Faelle n=2 und n=3 braucht es nicht: ab vier Schritten steht
    die Schrittfolge ohnehin senkrecht und traegt dort wieder das Stueck
    an der Markierung. Bei nur einem gerenderten Schritt bleibt die
    Achse aus, eine Achse ohne zweite Markierung verbindet nichts.

    Die Markierung deckt die Achse ab, wo sie sie kreuzt: sie ist
    position: relative und traegt eine deckende Flaeche, das Pseudoelement
    des Containers wird vor den Kindern gezeichnet. Deshalb braucht die
    Achse kein z-index und die Linie sitzt sichtbar zwischen den
    Markierungen, nicht ueber ihnen.
  */
  .ke-process-timeline__steps--horizontal:has(.ke-process-timeline__marker)::before {
    content: "";
    display: none;
    position: absolute;
    inset-block-start: calc(var(--s-12) / 2 - var(--line-strong) / 2);
    height: var(--line-strong);
    background: var(--flow-line);
  }

  .ke-process-timeline__steps--horizontal:has(> :nth-child(2)):not(:has(> :nth-child(3)))::before {
    display: block;
    inset-inline: calc(25% - var(--s-8) / 4);
  }

  .ke-process-timeline__steps--horizontal:has(> :nth-child(3)):not(:has(> :nth-child(4)))::before {
    display: block;
    inset-inline: calc(100% / 6 - var(--s-8) / 3);
  }

  /*
    Dieselbe gemessene Umschaltung wie ke-method-flow: ab dem VIERTEN Schritt
    kehrt die waagerechte Achse zur senkrechten Grundform zurueck,
    unabhaengig von der Layout-Wahl. Bis zu acht Schritte sind moeglich,
    ab dem vierten stehen sie also ohnehin senkrecht.
  */
  .ke-process-timeline__steps--horizontal:has(> :nth-child(4)) {
    flex-direction: column;
  }

  .ke-process-timeline__steps--horizontal:has(> :nth-child(4)) .ke-process-timeline__step {
    flex: initial;
    flex-direction: row;
    align-items: flex-start;
    text-align: start;
  }

  /* Zurueck auf die senkrechten Werte: ab vier Schritten gibt es keine
     waagerechte Achse mehr, und die Markierung soll wieder genau
     var(--s-12) breit sein. Die deckende Fläche bleibt, sie trägt jetzt die
     Aussparung der senkrechten Achse (Grundform oben); ihr Wegnehmen liess
     die Achse quer durch die Ziffer laufen. Die Breite ist der Grund für
     padding-inline: 0: eine Markierung, deren Breite an der Ziffernbreite
     hängt, versetzt die Achse gegen die Ziffernmitte (gemessen 169,5 /
     171,5 / 172 statt einer Linie). */
  .ke-process-timeline__steps--horizontal:has(> :nth-child(4)) .ke-process-timeline__marker {
    justify-content: center;
    align-items: flex-start;
    min-height: 0;
    padding-block-start: var(--s-1);
    padding-inline: 0;
  }

  .ke-process-timeline__steps--horizontal:has(> :nth-child(4)) .ke-process-timeline__body {
    align-items: flex-start;
    padding-block-start: var(--s-2);
  }

  /* display: block, weil die waagerechte Regel darüber das senkrechte Stück
     abgeschaltet hat: ab vier Schritten steht die Schrittfolge senkrecht und
     trägt dort wieder ihre Stücke, die zusammen die durchgehende Achse
     bilden, statt der Containerachse. */
  .ke-process-timeline__steps--horizontal:has(> :nth-child(4)) .ke-process-timeline__step:not(:last-child)::before {
    display: block;
  }
}

/*
  Die grosse Karte je Station, Feldwert "card". Eine OPTION neben der
  schlichten Grundform, kein Ersatz: die Vorgabe des Feldes ist "none", und
  ohne sie bleibt jede Regel oben unverändert wirksam.

  Sie ist ausdrücklich NICHT dieselbe Antwort, die ke-method-flow auf
  dieselbe Frage gibt. Dort wächst die Markierung zur umrandeten Tafel um
  den ganzen Schritt, weil dieses Modul mit einer umrandeten Tafel markiert.
  Hier markiert eine gesetzte Ziffer ohne jede umschliessende Form, und ein
  Rahmen um die Station würde genau die Form zurückholen, die dieses Modul
  bewusst nicht führt. Die Station wird deshalb eine FLÄCHE ohne Rahmen: die
  Kartenfläche des Themes, --sec-card-bg, dieselbe Machart wie .ke-faq__item
  (Polster --s-6, --radius-lg, Schattenstufe 1). Auf der hellen Sektion ist
  das das Hellgrau, auf der abgesenkten Weiss, auf der invertierten die
  angehobene dunkle Ebene: der Absatz kommt aus der Fläche, nicht aus einer
  Linie. Zwei Module, zwei Antworten, statt derselben Karte zweimal.

  Was die Karte zur Zeitachse macht, ist der Termin. Er trägt jetzt eine
  Linie unter sich, var(--line-strong) in --sec-accent, und wird damit zum
  Kopf der Station: Datum, Trennlinie, dann Sache und Beschreibung. Das ist
  dieselbe Rolle, die --accent laut tokens.css hat (Linien und Nummern),
  und dieselbe Bauart wie die Kopflinie einer Tabelle. Ohne Termineintrag
  entfällt die Linie mit ihm, weil sie an seinem Element hängt: eine
  Trennlinie ohne etwas darüber trennt nichts.

  Gemessene Farben auf der Karte, weil die Karte eine ANDERE Fläche ist als
  die Sektion und die bisherigen Werte gegen die Sektionsfläche gerechnet
  waren: --sec-accent gegen --sec-card-bg trägt 11,52:1 auf der abgesenkten
  Sektion (Karte weiss), 10,58:1 auf der hellen (Karte hellgrau) und
  4,53:1 auf der invertierten (aufgehellte Fassung rgb(123,148,162) gegen
  die angehobene Ebene rgb(39,42,46)). Der invertierte Fall ist der engste
  Wert dieser Option und hält die Textschwelle 4,5:1 für den kleinen Termin
  gerade; die Ziffer liegt bei --fs-2xl im Bereich grosser Schrift, für die
  3:1 gilt, und die Linie ist mit derselben Zahl weit über der 3:1 für
  Linien. Die Schrift der Station bleibt --sec-ink und trägt auf der
  invertierten Karte 14,41:1.
*/
.ke-process-timeline__steps--card .ke-process-timeline__step {
  padding: var(--s-6);
  border-radius: var(--radius-lg);
  background: var(--sec-card-bg);

  /* Stufe 1, dieselbe wie an jeder anderen Karte des Themes. Der Schatten
     steht hier allein und darf die Theme-Stufe deshalb direkt lesen: in
     einer Liste mehrerer Schatten wäre dasselbe none bei abgeschalteten
     Schatten ein Syntaxfehler, der die ganze Deklaration verwirft. */
  box-shadow: var(--shadow-1);
}

/* Die deckende Fläche der Markierung muss hier weg, und zwar nicht nur der
   Optik wegen: sie ist die Fläche der SEKTION, und auf der Karte wäre sie
   ein sichtbares Rechteck in der falschen Farbe hinter der Ziffer (auf der
   abgesenkten Sektion Hellgrau auf Weiss). Ihre Aufgabe, die Achse dort
   abzudecken, wo diese sie kreuzt, hat sie in dieser Option nicht mehr: die
   Achse läuft nur noch in den Fugen zwischen den Karten. */
.ke-process-timeline__steps--card .ke-process-timeline__marker {
  background: transparent;
}

/* Der Körper füllt die Karte, statt seiner Textbreite zu folgen. Beides ist
   nötig und zwar getrennt, weil die Achsenlage die Achsen des Flex-Kastens
   tauscht: senkrecht liegt die Breite auf der Hauptachse (flex), waagerecht
   auf der Querachse (align-self). align-self statt align-items am Elternteil
   ist zugleich die Zeile, die sich um keine Spezifität streiten muss, und
   das ist hier der Punkt: die Umschaltung ab vier Stationen setzt
   align-items am Körper selbst neu, und eine Kopflinie, die je nach
   Stationszahl über die Karte oder nur unter das Datum liefe, wäre ein
   Zufallsbefund. */
.ke-process-timeline__steps--card .ke-process-timeline__body {
  flex: 1;
  align-self: stretch;
}

.ke-process-timeline__steps--card .ke-process-timeline__termin {
  align-self: stretch;
  padding-block-end: var(--s-2);
  border-block-end: var(--line-strong) solid var(--sec-accent);
}

.ke-process-timeline__steps--card .ke-process-timeline__title {
  font-size: var(--fs-xl);
}

/*
  Die Achse zwischen zwei Karten. Sie füllt genau die Fuge: von der
  Unterkante der eigenen Karte bis zur Oberkante der nächsten.

  Das ist NICHT der Krümel-je-Lücke-Defekt, den dieses Modul hinter sich
  hat, obwohl die Schreibweise ihm gleicht. Der Unterschied ist der Anker.
  Damals hing das Stück an der MARKIERUNG, deren Unterkante mit der Fuge
  nichts zu tun hat: die Markierung ist nur so hoch wie ihre Ziffer, der
  Textkörper daneben trägt Termin, Titel und Absatz, und was blieb, war ein
  Stummel mit gemessen 59 Pixeln Nichts dahinter. Hier hängt das Stück am
  SCHRITT, und dessen Unterkante IST der Anfang der Fuge, weil der Schritt
  das Flex-Element ist, zwischen dem und dem nächsten der gap steht. Die
  Länge var(--s-8) ist deshalb keine Schätzung, sondern dieselbe Grösse, die
  die Schrittfolge oben als gap setzt.

  Kein Zuschlag auf die 100%, anders als bei der Tafel in ke-method-flow:
  inset-block-start löst am Padding-Kasten auf, und der ist hier deckungs-
  gleich mit dem Rahmenkasten, weil die Karte keinen Rahmen trägt. Bekommt
  sie später einen, gehört var(--line-strong) hier addiert, sonst legt das
  Stück einen Fleck in der Linienfarbe auf die Kartenkante.

  Das :has() der Grundform bleibt stehen: ohne Nummerierung gibt es keine
  Markierung, keine Knoten und deshalb auch hier keine Achse. Die Karten
  tragen dann allein, was sie ordnet, nämlich Termin und Kopflinie.
*/
.ke-process-timeline__steps--card:has(.ke-process-timeline__marker)
  .ke-process-timeline__step:not(:last-child)::before {
  inset-block: 100% auto;
  inset-inline-start: calc(var(--s-6) + var(--s-12) / 2 - var(--line-strong) / 2);
  height: var(--s-8);
}

@media (min-width: 992px) {
  /* Gleich hohe Karten in der waagerechten Lage. Die Grundform lässt die
     Schritte oben ausgerichtet unterschiedlich hoch enden, was ohne eigene
     Fläche niemand sieht; mit Fläche sind drei verschieden hohe Karten
     nebeneinander ein Befund. */
  .ke-process-timeline__steps--horizontal.ke-process-timeline__steps--card {
    align-items: stretch;
  }

  /*
    Die durchgehende Containerachse der waagerechten Lage liegt auf der Mitte
    der Markierung, und die sitzt in dieser Option um das Polster der Karte
    tiefer. Ohne diese Zeile liefe die Achse quer über die Oberkante der
    Karten statt über ihre Ziffern.

    Ausdehnung und Sichtbarkeit bleiben, wo sie stehen: die beiden
    :has()-Regeln oben setzen inset-inline und display je Stationszahl, hier
    ändert sich nur die Höhenlage. Die Karten decken die Achse ab, wo sie sie
    kreuzt, denn sie tragen eine deckende Fläche und werden nach dem
    Pseudoelement des Containers gezeichnet, dieselbe Mechanik, mit der
    vorher die Markierung sie abdeckte.
  */
  .ke-process-timeline__steps--horizontal.ke-process-timeline__steps--card:has(
      .ke-process-timeline__marker
    )::before {
    inset-block-start: calc(var(--s-6) + var(--s-12) / 2 - var(--line-strong) / 2);
  }
}

/* Schritte mit Medium: derselbe Split und derselbe gezeichnete Platzhalter
   wie bei ke-method-flow, keine dritte Formensprache fuer denselben Fall. */
.ke-process-timeline__media {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);

  /* Stufe 2, die Tafel: ein Bild ist eine eigene Flaeche auf der Sektion,
     und eine Flaeche ohne Schatten neben einer mit Schatten liest sich als
     Fehler. Der Schatten steht hier allein und darf deshalb die Theme-Stufe
     direkt lesen, siehe .ke-hero__bullet: in einer Liste mehrerer Schatten
     waere dasselbe none bei abgeschalteten Schatten ein Syntaxfehler, der
     die ganze Deklaration verwirft. Der gezeichnete Platzhalter daneben
     bekommt bewusst keinen: er hat keine eigene Fuellung, ein Schatten
     haette dort nichts, von dem er faellt. */
  box-shadow: var(--shadow-2);
}

.ke-process-timeline__media-placeholder {
  aspect-ratio: 4 / 3;
  border: 1px solid var(--sec-accent);
  border-radius: var(--radius-lg);
  background-image:
    linear-gradient(
      to top right,
      transparent calc(50% - 1px),
      var(--sec-accent) calc(50% - 1px),
      var(--sec-accent) calc(50% + 1px),
      transparent calc(50% + 1px)
    ),
    linear-gradient(
      to top left,
      transparent calc(50% - 1px),
      var(--sec-accent) calc(50% - 1px),
      var(--sec-accent) calc(50% + 1px),
      transparent calc(50% + 1px)
    );
}

/*
  Der Pfeil, der an der senkrechten Achse mitscrollt.

  Die Schiene liegt auf derselben Achse wie die Verbindungslinie der
  Schritte: inset-inline-start rechnet mit derselben Formel
  (halbe Markierungsbreite minus halbe Linienstaerke), damit der Pfeil auf
  der Linie laeuft und nicht daneben.

  Die Bewegung kommt aus animation-timeline: view(). Das ist eine Animation,
  deren Fortschritt an der Scrollposition haengt und die der Browser selbst
  berechnet: kein Scroll-Listener, kein requestAnimationFrame, keine Kosten
  in der Messung.

  animation-range: cover 20% cover 80% spannt den Weg ueber die mittleren
  sechzig Prozent der Zeit, in der die Sektion das Bild beruehrt. Mit
  "entry 25% exit 75%" (der ersten Fassung) bewegte sich der Pfeil erst im
  letzten Drittel: bei einer Sektion, die hoeher ist als das Fenster,
  endet "entry" erst, wenn sie ganz drin ist, und das ist bei dieser
  Sektion spaet. Am gerenderten Dokument gemessen, bei vier Scrollstaenden.

  OHNE UNTERSTUETZUNG IST ER NICHT SICHTBAR. Das ist Absicht: ein Pfeil, der
  sich nicht bewegt, waere ein Strich mitten in der Achse und damit ein
  Defekt. Die Achse zeigt die Reihenfolge ohnehin, der Pfeil betont sie nur.
  animation-timeline koennen heute Chrome und Edge ab 115 und Safari; in
  Firefox steckt es hinter einem Schalter.
*/
.ke-process-timeline__rail {
  display: none;
}

@supports (animation-timeline: view()) {
  /* Der benannte Bezug fuer die Bewegung des Pfeils, siehe unten. */
  .ke-process-timeline__steps--vertical {
    view-timeline-name: --ke-ablauf;
  }

  /*
    Die Spur liegt NEBEN den Stationen, nicht auf ihrer Achse.

    Bis zum 11. September 2026 lief der Pfeil als 16 Pixel grosses Dreieck
    auf derselben Linie, die die Karten verbindet. Damit war er zweierlei
    zugleich: Teil der Verbindung und eigener Zeiger, und als Zeiger war er
    zu klein, um aufzufallen. Der Befund dazu: der Pfeil soll viel groesser
    sein und getrennt von den Boxen links herunterfliegen.

    Die Schrittfolge oeffnet dafuer links eine Spur, die Karten ruecken um
    genau diese Breite nach rechts. Erst ab 768 Pixeln: darunter ist die
    Spalte zu schmal, um 80 Pixel davon abzugeben, und der Pfeil entfaellt
    dort ohnehin (siehe unten).
  */
  @media (min-width: 768px) {
    .ke-process-timeline__steps--vertical {
      padding-inline-start: var(--s-24);
    }
  }

  .ke-process-timeline__steps--vertical .ke-process-timeline__rail {
    position: absolute;
    z-index: 1;
    inset-block: 0;

    /* Die Mitte der Spur. Der Kopf zentriert sich darauf selbst. */
    inset-inline-start: calc(var(--s-24) / 2);
    display: none;

    /* Vier statt zwei Pixel: unter einem Kopf von 64 Pixeln traegt eine
       Haarlinie nichts. */
    width: var(--s-1);
    pointer-events: none;
  }

  /*
    Die Spur, die der Kopf hinter sich herzieht.

    Sie haengt an derselben Zeitachse und derselben Spanne wie er, deshalb
    endet sie immer genau dort, wo er steht. Oben laeuft sie ueber die
    groesste Stufe der Abstandsskala aus (128 Pixel): eine Linie, die am Rand hart anfaengt, ist ein Strich, eine
    auslaufende ist eine Bewegung.
  */
  .ke-process-timeline__rail::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-start: 0;
    height: 0;
    background: linear-gradient(
      to bottom,
      transparent 0,
      var(--sec-accent) var(--s-32)
    );
    animation: ke-process-timeline-spur linear both;
    animation-timeline: --ke-ablauf;
    animation-range: cover 20% cover 80%;
  }

  @keyframes ke-process-timeline-spur {
    from {
      height: 0;
    }

    to {
      height: 100%;
    }
  }

  @media (min-width: 768px) {
    .ke-process-timeline__steps--vertical .ke-process-timeline__rail {
      display: block;
    }
  }

  /*
    Der Kopf. Ein gefuelltes Dreieck aus einem clip-path und keine
    Rahmenkonstruktion: ein Dreieck aus border ist eine Rechnung mit
    Nullbreiten, die niemand liest, und es kann keine Farbe aus einem Token
    erben.

    translate zentriert ihn auf der Linie und zieht ihn um die halbe eigene
    Hoehe nach oben, damit die Spitze und nicht die Oberkante auf der
    Scrollposition sitzt.
  */
  .ke-process-timeline__rail-head {
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 50%;

    /* 64 statt 16 Pixel. In der eigenen Spur steht dem Pfeil die Groesse zu:
       er ist dort kein Punkt auf einer Linie mehr, sondern das einzige
       Element, und ein Zeiger, den man suchen muss, zeigt nichts. */
    width: var(--s-16);
    height: var(--s-16);
    translate: -50% -50%;
    background: var(--sec-accent);
    clip-path: polygon(50% 100%, 0 0, 100% 0);
    animation: ke-process-timeline-rail linear both;

    /*
      Die Zeitachse ist die SCHRITTFOLGE und nicht der Pfeil selbst.

      "animation-timeline: view()" ohne Namen nimmt das animierte Element
      als Bezug, und das ist hier ein Dreieck von 16 Pixeln: dessen eigener
      Sichtbarkeitsverlauf ist beim Scrollen fast binaer, und genau so sah
      es aus. Am gerenderten Dokument an neun Scrollstaenden gemessen: der
      Pfeil stand bis 0,4 am Anfang und ab 0,5 am Ende, dazwischen sprang
      er.

      Mit view-timeline-name an der Schrittfolge und dem Namen hier laeuft
      er ueber deren Sichtbarkeit, also ueber die ganze Sektion.
    */
    animation-timeline: --ke-ablauf;
    animation-range: cover 20% cover 80%;
  }

  @keyframes ke-process-timeline-rail {
    from {
      inset-block-start: 0;
    }

    to {
      inset-block-start: 100%;
    }
  }

  /* Schmuck, und die Reihenfolge steht in den Nummern. */
  @media (prefers-reduced-motion: reduce) {
    .ke-process-timeline__steps--vertical .ke-process-timeline__rail {
      display: none;
    }
  }
}
