/* ============================================================
   code dimension — Inhaltsbahnen
   ============================================================
   Gemeinsame Regeln der Inhaltsbahnen. Je Inhaltselement liegt
   eine eigene Datei unter bahnen/ — so bleibt beim Bauen getrennt,
   was getrennt gehoert, und zwei Leute kommen sich nicht in
   derselben Datei ins Gehege.

   SEIT 04.09.2026 STEHEN DIESE DATEIEN EINZELN IM LAYOUT und nicht
   mehr als @import hier. Warum, steht dort. Wer eine neue Bahn
   anlegt, traegt sie in Layouts/Pages/Default.fluid.html ein —
   VOR dieser Datei, damit die Kaskade bleibt.

   Zur Reihenfolge: Die Bahnen-Dateien stehen im Layout VOR dieser
   Datei, ihre Regeln kommen also vor den eigenen Regeln hier und
   nach layout.css und komponenten.css. Genau so war es mit @import
   auch, und genau so ist es gewollt — die Bahnen bauen auf den
   Bauteilen auf.

   Was von hier aus NICHT geht: eine spaeter geladene Datei
   uebertrumpfen. Wer etwas ueberschreiben will, das in wacon.css
   steht, muss es dort tun — wacon.css laedt danach.
   ============================================================ */

/* --- Kopf und Menue ---------------------------------------
   Keine Inhaltsbahn, aber dieselbe Bauart: EIN Schalter, viele
   Fassungen — wie bahnen/cd_kundenmenue.css. Steht hier und nicht
   in layout.css, weil die Fassungen auch an .cd-knopf ruehren und
   komponenten.css spaeter laedt als layout.css. */

/* --- Seitenkopf und Handlungsband ------------------------- */

/* --- Karten und Logos ------------------------------------- */

/* --- Abfolgen --------------------------------------------- */

/* --- Bahnen und Preise ------------------------------------ */

/* --- Referenzen und Stimmen ------------------------------- */

/* --- Fragen und Beitraege --------------------------------- */

/* --- Reiter ueber benachbarten Bahnen ---------------------
   Steht VOR der Erklaergrafik: Er schaltet deren Bahnen, setzt
   aber keine ihrer Regeln ausser Kraft. */

/* --- Erklaergrafik ---------------------------------------- */

/* --- Zuletzt: Kartenraster als Schiebespur am Handy -------
   Steht bewusst als letzter Import. Er nimmt Rasterregeln aus
   den Bahn-Dateien darueber zurueck; bei gleicher Staerke
   entscheidet die Reihenfolge. */

/* --- Gegenueberstellungen --------------------------------- */

/* --- Formular und Fallstudie ------------------------------ */

/* ============================================================
   Gemeinsamer Rhythmus aller Bahnen
   ============================================================
   Jedes Inhaltselement ist eine Bahn. Der Abstand entsteht hier
   einmal und nicht in sechzehn Dateien einzeln.
   ============================================================ */

/* Die Luft selbst steht weiter unten unter "Darstellung je
   Bildschirmbreite" — dort, wo auch die von der Redaktion
   gewaehlten Stufen einlaufen. Zwei Stellen fuer denselben Wert
   waeren eine zu viel. */

/* Zwei Bahnen mit gleichem Grund direkt untereinander sollen wie
   EINE Flaeche wirken — sonst entsteht eine doppelte Luftschicht
   mitten im Farbblock.

   Das negative Aussenmass ist KEINE Feinjustierung, sondern
   behebt eine sichtbare Naht: Die Luft der Bahnen kommt aus
   clamp() und faellt auf Bruchteile von Pixeln (gemessen
   122,606 px). Die Bahn endet damit mitten in einer Bildzeile,
   die naechste beginnt in der uebernaechsten — dazwischen bleibt
   GENAU EINE Zeile Seitengrund stehen. Auf Weiss ergibt das
   einen hellen Strich quer durch den dunklen Block. Gemessen im
   Bildschirmfoto: Zeile 381 rgb(255,255,255), darueber und
   darunter rgb(22,39,47).

   Ein Pixel Ueberlappung deckt die Naht zu. Da beide Flaechen
   dieselbe Farbe tragen, ist die Ueberlappung selbst unsichtbar. */
