/* ====================================================================
   ENNS – Engineering Systems
   Gestaltung „Zeichnungsblatt“: Der Browser ist das Blatt. Rahmen,
   Koordinatenlineal und Schriftfeld bilden eine technische Zeichnung
   nach; dunkle Flächen sind der „Anlage unter Spannung“ vorbehalten.

   Grundsätze:
   · Ein Beobachter treibt Lineal, Zonenmarken und Standortanzeige im
     Schalter gemeinsam – sie können nie auseinanderlaufen.
   · Jede Sektion trägt eine feste Zonenkoordinate (data-zone): Spalte =
     Themenkategorie, Zeile = Reihenfolge auf dem Blatt.
   · Bewegt werden ausschließlich transform, opacity und Farbe. Jede
     Animation hat einen ruhenden Endzustand und respektiert
     prefers-reduced-motion (Block am Dateiende).
   · --green-ink (#00ba80) für Akzente und Notation auf hellem Grund,
     --green (#00db9e) auf dunklen Flächen und in den Zeichen. Kontrast
     von --green-ink auf #f9f7f7 gemessen: 2,36:1 – unter der
     4,5:1-Schwelle, bewusst akzeptiert und deshalb nie für Fließtext
     eingesetzt; dafür steht --ink-soft.
   · Mobil (< 820px): Rahmen bleibt als dünne Linie, Lineal und
     Zonenmarken entfallen – kein Platz, kein erzwungenes Verkleinern.

   Keine Inline-Styles, keine Inline-Skripte: die Auslieferung erzwingt
   per Content-Security-Policy script-src/style-src 'self'.
   ==================================================================== */