/* Das Aussenmass gilt fuer ALLE Nachbarn mit gleicher Grundklasse
   — auch fuer die eine Ausnahme unten: Ein Pixel Ueberlappung ist
   bei zwei Toenen genauso unsichtbar und deckt die Naht weiter zu. */
.cd-bahn.cd-auf-dunkel + .cd-bahn.cd-auf-dunkel,
.cd-bahn.cd-auf-rot + .cd-bahn.cd-auf-rot {
  margin-block-start: -1px;
}

/* Die Luft dagegen wird nur dort genommen, wo wirklich EINE
   Flaeche entsteht — siehe die Ausnahme darunter. */
.cd-bahn.cd-auf-dunkel + .cd-bahn.cd-auf-dunkel:not(.cd-stimmen),
.cd-bahn.cd-auf-rot + .cd-bahn.cd-auf-rot {
  padding-block-start: 0;
}

/* AUSNAHME: Bahnen die ihren Grund SELBST malen.
   Die Regel darueber setzt voraus was ihre Begruendung sagt —
   gleicher Grund. Das gilt fuer alle Bahnen, die ihre Farbe aus
   der Klasse .cd-auf-dunkel beziehen. Genau eine tut das nicht:
   .cd-stimmen setzt --cd-st-grund und malt --cd-tinte (#0D1A21),
   waehrend die Klasse --cd-dunkel (#16272F) bringt. Zwischen den
   beiden liegt dann keine unsichtbare Naht sondern eine sichtbare
   Tonkante — und ihr wird die Luft genommen, die sie am
   noetigsten braucht.

   Gemessen auf /leistungen/webseite-erstellen-lassen, wo die
   Zitate-Bahn direkt unter einer dunklen Schritte-Bahn steht:
   56 px zwischen Kante und Zitat, 156 px unter der Person.

   Das negative Aussenmass BLEIBT: Ein Pixel Ueberlappung ist auch
   bei zwei Toenen unsichtbar und deckt die Bruchteil-Pixel-Naht
   weiterhin zu. Nur die Luft kommt zurueck.

   Wenn spaeter eine weitere Bahn ihren Grund selbst setzt, gehoert
   sie in das :not() der Regel darueber.

   WARUM IM SELEKTOR und nicht als Rueckgabe eines Wertes: Die Luft
   der Bahn kommt aus einem clamp() an .cd-bahn. Wer sie hier
   zurueckholen wollte, muesste dieses clamp() abschreiben — und
   haette denselben Wert an zwei Stellen. `revert-layer` hilft
   nicht: Ohne Kaskadenschichten faellt es bis zum Browser durch
   und landet bei 0. */

/* Die erste Bahn direkt unter dem Kopfbereich braucht oben keine
   zusaetzliche Luft — der Seitenkopf bringt sie mit.
   AUSNAHME Seitenkopf: Der Hero ist selbst die erste Bahn und
   braucht seine Luft, sonst klebt die Schlagzeile an der
   Navigation. Er setzt sie in bahnen/cd_hero.css selbst. */
.cd-inhalt > .cd-bahn:first-child:not(.cd-hero) {
  padding-block-start: 0;
}

.cd-bahn__inhalt {
  inline-size: 100%;
  max-inline-size: var(--cd-inhalt);
  margin-inline: auto;
  padding-inline: var(--cd-rinne);
}

/* Sprungziel einer Bahn. Der Versatz haelt die feste Kopfleiste
   vom angesprungenen Titel fern (WCAG 2.4.11). */
.cd-bahn[id] {
  scroll-margin-block-start: calc(var(--cd-kopf-gesamt) + 16px);
}