:root{
  --blue:#151f35; --blue-900:#0f1727; --green:#00db9e; --green-ink:#00ba80;
  --grey:#c6c9d1; --white:#f9f7f7; --ink:#151f35; --ink-soft:#42506a;
  --rule:rgba(21,31,53,.22); --rule-strong:rgba(21,31,53,.45);
  --ease:cubic-bezier(.22,.61,.36,1);
  --font:'bahnschrift','Bahnschrift','DIN Alternate','Segoe UI',system-ui,Arial,sans-serif;
  --m:56px;            /* Randbreite des Blattrahmens, zugleich Kopfzeile */
  /* Ein Blatt hat ein Format – es zieht sich nicht endlos. Ohne diese
     Grenze blieben Logo, Schrift und Tabellenbreite auf normale
     Bildschirme abgestimmt, während der Rahmen auf einem breiten Monitor
     einfach weiterlief: alles wirkte plötzlich zu klein, die Tabelle
     brach um, obwohl sichtbar Platz da war. --edge wächst erst, wenn der
     Viewport --sheet-max überschreitet, und zentriert das Blatt dann
     symmetrisch – darunter bleibt es randlos wie bisher. */
  --sheet-max:1480px;
  --edge:0px;
  --top:14px;          /* Abstand Blattrand zur Viewport-Oberkante – gleich
                          groß wie unten (bottom:14px), das Blatt ist
                          symmetrisch gerahmt */
  --header-h:104px;    /* Höhe der Kopfzeile, als oberste Zeile INNERHALB
                          des Rahmens – keine eigene Chrome mehr darüber.
                          Logo/Schalter sind vertikal zentriert (align-items:
                          center), mehr Höhe heißt hier direkt mehr Luft
                          oben/unten um beide – alle Blatt-Offsets hängen
                          an dieser einen Variable und ziehen automatisch nach */

  /* ---- Inhaltsspalte -------------------------------------------------
     Der Rahmen läuft randlos mit dem Fenster mit, der Inhalt nicht: er
     hat eine Lesebreite und steht auf großen Schirmen mittig statt links
     zu kleben. Beide Polster nehmen den Überschuss je zur Hälfte auf und
     fallen auf schmalen Fenstern auf ihren Mindestwert zurück.
     --tick ist der Abstand von der Lineallinie zur Textspalte. Er wächst
     mit der Zentrierung mit – sonst würden die grünen Marken die Linie
     nicht mehr erreichen, an der sie ansetzen. */
  --content-max:1400px;
  --gutter:70px;       /* Mindestrinne zwischen Lineallinie und Text */
  --pad-l:max(calc(var(--edge) + var(--m) + var(--gutter)),
              calc((100vw - var(--content-max)) / 2));
  --pad-r:max(calc(var(--edge) + var(--gutter)),
              calc((100vw - var(--content-max)) / 2));
  --tick:calc(var(--pad-l) - var(--edge) - var(--m));
  /* Aufziehdauer der Zonenmarke. Sie muss mit der Strichlänge wachsen,
     sonst wirkt derselbe Weg auf breiten Schirmen gehetzt. Bewusst weit
     unterproportional: bei gleicher Geschwindigkeit bräuchte der Strich
     auf 2200px rund 2,6s und würde kriechen. Gestuft statt gerechnet –
     CSS kann aus einer Länge keine Zeit ableiten, und für reine Zier
     lohnt kein Messcode. Die Stufen stehen bei den Breiten, ab denen
     die Zentrierung den Strich spürbar verlängert. */
  --tick-dur:.55s;
  /* Zonenmarke: Höhe, Abstand zur Überschrift und beides zusammen.
     Der Summenwert ist der Vorlauf, den die Textspalte vor ihrer
     Überschrift hat – Bild- und Formularspalten daneben brauchen genau
     denselben, sonst beginnen sie höher als die Überschrift.
     In rem statt em, damit der Wert nicht von der geerbten Schriftgröße
     der jeweiligen Sektion abhängt (gemessen sind beide 16px). */
  --zone-h:1rem;
  --zone-gap:1.5rem;
  --zone-block:calc(var(--zone-h) + var(--zone-gap));
  /* Kastenbündig ist nicht optisch bündig: Über den Versalien einer
     .statement-Zeile steht totes Weiß. Gemessen bei 42,9px Schriftgrad –
     Oberlänge 50px, Versalhöhe nur 30,5px, dazu 2,1px halber Durchschuss:
     die Versalien beginnen 21,7px unter der Kastenoberkante, also fast
     eine halbe Versalhöhe. Ein Foto, dessen Kante dort kastenbündig
     ansetzt, startet sichtbar über der Überschrift.
     Der Betrag ist ein fester Anteil des Schriftgrads (21,7/42,9 = ,506),
     skaliert also mit dem clamp mit. Der Wert wiederholt dessen Formel,
     wie schon bei .two-col – CSS kann die Größe eines anderen Elements
     nicht abfragen. Bei Änderung von .statement hier mitziehen. */
  --statement-versalversatz:calc(.506 * clamp(1.8rem,4.4vw,3.4rem));
  /* Eine Skala statt achtzehn Einzelwerten. h1/h2/.statement bleiben
     außerhalb – die sind bewusst fluide (clamp) und gehören zu keiner
     Fließtext-Hierarchie. .about-facts .n ist eine Kennzahl, kein
     Fließtext, bleibt ebenfalls eigenständig. */
  --fs-micro:.72rem;   /* Bezugsnotation: Lineal, Zonen, Klemmen-IDs, Pos.-Nummern */
  --fs-sm:.85rem;      /* Nebentext: Spaltenköpfe, Bildunterschriften, Rechtstext */
  --fs-base:.95rem;    /* Fließtext: Bemerkungen, Fließtext im dunklen Feld, Formularantworten */
  --fs-body:1.05rem;   /* Betont: Lead-Absätze, Benennungen, Formularfelder, Menüpunkte */
  --fs-lg:1.15rem;     /* Hervorgehoben: Zitat-Vermerk, große Schriftfeld-Zelle */
  /* Dritte Überschriften-Ebene: Geltungsbereich, Modulname, Ebenen-Name
     der Systemarchitektur. Stand dreimal identisch im Stylesheet, jetzt
     an einer Stelle. Untergrenze 1.4rem statt 1.25rem: darunter rückte
     sie bei schmalen Fenstern bis auf 1,6px an die feste Tabellen-
     Benennung (1.15rem) heran – zwei Ebenen, die nicht mehr als zwei
     lesbar waren. Fluid wie h1/h2, deshalb außerhalb der --fs-Skala. */
  --fs-h3:clamp(1.4rem,1.8vw,1.6rem);
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{font-family:var(--font);background:var(--white);color:var(--ink);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased}
img,svg{display:block;max-width:100%}
/* Fehlten hier komplett – deshalb liefen Browser-Vorgaben (Punkte vor
   Listeneinträgen, Unterstrich unter Links) durch die eigene Gestaltung
   der Menüpunkte hindurch, obwohl css/style.css sie längst zurücksetzt. */
a{color:inherit;text-decoration:none}
ul,ol{list-style:none}
:focus-visible{outline:2px solid var(--green-ink);outline-offset:2px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---------- Website-Kopfzeile ---------------------------------------
   Fortsetzung des Blatts, keine eigenständige Chrome mehr darüber: die
   Kopfzeile ist die oberste Zeile INNERHALB des Rahmens, wie das
   Schriftfeld einer technischen Zeichnung. Derselbe Rahmen (.frame),
   dieselbe linke/rechte Kante (var(--edge)) umschließt Kopfzeile,
   Lineal und Inhalt als eine durchgehende Fläche. */
/* Schmaler Streifen zwischen Viewport-Oberkante und Kopfzeile (var(--top)
   =14px). Ohne eigene deckende Fläche schien dort scrollender Inhalt
   durch, weil nichts Fixiertes diesen Bereich abdeckte. */
.top-guard{position:fixed;top:0;left:0;right:0;height:var(--top);
  background:var(--white);z-index:55}
.bottom-guard{position:fixed;bottom:0;left:0;right:0;height:14px;
  background:var(--white);z-index:55}
/* Eigene obere/seitliche Linie in Rahmenstärke: der Rahmen selbst läge
   hier exakt unter der Kopfzeile und würde von ihrem Hintergrund
   überdeckt – ohne eigene Linie wäre die Rahmenkante an dieser Stelle
   unsichtbar. Keine Unterkante: die übernimmt das Kopfband direkt
   darunter (.head-band border-bottom), sonst läge eine doppelte Linie. */
.site-header{position:fixed;top:var(--top);left:var(--edge);right:var(--edge);
  height:var(--header-h);background:var(--white);z-index:60;
  border:1px solid var(--rule-strong);border-bottom:none;
  display:flex;align-items:center;justify-content:space-between;
  padding-left:var(--m);padding-right:1.6rem;}
.brand-mini{display:flex;align-items:center}
.brand-mini img{height:46px;width:auto}

/* ---------- Blattrahmen ---------- */
/* Beginnt an der Kopfzeile, nicht darunter – Kopfzeile, Lineal und
   Inhalt liegen in einem gemeinsamen Rahmen. */
.head-band{position:fixed;left:var(--edge);right:var(--edge);top:calc(var(--top) + var(--header-h));height:var(--m);
  background:var(--white);z-index:20;pointer-events:none;
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.frame{position:fixed;top:var(--top);right:var(--edge);bottom:14px;left:var(--edge);
  border:1px solid var(--rule-strong);pointer-events:none;z-index:30}
/* Die Rasterlinie beginnt erst unter der Kopfzeile – sie gehört zum
   Lineal/Inhalt, nicht zur Kopfzeile, in der das Logo an derselben
   x-Position ohne Linie dahinter sitzt. */
.frame::before{content:"";position:absolute;left:var(--m);top:var(--header-h);bottom:0;
  border-left:1px solid var(--rule)}
/* Die untere Kante des Kopfbands (.head-band) übernimmt die horizontale
   Linie – zwei übereinanderliegende Regeln hätten sich sonst dupliziert. */

.ruler{position:absolute;font-size:var(--fs-micro);letter-spacing:.18em;color:var(--ink-soft);
  transition:opacity .2s}
.ruler-y{left:0;top:calc(var(--header-h) + var(--m));bottom:0;width:var(--m);
  display:flex;flex-direction:column;justify-content:space-around;align-items:center}
/* Ohne Logo und Schalter im selben Band hat das Lineal seine ganze
   Breite zurück – keine Ausweich-Ränder mehr nötig. Beide Lineale sitzen
   absolut in .frame, dessen Nullpunkt jetzt oben an der Kopfzeile beginnt
   (nicht mehr am Kopfband) – deshalb hier +var(--header-h). */
.ruler-x{top:var(--header-h);left:var(--m);right:0;height:var(--m);
  display:flex;justify-content:space-around;align-items:center}
.ruler span{opacity:.5;transition:opacity .3s var(--ease),color .3s var(--ease)}
.ruler .on{opacity:1;color:var(--green-ink);font-weight:700}

/* Kein eigenes position:fixed mehr – sitzt jetzt als normales Flex-Kind
   in .site-header, rechtsbündig durch justify-content:space-between. */

/* ---------- Inhalt ---------- */
.sheet{padding:calc(var(--header-h) + 14px + var(--m) + 12px) var(--pad-r) 0 var(--pad-l)}
/* Sprungmarken: ohne das hier landet ein Klick auf einen Nav-Punkt genau
   unter der fixierten Kopfzeile, der Anfang des Abschnitts verschwindet
   dahinter. Versatz = Höhe der fixierten Kopfzone + etwas Luft. */
.field,.band{scroll-margin-top:calc(var(--top) + var(--header-h) + 24px)}
.field{position:relative;padding-block:clamp(3.5rem,7vw,7rem);border-bottom:1px solid var(--rule)}
.coord{position:absolute;left:calc(-1 * var(--tick));top:calc(clamp(3.5rem,7vw,7rem) + .25rem);
  font-size:var(--fs-micro);letter-spacing:.16em;color:var(--green-ink);font-weight:700}

/* Zonenmarke, Vorschau: statt einer immer sichtbaren Beschriftung, die an
   der Randlinie klebt, ein Strich, der von der Linie ausfährt, sobald der
   Abschnitt aktiv ist – vom selben Beobachter getrieben, der auch Lineal
   und Schalter-Pille synchron hält. Nur transform/opacity, kein Layout. */
/* War .7rem, unabhängig von der Größe der folgenden Überschrift – bei der
   großen Hero-Zeile ging das gerade noch durch, bei kleineren Überschriften
   hing die Marke sichtbar in der Luft. Ein knapper, fester Abstand liest
   sich als „gehört zu dieser Zeile“, unabhängig davon, wie groß sie ist –
   Nähe zählt, nicht Verhältnis. */
/* Höhe und Abstand hängen an --zone-block, damit die Objektspalten in
   E7 und E9 denselben Vorlauf bekommen können, ohne dass der Wert an
   drei Stellen einzeln gepflegt wird. */
.zone{position:relative;display:flex;align-items:center;
  height:var(--zone-h);margin-bottom:var(--zone-gap)}
.zone-tick{position:absolute;left:calc(-1 * var(--tick));top:50%;width:calc(var(--tick) + 4px);height:1px;background:var(--green);
  transform:scaleX(0);transform-origin:left;
  transition:transform var(--tick-dur) cubic-bezier(.16,1,.3,1)}
.zone-label{display:inline-block;vertical-align:middle;margin-left:.4rem;font-size:var(--fs-micro);letter-spacing:.16em;font-weight:700;
  color:var(--green-ink);opacity:0;transform:translateX(-6px);
  transition:opacity .4s var(--ease) .1s,transform .4s var(--ease) .1s}
.field.is-active .zone-tick{transform:scaleX(1)}
/* Gedecktes Grün ist für Papier gedacht – auf dem dunklen Band braucht es
   den hellen Ton, sonst ist die Marke dort kaum zu erkennen. */
.band .zone-tick{background:var(--green)}
.band .zone-label{color:var(--green)}
.field.is-active .zone-label{opacity:1;transform:none}

/* Grundgröße wie im alten Entwurf für Aussagen außerhalb des Heros
   (Haltung, später Kontakt) – der Hero bekommt seine eigene, größere
   Stufe direkt darunter. Beide teilten sich vorher versehentlich eine
   Größe, obwohl das Original hier eine klare Hierarchie hatte. */
.statement{font-weight:700;font-size:clamp(1.8rem,4.4vw,3.4rem);line-height:1.1;
  letter-spacing:-.015em;max-width:20ch}
.statement .g{color:var(--green)}
.hero .statement{font-size:clamp(2.4rem,6.4vw,5.4rem);line-height:.98;
  letter-spacing:-.03em;max-width:15ch}
/* Fließend wie im alten Entwurf statt fest – auf sehr breiten Blättern
   darf der Lead-Text bis 1.35rem mitwachsen. */
.lead{font-size:clamp(1.1rem,1.4vw,1.35rem);color:var(--ink-soft);max-width:46ch;margin-top:1.4rem}
/* Fließtext im Hauptfluss, nicht Begleittext in einem Bauteil: in der
   alten Fassung hatte dieser Absatz gar keine eigene Größe und lief auf
   der vollen Grundschrift (16–18px fluid). Mit --fs-base stand er auf
   15,2px und damit auf dem Niveau von Tabellen-Bemerkungen. --fs-body
   trifft die Mitte des alten Bereichs und bleibt in der Skala. */
.muted{font-size:var(--fs-body);color:var(--ink-soft);max-width:46ch;margin-top:1rem}
h2{font-weight:700;font-size:clamp(1.5rem,2.6vw,2.1rem);line-height:1.05;letter-spacing:-.02em;max-width:22ch}

/* Randlos heißt nicht endlos: der Rahmen wächst mit dem Fenster mit, der
   Content bekommt seine eigene Lesebreiten-Grenze, sonst zerfließt er auf
   breiten Monitoren proportional statt einfach mehr Platz frei zu lassen. */
.hero{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);
  gap:clamp(2rem,6vw,5rem);align-items:end;padding-top:clamp(2rem,5vw,4rem);max-width:var(--content-max)}
/* Im alten Entwurf gab es hier zwei Buttons und einen Scroll-Hinweis –
   fehlten hier komplett. Gleiche Sprache wie der Rest des Blatts: eckig,
   Haarlinien statt Pillen, kein Pfeil-Icon-Klischee. */
/* Aus dem Hero herausgelöst, damit die Modul-CTAs dieselbe Form benutzen
   statt einer zweiten, abweichenden Link-Optik. */
/* gap ersetzt den Wortzwischenraum: In einem Flex-Container werden reine
   Leerzeichen zwischen den Elementen verworfen. Sobald ein Wort der
   Beschriftung ein eigenes Element ist (.pn im Modul-CTA), klebte es
   sonst am nächsten – „E-BASEbesprechen“. */
.btn{display:inline-flex;align-items:center;gap:.3em;min-height:44px;
  padding:.75em 1.4em;font-weight:700;font-size:var(--fs-body);
  transition:background .2s var(--ease),border-color .2s var(--ease),color .2s var(--ease)}
.btn-primary{background:var(--ink);color:var(--white);border:1px solid var(--ink)}
.btn-primary:hover{background:var(--green-ink);border-color:var(--green-ink)}
.btn-ghost{background:none;color:var(--ink);border:1px solid var(--rule-strong)}
.btn-ghost:hover{border-color:var(--green-ink);color:var(--green-ink)}
.hero-cta{display:flex;flex-wrap:wrap;gap:.9rem;margin-top:2.2rem}

/* Wie im alten Entwurf: Aussage und Lead nebeneinander, nicht
   untereinander – dieselbe Spaltenteilung wie dort (1.1fr / .9fr). */
.two-col{display:grid;grid-template-columns:1.1fr .9fr;
  gap:clamp(2rem,5vw,4rem);align-items:start;max-width:var(--content-max)}
/* Registerhaltig: die Copy-Spalte beginnt dort, wo die erste Zeile der
   Headline endet (Zeilenhöhe 1.1 × deren fluide Schriftgröße), nicht
   mittig zur ganzen Headline. */
.two-col > :last-child{padding-top:calc(.92 * clamp(1.8rem,4.4vw,3.4rem))}
.hero-obj{position:relative;padding-bottom:46px}
.io{display:flex;align-items:center;gap:10%;padding-inline:6%}
.io .i{width:9%;height:auto}
.io .o{width:62%;height:auto}
.dim{position:absolute;left:6%;right:6%;bottom:20px;height:1px;background:var(--rule-strong)}
.dim::before,.dim::after{content:"";position:absolute;top:-4px;width:1px;height:9px;background:var(--rule-strong)}
.dim::before{left:0}.dim::after{right:0}
.dim-label{position:absolute;left:50%;bottom:2px;transform:translateX(-50%);
  padding:0 8px;font-size:var(--fs-micro);color:var(--ink-soft);white-space:nowrap}

/* ---------- Hero: die Teile treffen ein ------------------------------
   Sie fügen sich hier ausdrücklich nicht zusammen. Der Hero stellt die
   Prämisse – I und O getrennt, vermaßt, "Eingang · Ausgang" – und die
   Headline verspricht "From Input to System". Eingelöst wird das erst in
   B3 ("Wir schaffen Verbindungen"), wo die beiden Teile zusammenfahren.
   Zeigt der Hero das Fügen schon, ist B3 eine Wiederholung und beide
   Stellen verlieren.
   Bewegt wird nur waagerecht – das ist die Achse, die die Maßlinie
   darunter misst. Eine senkrechte Bewegung hätte auf dieser Zeichnung
   keinen Bezug und wäre bloß ein Auftritt.
   Alles an .hero gebunden: .dim und .dim-label gibt es auch in B3, dort
   sollen sie unangetastet stehen bleiben. */
.js .hero .io .i,.js .hero .io .o{opacity:0;
  transition:opacity .55s var(--ease),transform .55s var(--ease)}
.js .hero .io .i{transform:translateX(-14px);transition-delay:.1s}
.js .hero .io .o{transform:translateX(-18px);transition-duration:.65s;transition-delay:.3s}
.js .hero.is-active .io .i,.js .hero.is-active .io .o{opacity:1;transform:none}
/* Die Maßlinie zeichnet sich samt ihrer beiden Endmarken von links nach
   rechts. clip-path statt Maske: Die Marken sitzen als ::before/::after
   auf einer nur 1px hohen Fläche und ragen oben und unten darüber hinaus –
   eine Maske in Elementgröße würde sie wegschneiden. Die negativen Werte
   oben und unten lassen ihnen Platz. */
.js .hero .dim{clip-path:inset(-8px 100% -8px 0);
  transition:clip-path .75s var(--ease) .8s}
.js .hero.is-active .dim{clip-path:inset(-8px 0 -8px 0)}
.js .hero .dim-label{opacity:0;transition:opacity .35s var(--ease) 1.3s}
.js .hero.is-active .dim-label{opacity:1}

/* ---------- Verbindungs-Sequenz (Kompetenz) ---------------------------
   Kopfzone wie im Hero: Aussage links, Zeichen rechts, unten bündig.
   Der Ablauf hängt an derselben .is-active-Klasse wie Lineal und
   Zonenmarken – ein Beobachter, nicht ein zweiter Mechanismus. Nur
   transform, opacity und fill, kein Layout in Bewegung. */
.konnex{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);
  gap:clamp(2rem,6vw,5rem);align-items:end;max-width:var(--content-max);padding-bottom:2rem}
/* Das Zeichen hängt tiefer als der Text daneben – die 2rem unten sind
   der reservierte Gegenwert dazu, sonst rückt es dem Geltungsbereich-
   Feld darunter auf die Kante (dort waren nur 38px Luft). */
.konnex-obj{padding-inline:6%;position:relative;top:2rem}
.cx{width:100%;height:auto;overflow:visible}
.cx-ring path{fill:var(--green)}
/* Schritt 1: Der Ring dreht sich, bis seine Lücke nach links zeigt – zum
   Strich hin. Gedreht wird um den echten Kreismittelpunkt (280.64/277.78),
   nicht um die Mitte der Bounding-Box: die Lücke schneidet die Oberkante
   weg, dadurch liegen beide 1,4 Einheiten auseinander. Deshalb die
   Platzierung als Funktionsliste statt über transform-origin – Start und
   Ende haben dieselben Funktionen, nur der Winkel ändert sich, das
   interpoliert sauber als Drehung. */
.cx-ring{transform-origin:0 0;
  transform:translate(320.76px,0) translate(280.64px,277.78px) rotate(0deg) translate(-280.64px,-277.78px);
  transition:transform .65s cubic-bezier(.16,1,.3,1) .15s}
.field.is-active .cx-ring{
  transform:translate(320.76px,0) translate(280.64px,277.78px) rotate(-90deg) translate(-280.64px,-277.78px)}
/* Schritt 2: Der Strich legt sich um und fährt in die Lücke – 164,385
   Einheiten wäre die Strecke zwischen Start- und Endmitte, plus 4,01:
   die Lücke endet innen mit einer geraden Kante, die Strichkappe ist
   aber leicht ballig. Ohne den Zuschlag stehen ihre beiden Ecken genau
   um diesen Betrag zurück und es bleiben zwei feine Kerben stehen. */
.cx-bar{transform-box:fill-box;transform-origin:center;
  transition:transform .85s cubic-bezier(.16,1,.3,1) .75s}
.field.is-active .cx-bar{transform:translate(168.395px,0) rotate(90deg)}
/* Schritt 3: Erst wenn er sitzt, wird aus zwei Teilen ein System. */
.cx-bar path{fill:var(--blue);transition:fill .45s var(--ease) 1.7s}
.field.is-active .cx-bar path{fill:var(--green)}

/* table-layout:auto überließ die Spaltenbreite dem Browser – und dessen
   Algorithmus bemisst sie an ALLEN Zeilen der Spalte zusammen, nicht an
   der einzelnen Zelle. Je nachdem, was sonst noch in der Spalte stand,
   bekam „Interdisziplinäres Engineering“ mal genug Platz, mal nicht – das
   ist keine Entscheidung, das ist eine Rechnung, die niemand nachvollziehen
   kann. Die Breite unten ist gemessen (226px für den längsten real
   vorkommenden Eintrag) und fest gesetzt: jede Zeile verhält sich gleich,
   unabhängig vom Nachbarinhalt.
   Kein max-width mehr auf der Tabelle selbst: Die Trennlinien sollen die
   volle Blattbreite nutzen, die jetzt durch --sheet-max ohnehin begrenzt
   ist – eine zweite, engere Grenze obendrauf hätte nur wieder Umbrüche
   erzwungen, wo sichtbar Platz war. */
/* max-width auf .bem (der Zelle) wirkt bei table-layout:fixed nicht – die
   Spaltenbreite kommt vom <col>, nicht vom Zelleninhalt. Deckelt deshalb
   hier die ganze Tabelle, sonst reißt die Bemerkung-Spalte auf sehr
   breiten Monitoren unlesbar weit auseinander. */
/* ---------- Geltungsbereich (Kompetenz) --------------------------------
   Anwendungsbereich und Positionsliste sind auf einer Zeichnung zwei
   verschiedene Felder. Vorher standen beide als identische Tabelle
   untereinander, durchnummeriert 01–08 – das las sich als eine flache
   Achterliste, und die "drei Welten" aus dem Lead verschwanden darin.
   Hier deshalb dreispaltig, unnummeriert, mit senkrechten Haarlinien als
   Feldtrenner statt Zeilen. */
/* Oben und unten geschlossen: ein Feld auf einer Zeichnung hat eine
   definierte Unterkante, sonst läuft es ohne Abschluss in die Liste
   darunter. Die Unterkante ist die schwächere Linie – sie trennt zwei
   Felder, sie eröffnet keines. */
.scope{max-width:var(--content-max);margin-top:2.4rem;padding-bottom:2.2rem;
  border-top:1px solid var(--rule-strong);border-bottom:1px solid var(--rule)}
/* Feldbeschriftung – benennt, was darunter steht (Geltungsbereich,
   Leitsätze). Eine Regel für beide, damit die Beschriftungen im Blatt
   nicht auseinanderlaufen. */
.scope-caption,.tenets-caption{margin-top:.6rem;font-size:var(--fs-sm);font-weight:600;color:var(--ink-soft)}
.scope-cols{display:grid;grid-template-columns:repeat(3,1fr);margin-top:1.2rem}
.scope-cols > div{padding:0 1.6rem;border-left:1px solid var(--rule)}
.scope-cols > div:first-child{padding-left:0;border-left:0}
/* Überschriften-Stufe unter h2, nicht Fließtext: die drei Welten stehen
   eine Ebene über den Positionen der Liste darunter. Fluid wie die
   übrigen Überschriften, deshalb bewusst außerhalb der --fs-Skala. */
.scope-cols h3{font-weight:700;font-size:var(--fs-h3);
  line-height:1.15;letter-spacing:-.01em;margin-bottom:.5rem}
.scope-cols p{font-size:var(--fs-base);color:var(--ink-soft)}

.list{width:100%;max-width:var(--content-max);table-layout:fixed;border-collapse:collapse;margin-top:2.4rem}
/* Mehr Luft, wenn direkt ein geschlossenes Feld darüber steht – sonst
   liegen zwei Kopfzeilen (Geltungsbereich / Pos.) dicht aufeinander. */
.scope + .list{margin-top:3.6rem}
/* Spaltenköpfe sind Beschriftung, keine Bezugsnotation – normale
   Groß-/Kleinschreibung statt der Kapitälchen-Tracking-Masche, die vorher
   über fast jedem Label lag, unabhängig davon, ob sie etwas bedeutete. */
.list th{text-align:left;font-size:var(--fs-sm);font-weight:600;
  color:var(--ink-soft);padding:0 1rem .6rem 0;border-bottom:1px solid var(--rule-strong)}
/* Bei table-layout:fixed bestimmt die ERSTE Zeile der Tabelle die
   Spaltenbreiten – das ist die Kopfzeile, nicht die Datenzeilen. Breiten
   auf den <td> selbst hätten deshalb keine Wirkung; sie gehören auf die
   <col>-Elemente. overflow-wrap ist die zweite, unabhängige Absicherung:
   selbst mit korrekten Spaltenbreiten malt ein einzelnes langes Wort ohne
   Umbruch-Erlaubnis sichtbar über den Zellenrand hinaus, ohne dass sich
   die Elementgröße selbst ändert – ein Layout-Check findet das nicht. */
.list col.c-bez{width:2.8rem}
/* Gemessen, nicht geraten: „Interdisziplinäres Engineering“ braucht 226px
   bei diesem Schnitt – plus 24px rechtes Zellenpolster (.ben padding-right),
   macht 250px minimal nötig. 17rem (272px) lässt jede Zeile einzeilig
   stehen, mit Luft statt auf Kante genäht. */
.list col.c-ben{width:17rem}
.list td{padding:1rem 1rem 1rem 0;border-bottom:1px solid var(--rule);vertical-align:baseline;overflow-wrap:break-word}
.list .bez{font-weight:700;font-size:var(--fs-micro);color:var(--green-ink);white-space:nowrap}
/* Eine Stufe höher als die Bemerkung daneben (vorher nur 0,1rem
   Unterschied – die Benennung stand kaum von ihrer eigenen Beschreibung
   ab), bleibt aber unter den Überschriften des Geltungsbereichs. */
.list .ben{font-weight:700;font-size:var(--fs-lg);padding-right:1.5rem}
.list .bem{color:var(--ink-soft);font-size:var(--fs-base);max-width:60ch}
.list .bem .claim{display:block;color:var(--ink);font-size:var(--fs-body);margin-bottom:.3rem}
.list tr:last-child td{border-bottom:0}

/* Randlos bis an beide Blattkanten, auch wenn der Inhalt mittig steht:
   die negativen Ränder heben genau die Polster der Seite auf. */
.band{margin-left:calc(-1 * var(--pad-l));margin-right:calc(-1 * var(--pad-r));
  padding:clamp(3rem,6vw,5.5rem) var(--pad-r) clamp(3rem,6vw,5.5rem) var(--pad-l);
  background:var(--blue-900);color:rgba(255,255,255,.82);
  border-block:1px solid var(--rule-strong)}
.band h2{color:#fff}
.band .lead{color:rgba(255,255,255,.68)}
/* Wie im alten Entwurf: Einleitung sticky links, Signalschiene rechts –
   beim Scrollen durch die vier Ebenen bleibt der Text sichtbar, statt
   nach oben aus dem Bild zu laufen. */
/* Hälftig geteilt. Vorher .82/1.18 zugunsten der Schiene – gemessen war
   es aber genau umgekehrt: bei 1700px war die linke Spalte mit 548px
   restlos ausgereizt (die Aussage bricht auf drei Zeilen), während rechts
   318px leer blieben, weil die Ebenentexte ohnehin bei 56ch abbrechen.
   Die engere Spalte trug den gedrängteren Inhalt. */
.arch-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(2rem,5vw,4rem);align-items:start}
.arch-intro{position:sticky;top:calc(var(--header-h) + 28px)}
/* Kein Abstand nach oben mehr nötig – die Schiene steht jetzt neben der
   Einleitung, nicht mehr darunter. Der alte Wert kommt mobil zurück,
   sobald beide Spalten wieder gestapelt werden. */
/* --over: Überstand der Schiene über den ersten Abgriff hinaus. Sie soll
   sichtbar von weiter oben kommen, nicht am ersten Abgriff beginnen. */
/* Auf Höhe der Überschrift beginnen wie Foto und Formular: Der Strang
   setzte an der Zonenmarke an, 61,7px über den Versalien von "Vom
   Projektziel …" (gemessen 180 gegen 241,5).
   Bezugspunkt ist die Oberkante des ersten Knotens, nicht die der Linie:
   Deren Überstand nach oben (--over) ist gewollt und läuft ins Dunkle
   aus – er ist der Anlauf des Signals, nicht der Anfang des Inhalts. */
.rail{position:relative;padding-left:2.6rem;--over:2.6rem;--under:.4em;
  margin-top:calc(var(--zone-block) + var(--statement-versalversatz))}
.rail::before{content:"";position:absolute;left:0;top:calc(-1 * var(--over));
  bottom:var(--under);width:1px;background:rgba(255,255,255,.2)}
/* Die Schiene endet nicht, sie verlässt nur das Blatt. Die Ausblendung
   liegt auf dem HINTERGRUND, nicht auf den Linien: eine Maske am unteren
   Ende des grünen Wegs hätte dessen wandernde Front weichgezeichnet
   statt sein Ende. So verlieren sich graue Schiene und grüner Weg
   gleichermaßen im Dunkeln, und die Front bleibt scharf. Breit genug,
   um auch den Schein des Signals mit abzudecken. */
.rail::after{content:"";position:absolute;left:-12px;width:25px;
  top:calc(-1 * var(--over));bottom:var(--under);pointer-events:none;
  background:
    linear-gradient(to bottom,var(--blue-900),transparent) top/100% 2.6rem no-repeat,
    linear-gradient(to top,var(--blue-900),transparent) bottom/100% 2.6rem no-repeat}
/* Der grüne Signalweg wächst von oben mit --p (0…1), wie im alten
   Stromlaufplan – scrollgesteuert, fällt ohne JS/reduced-motion einfach
   weg und die statische grüne Linie darunter bleibt sichtbar. */
/* Dieselbe Ausblendung am oberen Ende, sonst läge eine harte grüne
   Kante über der ausgelaufenen grauen. Unten bleibt der Signalkopf
   scharf – er ist die Front, nicht ein Ende. Die Maske sitzt am festen
   Oberrand des Elements, der Wert bleibt also stehen, während die Höhe
   mit --p wächst. */
.rail-signal{position:absolute;left:0;top:calc(-1 * var(--over));width:1px;
  height:calc(var(--p, 0) * (100% + var(--over) - var(--under)));background:var(--green);
  box-shadow:0 0 10px 1px rgba(0,219,158,.5)}
.rail-signal::after{content:"";position:absolute;left:50%;bottom:0;width:9px;height:9px;
  border-radius:50%;background:var(--green);transform:translate(-50%,50%);
  box-shadow:0 0 0 4px rgba(0,219,158,.16),0 0 14px 2px rgba(0,219,158,.5);
  opacity:var(--head,0)}
/* Luft zwischen Abgriff und Text: ohne sie stößt die Leitung direkt an
   den Anfangsbuchstaben der Ebene. Die Einrückung dafür stand früher
   im entfallenen Kennungsfeld. */
.node{position:relative;padding:.75rem 0 .75rem 1.1rem}
.node::before{content:"";position:absolute;left:-2.6rem;top:1.35em;width:2.6rem;height:1px;background:var(--green);
  transform-origin:left;transition:transform .5s var(--ease),background .5s var(--ease)}
.node::after{content:"";position:absolute;left:calc(-2.6rem - 3px);top:calc(1.35em - 3px);width:7px;height:7px;background:var(--green);
  border-radius:50%;transition:background .4s var(--ease)}
/* Der Ebenen-Name ist das Thema der Ebene und damit das Stärkste hier.
   Vorher hatte er gar keine eigene Größe (geerbte 16px) und stand damit
   KLEINER da als sein eigener Untertitel darunter (16,8px) – beide fett
   und weiß. Dieselbe Stufe wie Geltungsbereich und Modulname: das Blatt
   hat damit eine durchgehende dritte Überschriften-Ebene. */
.node h3{font-weight:700;font-size:var(--fs-h3);line-height:1.15;
  letter-spacing:-.01em;color:#fff;transition:color .4s var(--ease)}
/* Der Untertitel tritt zurück – kleiner UND grün, also auch in der Art
   unterschieden statt nur in der Größe. So war es im alten Entwurf. */
.node-title{display:block;margin-top:.35rem;font-weight:700;
  font-size:var(--fs-body);color:var(--green);max-width:40ch;transition:color .4s var(--ease)}
.node p{margin-top:.15rem;font-size:var(--fs-base);color:var(--grey);
  max-width:56ch;transition:color .4s var(--ease)}
/* Grundzustand = voll lesbar (gilt auch ohne JS). Erst wenn JS läuft und
   die Schiene ihren Fortschritt kennt, starten die Ebenen gedimmt und
   werden beim Scrollen nacheinander freigeschaltet. */
.js .node:not(.on)::before{transform:scaleX(.35);background:rgba(255,255,255,.18)}
.js .node:not(.on)::after{background:rgba(255,255,255,.25)}
.js .node:not(.on) h3,.js .node:not(.on) .node-title{color:rgba(255,255,255,.35)}
.js .node:not(.on) p{color:rgba(255,255,255,.25)}

/* ---------- Module: Sammelschiene -------------------------------------
   "Drei Module. Ein System." – drei Listenzeilen zeigten nur das
   Getrenntsein. An einer gemeinsamen Schiene hängend zeigen sie beides:
   ein System und trotzdem einzeln lesbar, einzeln beauftragbar.
   Waagerecht und ohne Signalweg – die senkrechte, animierte Schiene
   gehört der Systemarchitektur, sonst wiederholt sich das Blatt. */
/* Um --drop nach links gerückt: die Abgriffe sollen neben dem Text
   stehen, nicht in ihm. Dadurch beginnt der Text des ersten Moduls
   weiterhin genau an der Inhaltskante, während Schiene und Abgriff
   davor liegen. */
.bus{position:relative;max-width:var(--content-max);margin-top:3.2rem;padding-top:3.4rem;
  --drop:1.4rem;margin-left:calc(-1 * var(--drop))}
/* --green statt --green-ink: gezeichnete Elemente tragen den hellen
   Markenton, der gedeckte bleibt der Schrift vorbehalten. */
.bus-rail{position:absolute;left:0;right:0;top:1.5rem;height:2px}
/* Die Linie liegt im ::before, nicht im Element selbst: Sie fährt beim
   Eintritt einmal von links nach rechts aus, und die Klemme am Ende darf
   dabei nicht mitskaliert werden. Eine Geste statt drei Auftritten – die
   Module selbst bleiben ruhig stehen, die Schiene kommt und nimmt sie
   auf. Der Signalweg (Punkt wandert, Stationen schalten frei) bleibt der
   Systemarchitektur vorbehalten; hier zeichnet sich nur eine Linie aus,
   wie die Zonenmarken es überall auf dem Blatt tun. */
/* --ease statt der Kurve der Zonenmarken: die ist stark vorgezogen und
   für einen 70px-Strich richtig, der schnappen soll. Über die volle
   Inhaltsbreite legt sie 60 % der Strecke in den ersten 120 ms zurück –
   man sieht dann kein Ausfahren mehr, nur ein Erscheinen. */
.bus-rail::before{content:"";position:absolute;inset:0;background:var(--green);
  transform-origin:left center;
  transition:transform 1.1s var(--ease)}
/* Offene Klemme am Ende: die Schiene hört nicht auf, sie steht bereit. */
.bus-rail::after{content:"";position:absolute;right:0;top:50%;width:9px;height:9px;
  border-radius:50%;border:2px solid var(--green);background:var(--white);
  transform:translate(50%,-50%)}
/* Ohne JS gibt es kein .is-active – dann steht die Schiene sofort und
   vollständig da. Sie ist die Aussage der Sektion, nicht ihre Zugabe. */
.js .bus-rail::before{transform:scaleX(0)}
.js .bus-rail::after{opacity:0;transition:opacity .35s var(--ease) .9s}
.js .field.is-active .bus-rail::before{transform:scaleX(1)}
.js .field.is-active .bus-rail::after{opacity:1}
.bus-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.6rem,3.5vw,3rem)}
/* Spalte als Flex, damit der CTA unten andockt: die drei Beschreibungen
   sind unterschiedlich lang, sonst stehen die drei Links auf drei
   verschiedenen Höhen. */
.mod{position:relative;padding-left:var(--drop);padding-right:1.5rem;display:flex;flex-direction:column}
/* Der Abgriff läuft über die volle Spaltenhöhe weiter und tut damit
   zwei Dinge zugleich: Er ist die Verbindung zur Schiene UND die
   Trennlinie zum Nachbarmodul. Aus drei Stapeln unter einem Strich
   wird eine Sammelschiene mit drei abgehenden Strängen.
   Unten läuft er offen aus – geschlossen wäre es eine Tabelle, offen
   bleibt es ein Schaltplan. */
.mod-drop{position:absolute;left:0;top:-1.9rem;bottom:0;width:2px;
  background:linear-gradient(to bottom,
    var(--green) 0,
    var(--green) calc(100% - 5rem),
    transparent 100%)}
.mod-pos{font-weight:700;font-size:var(--fs-micro);color:var(--green-ink);margin-bottom:.5rem}
/* Der Modulname ist das Stärkste in der Spalte – vorher stand der Claim
   fett und dunkel darüber und schlug den Produktnamen. */
/* Versalien wie im Logotyp. Bewusst über text-transform statt im
   Markup: der Produktname heißt „e-base“, so steht er im Quelltext, in
   den strukturierten Daten und beim Kopieren – nur die Darstellung ist
   versal. Versalien brauchen etwas Laufweite; das negative Tracking der
   Fließsatz-Überschriften wäre hier zu eng.
   .pn trägt dasselbe im Fließtext der CTAs – dort nur das Produktwort,
   nicht der ganze Satz: „E-BASE BESPRECHEN“ würde schreien. */