/* ============================================================
   Darstellung je Bildschirmbreite
   ============================================================
   Drei Geraeteklassen, dieselben Schwellen wie im uebrigen
   Auftritt: bis 600 px Handy, bis 1100 px Tablet, darueber
   Rechner.

   Die Werte kommen als eigene CSS-Eigenschaften und als
   Datenattribute am Element (ViewHelper cd:bahnstil). Gesetzt
   wird nur, was die Redaktion wirklich gewaehlt hat — der
   Rueckfall in var() traegt die Vorgabe des Entwurfs.

   Klassen waeren hier der falsche Weg: drei Geraeteklassen mal
   vier Werte mal fuenf Einstellungen sind sechzig Namen, die
   niemand mehr auseinanderhaelt.
   ============================================================ */

/* --- Luft um die Bahn ---------------------------------------
   Zwei Werte statt einem: unten steht der Faktor aus tokens.css.
   Er gilt auch fuer die von der Redaktion gewaehlten Stufen — und
   bei "keine" bleibt null mal 1,05 erwartungsgemaess null.

   Die beiden Regeln weiter oben (erste Bahn unter dem Kopf, zwei
   Bahnen auf demselben Grund) setzen nur padding-block-START und
   wiegen mehr als eine Klasse. Sie ueberstehen diese Angabe
   deshalb unveraendert. */
.cd-bahn {
  padding-block: var(--cd-luft-m, var(--cd-bahn))
                 calc(var(--cd-luft-m, var(--cd-bahn)) * var(--cd-bahn-fuss));
}

@media (min-width: 601px) {
  .cd-bahn {
    padding-block: var(--cd-luft-t, var(--cd-luft-m, var(--cd-bahn)))
                   calc(var(--cd-luft-t, var(--cd-luft-m, var(--cd-bahn))) * var(--cd-bahn-fuss));
  }
}

@media (min-width: 1101px) {
  .cd-bahn {
    padding-block: var(--cd-luft-d, var(--cd-bahn))
                   calc(var(--cd-luft-d, var(--cd-bahn)) * var(--cd-bahn-fuss));
  }
}

/* --- Aufbau des Kopfbereichs --------------------------------
   Die Redaktion waehlt einen Anteil (60 heisst sechzig zu vierzig,
   100 heisst untereinander); der ViewHelper macht daraus die
   fertige Spaltenangabe. Deshalb hier eine Regel je Geraeteklasse
   statt einer je Wert — und Zwischenwerte gehen ohne neue Regel.

   Der Rueckfall traegt die Vorgabe des Entwurfs. Auf dem Tablet
   erbt der Wert vom Handy, wenn dort etwas gesetzt ist und hier
   nicht: sonst spraenge eine Bahn zwischen zwei Einstellungen auf
   die Vorgabe zurueck. */
/* ACHTUNG, hier lag ein Fehler: Der Rueckfall der Grundregel war
   zweispaltig (1fr + 26rem). Weil diese Datei NACH komponenten.css
   laedt und dieselbe Staerke hat, hat sie deren Mobilregel
   (komponenten.css:143 — "unter 900 px untereinander") stillschweigend
   ausgehebelt. Folge auf jedem Bahnkopf am Handy: fuer die
   Ueberschrift blieben rund 150 px, "Auf diese Arbeiten sind wir
   stolz." stand sechszeilig mit einem Wort je Zeile, der Kicker
   vierzeilig, und im Blog-Teaser lag der Knopf ueber der Zeile.
   Der Rueckfall traegt jetzt je Geraeteklasse den Wert, der dort
   gemeint ist: einspaltig bis 900 px, darueber zweispaltig. Eine
   ausdrueckliche Aufteilung aus dem Feld (--cd-kopfsp-*) sticht
   weiterhin. */
.cd-kopfzeile {
  grid-template-columns: var(--cd-kopfsp-m, minmax(0, 1fr));
}

@media (min-width: 601px) {
  .cd-kopfzeile {
    grid-template-columns: var(--cd-kopfsp-t, var(--cd-kopfsp-m, minmax(0, 1fr)));
  }
}

/* Erst ab hier ist Platz fuer zwei Spalten. 900 px ist die
   Schwelle aus komponenten.css:143 und bleibt es. */
@media (min-width: 901px) {
  .cd-kopfzeile {
    grid-template-columns: var(--cd-kopfsp-t, minmax(0, 1fr) minmax(0, 26rem));
  }
}