.pn{text-transform:uppercase;letter-spacing:.03em}
.mod-name{font-weight:700;font-size:var(--fs-h3);line-height:1.15;
  text-transform:uppercase;letter-spacing:.03em}
.mod-step{font-size:var(--fs-sm);color:var(--green-ink);font-weight:600;margin-top:.15rem}
/* Gewicht statt nur Farbe: Claim und Beschreibung standen beide auf
   15,2px und unterschieden sich allein im Grauwert. Der alte Entwurf
   hatte den Claim zusätzlich halbfett gesetzt. */
.mod-claim{font-size:var(--fs-base);font-weight:600;color:var(--ink);margin-top:.9rem}
.mod-text{font-size:var(--fs-base);color:var(--ink-soft);margin-top:.4rem}
/* Outline-Button statt Fließtext-Link: das ist die eigentliche Handlung
   des Abschnitts, und die Form gibt es im Blatt schon (Hero, "Leistungen
   ansehen"). margin-top:auto dockt ihn unten an, damit alle drei auf
   einer Linie stehen. Etwas kleiner als im Hero – drei nebeneinander in
   schmalen Spalten, und sie sollen dem Haupt-CTA nicht den Rang ablaufen. */
.mod-link{align-self:start;margin-top:auto;
  font-size:var(--fs-base);padding:.7em 1.1em}