@media (min-width: 1101px) {
  .cd-kopfzeile {
    grid-template-columns: var(--cd-kopfsp-d, minmax(0, 1fr) minmax(0, 26rem));
  }
}

/* ============================================================
   Auftritt beim Blättern
   ============================================================
   Eine Bahn tritt auf, sobald sie ins Bild kommt. Welche Fassung
   gilt, steht am body (Site-Einstellung) und kann je Bahn
   überschrieben werden — deshalb zuerst die Regel für den body und
   danach die für das Element.

   Das Skript setzt cd-ein an jede Bahn, sobald sie sichtbar wird.
   OHNE Skript bleibt cd-ein aus — deshalb steht der Endzustand in
   der Grundregel und der Startzustand nur dort, wo das Skript
   angemeldet hat (html.cd-bewegung). Sonst bliebe die halbe Seite
   unsichtbar, wenn ein Skript nicht lädt.
   ============================================================ */

html.cd-bewegung .cd-bahn {
  --cd-weg: 28px;
  --cd-dauer: .7s;
  opacity: 0;
  transform: none;
  transition: opacity var(--cd-dauer) var(--cd-kurve),
              transform var(--cd-dauer) var(--cd-kurve);
  will-change: opacity, transform;
}

html.cd-bewegung body[data-bewegung="deutlich"] .cd-bahn {
  --cd-weg: 56px;
  --cd-dauer: .9s;
}

/* Startzustand je Fassung. Der Wert am Element sticht den am body —
   deshalb steht er weiter unten und mit einer Klasse mehr. */
html.cd-bewegung body[data-auftritt="hoch"]   .cd-bahn { transform: translateY(var(--cd-weg)); }
html.cd-bewegung body[data-auftritt="links"]  .cd-bahn { transform: translateX(calc(var(--cd-weg) * -1)); }
html.cd-bewegung body[data-auftritt="rechts"] .cd-bahn { transform: translateX(var(--cd-weg)); }
html.cd-bewegung body[data-auftritt="zoom"]   .cd-bahn { transform: scale(.97); }
html.cd-bewegung body[data-auftritt="keine"]  .cd-bahn { opacity: 1; transition: none; }

html.cd-bewegung .cd-bahn[data-auftritt="blende"] { transform: none; }
html.cd-bewegung .cd-bahn[data-auftritt="hoch"]   { transform: translateY(var(--cd-weg)); }
html.cd-bewegung .cd-bahn[data-auftritt="links"]  { transform: translateX(calc(var(--cd-weg) * -1)); }
html.cd-bewegung .cd-bahn[data-auftritt="rechts"] { transform: translateX(var(--cd-weg)); }
html.cd-bewegung .cd-bahn[data-auftritt="zoom"]   { transform: scale(.97); }
html.cd-bewegung .cd-bahn[data-auftritt="keine"]  { opacity: 1; transform: none; transition: none; }

/* Angekommen. */
html.cd-bewegung .cd-bahn.cd-ein {
  opacity: 1;
  transform: none;
}

/* Karten nacheinander. Der Versatz steckt in der Verzögerung und
   nicht in einer eigenen Bewegung — acht Felder, danach laufen sie
   zusammen, weil sonst die letzte Karte einer langen Reihe ewig
   braucht. */
html.cd-bewegung .cd-bahn[data-staffel="1"] :is(.cd-karten__feld, .cd-referenzen__folie, .cd-schritte__punkt) {
  opacity: 0;
  transform: translateY(calc(var(--cd-weg) * .5));
  transition: opacity var(--cd-dauer) var(--cd-kurve),
              transform var(--cd-dauer) var(--cd-kurve);
}
html.cd-bewegung .cd-bahn[data-staffel="1"].cd-ein :is(.cd-karten__feld, .cd-referenzen__folie, .cd-schritte__punkt) {
  opacity: 1;
  transform: none;
}
html.cd-bewegung .cd-bahn[data-staffel="1"].cd-ein :is(.cd-karten__feld, .cd-referenzen__folie, .cd-schritte__punkt):nth-child(2) { transition-delay: .08s; }
html.cd-bewegung .cd-bahn[data-staffel="1"].cd-ein :is(.cd-karten__feld, .cd-referenzen__folie, .cd-schritte__punkt):nth-child(3) { transition-delay: .16s; }
html.cd-bewegung .cd-bahn[data-staffel="1"].cd-ein :is(.cd-karten__feld, .cd-referenzen__folie, .cd-schritte__punkt):nth-child(4) { transition-delay: .24s; }
html.cd-bewegung .cd-bahn[data-staffel="1"].cd-ein :is(.cd-karten__feld, .cd-referenzen__folie, .cd-schritte__punkt):nth-child(5) { transition-delay: .32s; }
html.cd-bewegung .cd-bahn[data-staffel="1"].cd-ein :is(.cd-karten__feld, .cd-referenzen__folie, .cd-schritte__punkt):nth-child(n+6) { transition-delay: .4s; }