/* Mindestabstand zum Button – margin-top:auto allein könnte auf null
   zusammenfallen, wenn eine Spalte die volle Höhe füllt. */
.mod-text{margin-bottom:1.4rem}

/* ---------- Prüfliste (Lebenszyklus) – bewusst kein drittes .list, sonst
   wiederholt sich dieselbe Tabellenform ein drittes Mal in Folge. Eine
   knappe, einspaltige Liste mit kleinen Ordnungszahlen statt Spalten. ---- */
.checklist{margin-top:2rem}
.checklist li{display:flex;gap:1rem;padding:.85rem 0;border-bottom:1px solid var(--rule)}
.checklist li:last-child{border-bottom:0}
.checklist .n{font-weight:700;color:var(--green-ink);min-width:1.6rem;flex:none}
/* Hatte keine eigene Größe und erbte die 16px der Grundschrift – ein
   Wert, den die Skala gar nicht kennt. Fließtext im Hauptfluss, also
   dieselbe Stufe wie der Haltung-Absatz. */
.checklist p{max-width:60ch;margin:0;font-size:var(--fs-body)}

/* ---------- Lebenszyklus: Anschlusspunkt mit auslaufendem Leiter ------
   Schluss der Checkliste, nicht Objekt neben der Überschrift: Als Hero-
   Zeichen bekäme D6 exakt die Silhouette von B3, und zwei Sektionen mit
   derselben Geometrie sind genau das, was das Blatt sonst vermeidet.
   Hier bauen die sieben Punkte auf den Ring zu und die Linie verlässt
   ihn – die Liste wird zum Zeitstrahl.
   Strichstärke = Durchmesser/7: dasselbe Verhältnis wie im Zeichen von
   B3 (Ringstärke 80,18 bei 561,28 Außendurchmesser). Eine gezeichnete
   Einheit auf dem ganzen Blatt, keine dritte Linienstärke. */
/* Der Ring hat exakt den Durchmesser des Rings aus B3. Beide Zeichen als
   dieselbe Figur zu zwei Zeitpunkten zu lesen, funktioniert nur bei
   gleicher Größe – bei 44px gegen 152px sieht niemand einen Zusammenhang.
   B3 skaliert flüssig mit der Inhaltsbreite (.cx{width:100%} in einer
   .75fr-Spalte), deshalb hier dieselbe Ableitung statt einer festen
   Größe: 19,4 % der Inhaltsbreite, gemessen gegen B3 nachgerechnet. */
/* Kopfzone wie in B3: Aussage links, Zeichen rechts. Das Zeichen steht
   nicht wie dort in seiner Spalte still, sondern verlässt sie – die
   Linie läuft über die Blattkante hinaus. Deshalb hier kein
   padding-bottom als Gegenwert für einen Versatz. */
.cycle-head{padding-bottom:0}
.cycle{position:relative;
  --d:calc((100vw - var(--pad-l) - var(--pad-r)) * .194);--w:calc(var(--d) / 7);
  /* Der Zuschlag zur Höhe fängt Beschriftung und Maßlinie auf – beide
     stehen absolut und zählen sonst in keiner Höhe mit. */
  height:calc(var(--d) + 3.6rem)}
.cycle-ring{position:absolute;left:0;top:0;width:var(--d);height:var(--d);
  border:var(--w) solid var(--green);border-radius:50%}
/* Der Verlauf sitzt im Hintergrund, nicht in der Maske: Ohne Maskenunter-
   stützung bleibt so das richtige Bild stehen, nur die Bewegung fehlt. */
/* Um eine Strichstärke in den Ring hinein, nicht an ihn heran: Bei
   left:var(--d) berührt die Linie den Kreis nur in einem einzigen Punkt.
   Der Kreis krümmt sich von dort sofort weg – an den Ober- und Unterkanten
   der Linie steht seine Außenkante schon bei 150,4px gegen 151,3px, also
   0,8px Luft, und die Verbindung sieht aus wie ein Anstoßen. Mit dem
   Versatz läuft die Linie in die Ringstärke hinein und die Fuge ist zu. */
/* right über die Spalte hinaus statt über einen negativen Rand am
   Elternelement: .cycle steht jetzt in der schmalen Rasterspalte, ein
   negativer Rand würde deren Breite ändern und damit den Ring. Absolut
   positioniert wächst nur die Linie über die Kante. */
.cycle-line{position:absolute;left:calc(var(--d) - var(--w));right:calc(-1 * var(--pad-r));
  top:calc(var(--d) / 2 - var(--w) / 2);height:var(--w);
  background:linear-gradient(to right,var(--green) 0,var(--green) 55%,transparent 88%)}
/* Beschriftung an einer Zeichnung – dieselbe Rolle und dieselbe Form wie
   .dim-label in B3. Nicht wie .zone-label: gesperrte grüne Versalien sind
   auf dem Blatt die Zonenmarke (A1, B3, C5 …), und "Projektabschluss"
   sähe damit aus wie eine. */
/* Mittig unter dem Ring, nicht unter .cycle: Das Element reicht bis zur
   Spaltenkante, seine Mitte läge weit rechts vom Zeichen. Bezug ist der
   Ring, also die halbe Ringbreite. */
.cycle-label{position:absolute;left:calc(var(--d) / 2);transform:translateX(-50%);
  top:calc(var(--d) + .5rem);
  font-size:var(--fs-micro);color:var(--ink-soft);white-space:nowrap}
/* Maßlinie wie unter dem Zeichen in B3 – aber nur mit einem Maßhilfsstrich.
   Eine Maßlinie hat zwei Endmarken, weil sie eine Strecke misst; diese
   hat links eine und rechts keine, weil die Strecke kein Ende hat. Sie
   läuft im selben Verhältnis aus wie der Leiter darüber, damit beide als
   eine Zeichnung lesen. Gedeckte Zeichnungsfarbe, nicht Grün: sie
   beschriftet das Zeichen, sie ist nicht Teil davon. */
.cycle-dim{position:absolute;left:0;right:calc(-1 * var(--pad-r));
  top:calc(var(--d) + 2.4rem);height:1px;
  background:linear-gradient(to right,var(--rule-strong) 0,var(--rule-strong) 55%,transparent 88%)}
.cycle-dim::before{content:"";position:absolute;left:0;top:-4px;
  width:1px;height:9px;background:var(--rule-strong)}