/* Wer Bewegung abbestellt hat, bekommt keine — und zwar unabhängig
   davon, was in den Einstellungen steht (WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
  html.cd-bewegung .cd-bahn,
  html.cd-bewegung .cd-bahn[data-staffel="1"] :is(.cd-karten__feld, .cd-referenzen__folie, .cd-schritte__punkt) {
    opacity: 1;
    transform: none;
    transition: none;
  }
}


/* ============================================================
   Breite, Lage und Einzug einer einzelnen Bahn
   ============================================================
   Jede Bahn nimmt von sich aus dieselben 1280 px. Uebereinander
   ergibt das eine sehr gerade Kante ueber die ganze Seite —
   sauber, aber ohne Rhythmus. Diese drei Stellschrauben brechen
   sie auf, je Element gewaehlt und ohne eigene Vorlage.

   ALLES ERST AB 1101 PX. Darunter ist die Breite die des
   Bildschirms, und ein Einzug waere verlorener Platz.

   Der Block steht am ENDE der Datei: Er ueberschreibt
   .cd-bahn__inhalt von weiter oben (Zeile 89). Bei gleicher
   Spezifitaet gewinnt die spaetere Regel.
   ============================================================ */

@media (min-width: 1101px) {

  /* --- 1. Breite ------------------------------------------- */
  /* Als Faktor auf --cd-inhalt und nicht als feste Pixelzahl:
     Aendert sich die Inhaltsbreite einmal, wandern alle drei
     Stufen mit. */
  .cd-bahn[data-bahnbreite="schmal"] > .cd-bahn__inhalt { max-inline-size: calc(var(--cd-inhalt) * .74); }
  .cd-bahn[data-bahnbreite="eng"]    > .cd-bahn__inhalt { max-inline-size: calc(var(--cd-inhalt) * .56); }

  /* "breit" geht ueber die Inhaltsbreite hinaus, aber nie ueber
     den Bildschirm: min() deckelt bei der vollen Breite minus
     zweimal Rinne. Ohne den Deckel liefe die Bahn bei 1200 px
     Fenster ueber den Rand (WCAG 1.4.10). */
  .cd-bahn[data-bahnbreite="breit"] > .cd-bahn__inhalt {
    max-inline-size: min(calc(var(--cd-inhalt) * 1.14), calc(100vw - var(--cd-rinne) * 2));
  }

  /* --- 2. Lage --------------------------------------------- */
  /* Eine schmalere Bahn steht von selbst mittig. Buendig zur
     uebrigen Seite steht sie erst, wenn ihr linker Rand so gross
     ist wie der einer vollbreiten Bahn — genau das rechnet
     max(): entweder die Rinne oder die halbe Differenz zur
     Inhaltsbreite, je nachdem was groesser ist.

     Ohne max() klebte die Bahn auf einem schmalen Rechner am
     Fensterrand. */
  .cd-bahn[data-bahnlage="links"] > .cd-bahn__inhalt {
    margin-inline: max(var(--cd-rinne), calc((100% - var(--cd-inhalt)) / 2)) auto;
  }
  .cd-bahn[data-bahnlage="rechts"] > .cd-bahn__inhalt {
    margin-inline: auto max(var(--cd-rinne), calc((100% - var(--cd-inhalt)) / 2));
  }

  /* --- 3. Einzug der Ueberschrift --------------------------- */
  /* Nur der Kopfbereich rueckt ein, nicht die Bahn. Das Raster
     darunter bleibt stehen — genau daraus entsteht der Versatz,
     der die Kante bricht.

     Die Liste nennt die Kopfbereiche AUSDRUECKLICH und faengt sie
     nicht ueber [class*="__kopf"]: Das traefe auch __kopfknopf,
     __kopfbild und __kopfrechts — und ruecke damit den Knopf ein,
     der rechts stehen soll.

     WER EINE BAHN ERGAENZT, ergaenzt hier ihren Kopfbereich. Ohne
     Eintrag tut das Feld an dieser Bahn nichts — sichtbar, aber
     wirkungslos. */
  .cd-bahn[data-kopfeinzug] :is(
    .cd-kopfzeile__text,
    .cd-aussagenband__kopftext,
    .cd-gegen__kopftext,
    .cd-kontakt__kopf,
    .cd-preise__kopf,
    .cd-stimmen__kopftext,
    .cd-tab__kopftext,
    .cd-referenzdetail__kopftext,
    .cd-faq__seite > .cd-faq__beitext,
    .cd-logoband__ueberschrift
  ) {
    padding-inline-start: var(--cd-kopf-einzug, 0px);
  }

  .cd-bahn[data-kopfeinzug="klein"]  { --cd-kopf-einzug: 8%; }
  .cd-bahn[data-kopfeinzug="mittel"] { --cd-kopf-einzug: 17%; }
  .cd-bahn[data-kopfeinzug="gross"]  { --cd-kopf-einzug: 26%; }

  /* Eine eingeruecke Ueberschrift bekommt eine Linie an den
     gewonnenen Rand. Ohne sie sieht der Einzug nach einem Fehler
     aus; mit ihr nach Absicht. Sie ist reine Zier und traegt
     deshalb kein eigenes Element, sondern ein Pseudoelement. */
  .cd-bahn[data-kopfeinzug]:not([data-kopfeinzug=""]) :is(
    .cd-kopfzeile__text,
    .cd-aussagenband__kopftext,
    .cd-gegen__kopftext,
    .cd-stimmen__kopftext,
    .cd-tab__kopftext
  ) {
    position: relative;
  }
  .cd-bahn[data-kopfeinzug]:not([data-kopfeinzug=""]) :is(
    .cd-kopfzeile__text,
    .cd-aussagenband__kopftext,
    .cd-gegen__kopftext,
    .cd-stimmen__kopftext,
    .cd-tab__kopftext
  )::before {
    content: "";
    position: absolute;
    inset-block: 6px;
    inset-inline-start: calc(var(--cd-kopf-einzug, 0px) - var(--cd-a6));
    inline-size: 2px;
    background: var(--cd-rot);
  }

  /* Auf dunklem und rotem Grund traegt das Rot nicht. */
  .cd-auf-dunkel[data-kopfeinzug]:not([data-kopfeinzug=""]) :is(.cd-kopfzeile__text, .cd-stimmen__kopftext)::before {
    background: var(--cd-rot-auf-dunkel);
  }
  .cd-auf-rot[data-kopfeinzug]:not([data-kopfeinzug=""]) :is(.cd-kopfzeile__text, .cd-stimmen__kopftext)::before {
    background: var(--cd-weiss);
  }
}


/* ============================================================
   Versatz der Kacheln zueinander   (cd_versatz)
   ============================================================
   Fuenf gleich hohe Kacheln in einer Reihe sind ruhig — und
   langweilig. Der Versatz bricht die Kante, ohne dass an den
   Kacheln selbst etwas anders waere.

   UEBER MARGIN UND NICHT UEBER TRANSFORM: Das Auftrittssystem
   legt den Kacheln beim Einblenden ein transform an (Zeile 251
   dieser Datei). Ein zweites transform hier wuerde es
   ueberschreiben — die Kacheln blieben beim Blaettern unsichtbar.
   Ein Aussenabstand vertraegt sich damit, und im Raster waechst
   die Zeile von selbst mit: es braucht keinen Ausgleich am Fuss.

   --cd-schritt traegt jede Schrittkachel bereits als eigene
   Eigenschaft (0, 1, 2 …) — daraus entsteht die Treppe ohne eine
   Regel je Kachel.
   ============================================================ */

@media (min-width: 1101px) {

  /* --- Das Raster oeffnet sich ----------------------------- */
  /* Die Kachelbauform der Schrittbahn zeichnet ihre Linien als
     2-px-Spalt ueber einer eingefaerbten Flaeche. Versetzt man
     die Kacheln, bleiben davon Reste zwischen den Feldern stehen.
     Deshalb faellt die Flaeche weg und jede Kachel bekommt ihre
     eigene Kante. */
  .cd-schritte--kacheln[data-versatz] .cd-schritte__liste,
  .cd-schritte--fragen[data-versatz] .cd-schritte__liste {
    gap: var(--cd-a5);
    background: none;
    border: 0;
    align-items: start;
  }
  .cd-schritte--kacheln[data-versatz] .cd-schritte__punkt,
  .cd-schritte--fragen[data-versatz] .cd-schritte__punkt {
    border: 1px solid var(--cd-schritt-linie);
    border-radius: var(--cd-r-karte);
  }

  /* Auch die uebrigen Kachelraster geben ihre gemeinsame Linie
     auf — sonst haengt eine versetzte Kachel schief im Gitter. */
  .cd-bahn[data-versatz] .cd-karten__raster,
  .cd-bahn[data-versatz] .cd-referenzen__raster,
  .cd-bahn[data-versatz] .cd-referenzen__karten,
  .cd-bahn[data-versatz] .cd-blog__raster {
    align-items: start;
  }

  /* --- Die drei Fassungen ---------------------------------- */
  /* wechselnd: jede zweite Kachel tiefer. Ruhig genug fuer eine
     Reihe mit vielen Feldern, weil die Bahn nur um EINEN Schritt
     hoeher wird. */
  .cd-bahn[data-versatz="wechsel"] :is(
    .cd-schritte__punkt,
    .cd-karten__feld,
    .cd-referenzen__kachel,
    .cd-referenzen__karte,
    .cd-blog__karte
  ):nth-child(even) {
    margin-block-start: 34px;
  }

  /* Treppe: jede Kachel eine Stufe tiefer als die vorige. Bei
     fuenf Kacheln sind das 88 px Gefaelle — sichtbar, aber noch
     kein Absturz. */
  .cd-schritte[data-versatz="treppe"] .cd-schritte__punkt {
    margin-block-start: calc(var(--cd-schritt, 0) * 22px);
  }

  /* Bogen: erst abwaerts, dann wieder herauf. Die Reihe bekommt
     eine Mitte, ohne dass die letzte Kachel tief unten haengt.
     Nur fuer die Schrittbahn: nur sie kennt ihre Kachelzahl. */
  /* EINHEITEN ERST GANZ ZUM SCHLUSS.
     Hier stand max(0px, <zahl ohne Einheit>) — das mischt Pixel
     und blosse Zahl, macht den ganzen calc-Ausdruck ungueltig,
     und der Abstand faellt still auf null. Die Reihe stand
     wieder schnurgerade da, ohne dass irgendwo etwas fehlte.

     Jetzt rechnet der Ausdruck bis zum Ende ohne Einheit und
     bekommt sie erst mit der Multiplikation. */
  .cd-schritte[data-versatz="bogen"] .cd-schritte__punkt {
    margin-block-start: calc(
      (
        var(--cd-schritt, 0)
        - 2 * max(0, var(--cd-schritt, 0) - (var(--cd-schritte-anzahl, 4) - 1) / 2)
      ) * 22px
    );
  }

  /* Ohne die Zahl der Kacheln kann der Bogen nicht rechnen —
     dann bleibt es bei der Treppe. Das ist der stille, aber
     harmlose Rueckfall. */
}

/* Untereinander gibt es nichts zu versetzen: Unter 1101 px stehen
   die Kacheln in einer oder zwei Spalten, und ein Aussenabstand
   waere dort nur eine Luecke ohne Grund. */