.js .cycle-dim{
  -webkit-mask-image:linear-gradient(to right,#000 0,#000 50%,transparent 58%);
  mask-image:linear-gradient(to right,#000 0,#000 50%,transparent 58%);
  -webkit-mask-size:200% 100%;mask-size:200% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:100% 0;mask-position:100% 0;
  transition:-webkit-mask-position 1.6s cubic-bezier(.45,.15,.35,1),
             mask-position 1.6s cubic-bezier(.45,.15,.35,1)}
.js .cycle.is-drawn .cycle-dim{-webkit-mask-position:0 0;mask-position:0 0}
/* Aufbau über eine wandernde Maske statt über scaleX oder width: scaleX
   würde den Verlauf mitstauchen (am Anfang eine kurze, komplett blasse
   Linie), width wäre eine Layout-Animation. Die Maske fährt von rechts
   herein, ihre weiche Kante ist die wachsende Spitze und geht am Ende im
   Verlauf des Hintergrunds auf.

   Maskenbreite und Kantenlage sind nicht frei wählbar. Bei Breite S und
   Kante a liegt die Spitze bei x = (S·a − (S−1)·p) · Linienlänge.
   Damit p=100% genau "nichts gezeichnet" und p=0% genau "ganz
   gezeichnet" bedeutet, muss a = (S−1)/S und zugleich a = 1/S sein –
   das geht nur bei S=2, a=50%. Jede andere Kombination bildet den
   Wertebereich verzerrt ab: mit S=3/a=60% lag der ganze sichtbare
   Vorgang zwischen p=90% und p=40%, gezeichnet in rund 260 ms, der Rest
   war unsichtbares Nachkriechen.
   Der Rest der Maske (50…58%) ist die weiche Spitze, rund 16% der Länge.

   Eigene Kurve statt --ease: --ease ist stark vorgezogen und für ein
   Schalten richtig (Sammelschiene: Spannung liegt an). Hier geht es um
   Dauer – dass die Linie Zeit braucht, ist die Aussage. Also gleichmäßig
   und erst am Ende auslaufend. */
.js .cycle-line{
  -webkit-mask-image:linear-gradient(to right,#000 0,#000 50%,transparent 58%);
  mask-image:linear-gradient(to right,#000 0,#000 50%,transparent 58%);
  -webkit-mask-size:200% 100%;mask-size:200% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:100% 0;mask-position:100% 0;
  transition:-webkit-mask-position 1.6s cubic-bezier(.45,.15,.35,1),
             mask-position 1.6s cubic-bezier(.45,.15,.35,1)}
/* .is-drawn statt .field.is-active: siehe Kommentar in main.js – am
   Abschnitt hängend wäre die Linie fertig, bevor man sie sieht. */
.js .cycle.is-drawn .cycle-line{-webkit-mask-position:0 0;mask-position:0 0}
/* Zitat als angehefteter Vermerk, wie eine Notiz am Blattrand – eine
   Bezugslinie, kein Zitat-Layout aus dem alten Kartensystem. */
.annotation{margin-top:2.4rem;padding-left:1.3rem;border-left:2px solid var(--green);max-width:34rem}
.annotation + .annotation{margin-top:1.4rem}
.annotation p{font-weight:700;font-size:var(--fs-lg);line-height:1.35;color:var(--ink)}
.annotation cite{display:block;margin-top:.5rem;font-style:normal;font-weight:600;
  font-size:var(--fs-sm);letter-spacing:.1em;color:var(--ink-soft)}
.band .annotation{border-left-color:var(--green)}
.band .annotation p{color:#fff}
.band .annotation cite{color:var(--grey)}

/* ---------- Leitsätze (Lebenszyklus) --------------------------------
   Drei gleichrangige Sätze. Untereinander gestapelt ergaben sie nach
   der siebenzeiligen Prüfliste einen sehr langen senkrechten Lauf;
   nebeneinander lesen sie sich als das, was sie sind – ein Satz von
   drei Grundsätzen auf einer Ebene. */
.tenets{max-width:var(--content-max);margin-top:3rem;border-top:1px solid var(--rule-strong)}
.tenets-cols{display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(1.6rem,3.5vw,3rem);margin-top:1.4rem}
/* Im Raster trägt der Abstand das Raster, nicht der Außenabstand. */
.tenets-cols .annotation,.tenets-cols .annotation + .annotation{margin-top:0}
/* In der Schiene sitzt die Notiz sonst näher an der Signallinie als an
   der Textspalte der Ebenen darüber und wirkt dadurch unverbunden –
   hier auf dieselbe Spalte wie X1–X4 (.node-title/.node p) ausgerichtet. */
.rail .annotation{padding-top:1.4rem;padding-left:0;
  border-left:0;border-top:1px solid rgba(255,255,255,.18)}

/* ---------- Über ---------- */
/* Text zuerst (linke Spalte, breiter), Bild zweite Spalte, schmaler –
   damit steht der Strich links wie in jedem anderen Abschnitt, nicht
   rechts neben dem Foto. */
.about{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.6fr);
  gap:clamp(2rem,5vw,4rem);align-items:start;max-width:var(--content-max)}
/* Auf Höhe der Überschrift beginnen, nicht auf Höhe der Zonenmarke:
   Ohne den Vorlauf startete das Foto 40px über der Überschrift (gemessen
   1219 gegen 1259) und stand dadurch ohne Bezug neben dem Text. */
.about-obj{position:relative;padding-bottom:34px;
  margin-top:calc(var(--zone-block) + var(--statement-versalversatz))}
/* Natives Format des Fotos (1100×1100), deshalb kein Beschnitt: der
   Ausschnitt ist im Bild selbst gesetzt – Johann rechts, der mobile
   Arbeitsplatz links. Ein CSS-Beschnitt würde eine der beiden Hälften
   wegnehmen. aspect-ratio bleibt trotzdem stehen, damit vor dem Laden
   kein Layoutsprung entsteht. */
/* Nur leicht gerundet: Auf dem Blatt ist 2px am Navigationsmenü bisher
   der einzige eckige Radius, alles andere ist entweder scharfkantig oder
   ein voller Kreis. 3px nimmt dem Foto die Härte, ohne eine zweite
   Formensprache aufzumachen. */
.about-obj img{width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;filter:grayscale(.15);
  border-radius:3px}
/* Kennwerte als Feld, nicht als zwei lose Blöcke: senkrechte Haarlinie
   als Trenner wie im Geltungsbereich, waagerechte als Oberkante. */
.about-facts{position:relative;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  margin-top:2.2rem;padding-top:1.4rem}
.about-facts > div{padding:0 1.6rem;border-left:1px solid var(--rule)}
.about-facts > div:first-of-type{padding-left:0;border-left:0}
/* Fährt sich aus statt einfach dazustehen – dieselbe Geste und dieselbe
   Kurve wie die Zonenmarken am linken Blattrand. Nur transform. */
.facts-rule{position:absolute;left:0;right:0;top:0;height:1px;background:var(--rule-strong);
  transform:scaleX(0);transform-origin:left;
  transition:transform .7s cubic-bezier(.16,1,.3,1) .1s}
.field.is-active .facts-rule{transform:scaleX(1)}
/* Die Werte treten nach der Linie hervor – zwei Schritte, wie Strich und
   Marke bei den Zonen. Ein Hochzähler ginge nur bei „25+“, „DACH“ bliebe
   stehen; ein animierter und ein stehender Wert nebeneinander läse sich
   als Versehen. */
.about-facts .n,.about-facts .l{opacity:0;transform:translateY(4px);
  transition:opacity .45s var(--ease) .5s,transform .45s var(--ease) .5s}
.field.is-active .about-facts .n,.field.is-active .about-facts .l{opacity:1;transform:none}
.about-facts .n{font-weight:700;font-size:1.8rem;color:var(--green-ink);line-height:1}
.about-facts .l{font-size:var(--fs-sm);color:var(--ink-soft);margin-top:.2rem}

/* ---------- FAQ ---------- */
.faq-list{margin-top:1.6rem}
.faq-list details{border-bottom:1px solid var(--rule);padding:.3rem 0}
.faq-list summary{list-style:none;cursor:pointer;padding:1rem 0;font-weight:700;
  font-size:var(--fs-body);display:flex;justify-content:space-between;gap:1rem;align-items:center;
  transition:color .2s var(--ease)}
.faq-list summary:hover{color:var(--green-ink)}
.faq-list summary::-webkit-details-marker{display:none}
.faq-list summary::after{content:"+";color:var(--green-ink);font-weight:400;font-size:1.6em;line-height:1;flex:none;
  transition:transform .3s var(--ease)}
.faq-list summary:hover::after{transform:scale(1.15)}
.faq-list details[open] summary::after{content:"–"}
/* Sanftes Auf-/Zuklappen über grid-template-rows statt height – native
   details öffnen sonst schlagartig. .a-wrap bleibt (gegen die
   UA-Vorgabe, die den Inhalt bei :not([open]) auf display:none setzt)
   immer als Grid gerendert, nur die Zeilenhöhe animiert zwischen 0fr/1fr. */
.faq-list .a-wrap{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .38s var(--ease)}
.faq-list details[open] .a-wrap{grid-template-rows:1fr}
.faq-list .a{overflow:hidden;min-height:0;padding:0 0 1.2rem;color:var(--ink-soft);
  font-size:var(--fs-body);max-width:60ch}

/* ---------- Kontakt: echtes Formular, Zellen wie das Schriftfeld ------- */
.contact{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(2rem,5vw,4rem);align-items:start;max-width:var(--content-max)}
/* Gleicher Vorlauf wie beim Foto in E7 – das Formular begann sonst auf
   Höhe der Zonenmarke und wirkte neben der Überschrift angehängt. */
.contact form{margin-top:calc(var(--zone-block) + var(--statement-versalversatz))}
/* Gebaut wie die Positionsliste in D6, nicht mit Haken. Die Häkchen waren
   das einzige rein webtypische Element auf dem Blatt – überall sonst
   gliedern Marke links, Aussage rechts und eine Haarlinie dazwischen.
   Die Marke übernimmt zugleich die Bindung, die vorher der Doppelpunkt
   leisten musste: Die Spalte sagt, wozu die Zusage gehört.
   Bewusst kleiner als D6 (--fs-base statt --fs-body) und mit drei statt
   sieben Zeilen – gleiche Sprache, nicht dieselbe Sektion zweimal. */
.contact ul{margin-top:1.4rem}
.contact li{display:flex;gap:1rem;padding:.7rem 0;
  border-bottom:1px solid var(--rule);font-size:var(--fs-base);color:var(--ink-soft)}
.contact li:last-child{border-bottom:0}
/* Feste Spaltenbreite an der längsten Marke ("Erstgespräch", gemessen
   92px) – sonst stünden die drei Aussagen auf drei Einzügen. */
.contact li .k{font-weight:700;color:var(--green-ink);min-width:6.5rem;flex:none}
.contact li p{margin:0}
.form-status{padding:.85em 1em;margin-bottom:1.1rem;font-size:var(--fs-base);border:1px solid var(--rule-strong)}
.form-status[hidden]{display:none}
.form-status.is-ok{border-color:var(--green-ink);color:var(--green-ink)}
.form-status.is-error{color:#a33}
.form-status strong{display:block;font-weight:700}
.formcell{border:1px solid var(--rule-strong);margin-bottom:-1px}
.formcell label{display:block;font-size:var(--fs-micro);color:var(--ink-soft);padding:.55em .8em 0}
.formcell input,.formcell textarea{width:100%;border:0;background:transparent;
  font:inherit;font-size:var(--fs-body);color:var(--ink);padding:.3em .8em .7em}
.formcell input:focus,.formcell textarea:focus{outline:2px solid var(--green-ink);outline-offset:-2px}
.formcell textarea{resize:vertical;min-height:6rem}
.hp{position:absolute;left:-9999px}
.form-submit{margin-top:1.3rem;display:inline-flex;align-items:center;gap:.6rem;
  border:1px solid var(--ink);background:var(--ink);color:var(--white);
  font:inherit;font-weight:700;font-size:var(--fs-body);padding:.75em 1.4em;cursor:pointer;
  min-height:44px}
.form-submit:hover{background:var(--green-ink);border-color:var(--green-ink)}
.formcell input,.formcell textarea{min-height:44px}
.list .bem a{display:inline-flex;align-items:center;min-height:44px}
.legal{margin-top:1.4rem;font-size:var(--fs-sm);color:var(--ink-soft)}
.legal a{color:var(--green-ink);text-decoration:underline}

/* 600px statt 560: die Gegenstandszeile braucht ohne Umbruch 544px, mit
   Zellpolster und Rahmen rund 572 – bei 560 brach „E-CAE-Dokumentation“
   in die zweite Zeile. Der Rest ist Reserve für Rendering-Unterschiede. */
.titleblock{margin:0 0 calc(14px + var(--m)) auto;width:min(100%,600px);
  border:1px solid var(--rule-strong);display:grid;grid-template-columns:repeat(4,1fr);
  margin-top:clamp(3rem,6vw,5rem)}
.tb{border-right:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:.7rem .8rem}
.tb:nth-child(4n){border-right:0}
.tb.wide{grid-column:span 4}
.tb.half{grid-column:span 2}
.tb dt{font-size:var(--fs-micro);letter-spacing:.2em;color:var(--ink-soft);text-transform:uppercase;margin-bottom:.3rem}
.tb dd{font-size:var(--fs-base);font-weight:700;line-height:1.25}
.tb.wide dd{font-size:var(--fs-lg)}
/* Rechtliches: Links links, Rechtevermerk rechts an der Feldkante.
   flex-wrap statt float – ein echter float ließe die Folgezeile um den
   Vermerk herumfließen; hier soll er umbrechen und dann links stehen.
   Die zwei Gruppen sind als <span> gefasst, weil sonst jeder Link und
   jeder Mittelpunkt ein eigenes Flex-Element wäre und space-between alle
   drei auseinanderzöge. */
.tb-legal{display:flex;flex-wrap:wrap;justify-content:space-between;
  align-items:baseline;gap:.2rem 1.2rem}

/* ---------- Schalter (unverändert aus index.html, nur Kontext neu) ---- */
.fab{position:relative;display:flex;align-items:center;flex:none}
/* Eckig statt Pille – alles andere auf dem Blatt ist mit Haarlinien und
   rechten Winkeln gezeichnet, ein voll abgerundeter Knopf war ein Rest der
   alten Karten-Ästhetik. Das Signet (.fab-mark) bleibt rund: das ist die
   gezeichnete Form des Zeichens selbst, keine UI-Konvention. */
/* Nur das Zeichen selbst, ohne Box/Pille/Kreis dahinter – so wie im
   Referenzbild: das Ein/Aus-Signet in Tinte, freistehend auf dem Blatt. */
/* min-height: das Zeichen misst 30px, mit Polsterung ergab das 43px –
   1px unter der Mindestgröße für Bedienziele. */
.fab-btn{flex:none;display:inline-flex;align-items:center;gap:0;cursor:pointer;
  padding:.4rem;min-height:44px;background:none;border:none;box-shadow:none}
/* Feste Breite statt variabler max-width – "Systemarchitektur" ist das
   längste Wort (gemessen 150px), alle kürzeren Namen bekommen denselben
   Platz. Sonst ändert sich beim Scrollen von Abschnitt zu Abschnitt die
   Breite mit jedem Wort, und der Schalter zuckt seitlich. */
.fab-here{width:0;overflow:hidden;opacity:0;
  transition:width .45s var(--ease),opacity .3s var(--ease)}
.fab-here-t{display:block;font-weight:600;font-size:var(--fs-sm);letter-spacing:.04em;
  color:var(--ink-soft);white-space:nowrap;padding-right:1.4rem;text-align:right}
.fab-btn.has-here .fab-here{width:10rem;opacity:1}
.fab-mark{display:grid;place-items:center;width:30px;height:30px;flex:none;
  transition:transform .35s var(--ease)}
.fab-mark .sig{grid-area:1/1;width:30px;height:30px;overflow:visible;fill:var(--ink);
  transition:opacity .34s var(--ease),fill .3s var(--ease)}
.fab-mark .sig-standby{opacity:1}
.fab-mark .sig-on{opacity:0}
.fab.open .fab-mark{transform:scale(1.06)}
.fab.open .fab-mark .sig{fill:var(--green)}
.fab.open .fab-mark .sig-standby{opacity:0}
.fab.open .fab-mark .sig-on{opacity:1}

/* Fährt aus der Kopfzeile nach links aus statt darunter aufzuklappen –
   eine Zeile, die sich fortsetzt, kein Menü, das herunterfällt. right:100%
   setzt die rechte Kante der Liste an die linke Kante des Schalters; die
   Liste wächst von dort nach links, so weit der Inhalt braucht. Mobil
   bleibt die vertikale Fassung, weil sechs Einträge nebeneinander auf
   375px nicht lesbar wären. */
.fab-items{position:absolute;top:50%;right:100%;transform:translateY(-50%);
  margin-right:.65rem;display:flex;flex-direction:row;align-items:center;gap:.5rem;
  visibility:hidden;pointer-events:none}
.fab.open .fab-items{visibility:visible;pointer-events:auto}
.fab-items li{opacity:0;transform:translateX(10px);transition:opacity .2s,transform .2s}
.fab.open .fab-items li{opacity:1;transform:none}
.fab-items a{display:block;padding:.62em 1.1em;border-radius:2px;font-weight:500;font-size:var(--fs-base);
  color:var(--ink);background:var(--white);border:1px solid var(--rule-strong);white-space:nowrap;
  transition:color .2s var(--ease),border-color .2s var(--ease),background .2s var(--ease)}
.fab-items a:hover{color:var(--green-ink);border-color:var(--green-ink)}
.fab-items a.is-cta{background:var(--ink);color:var(--white);border-color:var(--ink);font-weight:600}
.fab-items a.is-cta:hover{color:var(--green)}

/* Sechs Einträge nebeneinander brauchen ~766px – gemessen, nicht geraten.
   Unter 1080px reicht der Platz zwischen Schalter und Blattkante nicht
   mehr zuverlässig; bei 916px lief die Liste bereits 7px über den Rand.
   Eigene, höhere Schwelle statt der allgemeinen 820px-Mobilgrenze, damit
   die Layoutregeln unten unabhängig davon bleiben, wann die Navigation
   umschaltet. */
@media (max-width:1080px){
  .fab-items{position:absolute;top:calc(100% + .65rem);right:0;left:auto;
    transform:none;margin-right:0;flex-direction:column;align-items:flex-end;gap:.5rem}
  .fab-items li{transform:translateY(-10px)}
  .fab.open .fab-items li{transform:none}
}

@media (max-width:820px){
  :root{--m:34px}
  .hero,.two-col,.arch-grid,.konnex{grid-template-columns:1fr}
  /* Gestapelt steht das Zeichen ohnehin unter dem Text – der Versatz
     hätte hier keinen Bezug mehr. */
  .konnex{padding-bottom:0}
  .konnex-obj{top:0}
  /* Einspaltig bekommt das Zeichen in B3 die ganze Spalte statt einer
     .75fr-Teilbreite – der Ring wächst dort von 19,4 % auf 56 % der
     Inhaltsbreite. Ohne diese Zeile liefen die beiden Ringe hier wieder
     auseinander (113px gegen 39px gemessen). */
  .cycle{--d:calc((100vw - var(--pad-l) - var(--pad-r)) * .56)}
  /* Einspaltig kein Raster, sondern wieder Blöcke untereinander. Grund:
     .konnex schaltet hier auf 1fr, und 1fr ist minmax(auto,1fr) – die
     Spur wächst also auf die Mindestbreite ihres Inhalts. "Projektabschluss."
     ist in dieser Schriftgröße 230px breit, die Spalte nur 201px; die Spur
     wurde damit 222px breit, .cycle mit ihr, und die daran hängende Linie
     schob die Seite um 21px auf (396 gegen 375). Als Block hat die
     Überschrift keine Spur, die sie aufziehen könnte. */
  .cycle-head{display:block}
  .cycle-head .cycle{margin-top:2.4rem}
  .arch-intro{position:static}
  .rail{margin-top:2.6rem}
  .hero-obj{max-width:260px;margin-top:2.5rem}
  /* Einspaltig steht nichts mehr neben einer Überschrift, an der sich
     etwas ausrichten müsste – das Foto rückt sogar vor den Text
     (order:-1) und bekäme den Vorlauf an der völlig falschen Stelle.
     Das Formular behält einen eigenen, kleineren Abstand zum Text. */
  .about-obj{margin-top:0}
  .contact form{margin-top:2.4rem}
  /* Drei Spalten passen bei ~230 px Inhaltsbreite nicht mehr sauber
     nebeneinander – erzwungen bricht Fließtext mitten im Wort. Gestapelt
     statt gequetscht: Pos. und Benennung in einer Zeile, Bemerkung als
     eigener Absatz darunter, volle Breite. Keine Karte, keine neue Form –
     dieselbe Haarlinie trennt weiterhin die Positionen. */
  .about,.contact{grid-template-columns:1fr}
  /* Die feste Markenspalte der Kontaktliste passt hier nicht mehr: Sie
     nimmt 104px von 201px Inhaltsbreite, der Aussage blieben 81px – drei,
     drei und sechs Zeilen (gemessen). Gestapelt wie die Kompetenz-Tabelle
     darüber: Marke auf eigener Zeile, Aussage in voller Breite darunter.
     Die Haarlinie trennt weiterhin die Einträge. */
  .contact li{display:block}
  .contact li .k{display:block;min-width:0;margin-bottom:.15rem}
  /* Senkrechte Feldtrenner ergeben gestapelt keinen Sinn – wird zur
     waagerechten Trennung wie bei den Listen darunter. */
  .scope-cols{grid-template-columns:1fr}
  /* Gestapelt braucht jeder Satz wieder seinen eigenen Abstand. */
  .tenets-cols{grid-template-columns:1fr;gap:1.4rem}
  /* Gestapelt trennt die Waagerechte, nicht die Senkrechte. */
  .about-facts{grid-template-columns:1fr}
  .about-facts > div{padding:1.1rem 0;border-left:0;border-top:1px solid var(--rule)}
  .about-facts > div:first-of-type{padding-top:1.1rem;border-top:0}
  /* Gestapelt wird aus der liegenden Schiene eine stehende: die Leitung
     läuft links senkrecht durch, die Abgriffe zeigen nach rechts. Die
     Aussage "ein System" bleibt, die Form passt sich der Spalte an. */
  .bus{padding-top:0;padding-left:1.6rem;margin-left:0}
  .bus-rail{left:0;right:auto;top:.6rem;bottom:.6rem;width:2px;height:auto}
  /* Senkrecht gestellt fährt die Schiene von oben nach unten aus – die
     Leserichtung der gestapelten Module. */
  .bus-rail::before{transform-origin:center top}
  .js .bus-rail::before{transform:scaleY(0)}
  .js .field.is-active .bus-rail::before{transform:scaleY(1)}
  .bus-rail::after{right:auto;left:50%;top:auto;bottom:0;transform:translate(-50%,50%)}
  .bus-grid{grid-template-columns:1fr;gap:2.4rem}
  .mod{padding-right:0;padding-left:0}
  /* Gestapelt läuft die Schiene senkrecht links, der Abgriff zeigt
     waagerecht darauf zu – kein Verlauf, kein Durchziehen: hier trennt
     der Abstand, nicht eine Linie. */
  .mod-drop{left:-1.6rem;top:.85rem;bottom:auto;width:1.6rem;height:2px;
    background:var(--green)}
  .scope-cols > div{padding:1.1rem 0;border-left:0;border-top:1px solid var(--rule)}
  .scope-cols > div:first-child{padding-top:0;border-top:0}
  /* Mobil zurückgedreht: Foto zuerst, Text darunter – hier gibt es das
     Lineal/den Strich ohnehin nicht (.ruler-x/.ruler-y sind ausgeblendet),
     also keine Reihenfolge-Pflicht, und das Foto zuerst liest sich besser. */
  .about-obj{order:-1;max-width:280px}
  .list thead{display:none}
  .list, .list tbody, .list tr, .list td{display:block;width:auto}
  .list tr{padding:1.1rem 0;border-bottom:1px solid var(--rule)}
  .list td{padding:0;border-bottom:0;overflow-wrap:normal}
  .list .bez{display:inline;margin-right:.7rem}
  .list .ben{display:inline;padding-right:0}
  .list .bem{display:block;margin-top:.35rem}
  .titleblock{grid-template-columns:repeat(2,1fr)}
  .tb:nth-child(4n){border-right:1px solid var(--rule)}
  .tb:nth-child(2n){border-right:0}
  .tb.wide,.tb.half{grid-column:span 2}
  /* Rahmen bleibt als dünne Linie – Lineal und Marke fallen weg, kein
     Platz, kein erzwungenes Verkleinern. Der Schalter bleibt: er ist die
     Bedienung, kein Schmuck. */
  /* Logo bleibt jetzt sichtbar – es sitzt in der eigenen Kopfzeile, nicht
     mehr im gedrängten Blatt-Kopfband, und muss dem Lineal nicht mehr
     ausweichen. */
  .ruler-x,.ruler-y{display:none}
  .sheet{padding-top:calc(var(--header-h) + 14px + 34px + 16px)}
}

/* ---------- Ersatz für frühere Inline-Styles -------------------------
   style="…"-Attribute sind unter style-src 'self' genauso gesperrt wie
   <style>-Blöcke. Diese drei Regeln lösen die letzten drei ab. */
/* Letzter Abschnitt vor dem Schriftfeld – keine Trennlinie nach unten. */
.field:last-of-type{border-bottom:0}
/* Rechtslinks im Schriftfeld. */
.tb a{color:var(--green-ink);font-weight:600;text-decoration:underline;
  text-underline-offset:2px}
.tb a:hover{color:var(--ink)}

/* ---------- Sprungmarke für Tastatur und Screenreader ---------------
   Sichtbar erst bei Fokus, dann als Feld über dem Blattrand. */
.skip-link{position:fixed;top:-100px;left:var(--m);z-index:80;
  padding:.75rem 1.2rem;background:var(--ink);color:var(--white);
  font-weight:700;font-size:var(--fs-base);
  transition:top .2s var(--ease)}
.skip-link:focus{top:var(--top)}

/* ---------- Rechtsseiten (Impressum, Datenschutz) -------------------
   Eigene Seiten ohne Rahmen und Lineal – dieselbe Schrift, dieselben
   Haarlinien, damit die Seite eine Formensprache behält. */
.legal-page{padding:clamp(2.5rem,6vw,5rem) var(--m) clamp(4rem,8vw,7rem)}
.legal-page .wrap{max-width:70ch;margin-inline:auto}
.legal-page .back{display:inline-flex;align-items:center;gap:.5rem;
  min-height:44px;font-size:var(--fs-base);font-weight:600;color:var(--green-ink)}
.legal-page .back:hover{color:var(--ink)}
.legal-page h1{font-weight:700;font-size:clamp(1.9rem,4vw,2.8rem);
  line-height:1.1;letter-spacing:-.02em;margin:1.6rem 0 1.4rem}
.legal-page h2{font-size:var(--fs-h3);margin:2.4rem 0 .6rem}
.legal-page h3{font-size:var(--fs-lg);margin:1.6rem 0 .4rem}
/* Die gelieferte Datenschutzerklärung gliedert bis in die vierte und
   fünfte Ebene (Konferenz-Tools > Microsoft Teams > Auftragsverarbeitung).
   Ohne eigene Stufen fielen h4 und h5 auf die Browservorgabe zurück.
   h4 liegt auf der Größe des Fließtexts und unterscheidet sich nur durch
   Fettung und die dunklere Textfarbe – kleiner als der Absatz, den sie
   einleitet, darf eine Überschrift nicht sein. Erst h5 geht darunter,
   und dort steht nur noch ein einzelner, immer gleicher Absatz. */
.legal-page h4{font-size:var(--fs-body);margin:1.3rem 0 .35rem}
.legal-page h5{font-size:var(--fs-base);margin:1.1rem 0 .3rem;letter-spacing:.02em}
.legal-page p,.legal-page li{font-size:var(--fs-body);color:var(--ink-soft);
  margin-bottom:.7rem}
.legal-page ul{padding-left:1.2rem;list-style:disc}
/* Die Datenschutzerklärung nennt Quellen als ausgeschriebene Adressen
   ("https://www.adobe.com/de/privacy/policies/adobe-fonts.html"). Ohne
   Umbruchpunkt sind das unteilbare Wörter, die breiter sind als die
   Spalte: mobil schob die längste die Seite auf 464px bei 375px
   Fensterbreite auf. */
.legal-page a{color:var(--green-ink);text-decoration:underline;text-underline-offset:2px;
  overflow-wrap:anywhere}
.legal-page a:hover{color:var(--ink)}
.legal-page .todo{padding:.9rem 1.1rem;border-left:2px solid var(--green-ink);
  font-size:var(--fs-base)}
.legal-page .mt{margin-top:1.1rem}
.legal-page .mt-lg{margin-top:2.5rem}

/* ---------- Aufziehdauer der Zonenmarken ----------------------------
   Ab 1652px beginnt die Zentrierung, ab da wächst der Strich. Die
   Stufen sind gemessen: bei 1700px ist er rund 150px lang, bei 2100px
   rund 300px, bei 2600px über 500px. */
@media (min-width:1700px){ :root{--tick-dur:.7s} }
@media (min-width:2100px){ :root{--tick-dur:.85s} }
@media (min-width:2600px){ :root{--tick-dur:1s} }

/* ---------- Bewegungspräferenz -------------------------------------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
  /* Die Regel oben nimmt nur die Dauer, nicht den Startzustand: Die
     Schiene stünde weiterhin bis zum Eintritt der Sektion auf Null und
     erschiene dann schlagartig. Sie ist tragendes Bild der Sektion, also
     steht sie hier von Anfang an – wie ohne JS. */
  .js .bus-rail::before{transform:none!important}
  .js .bus-rail::after{opacity:1!important}
  .js .cycle-line,.js .cycle-dim{-webkit-mask-position:0 0!important;mask-position:0 0!important}
  /* .dim-label ist hier bewusst nicht dabei: Es wird über
     translateX(-50%) zentriert, ein transform:none würde es verschieben.
     Es animiert ohnehin nur seine Deckkraft. */
  .js .hero .io .i,.js .hero .io .o{opacity:1!important;transform:none!important}
  .js .hero .dim-label{opacity:1!important}
  .js .hero .dim{clip-path:none!important}
}
