/* ==========================================================================
   Guthabenkarten im ÖPNV — Landingpage
   --------------------------------------------------------------------------
   Eigenes, helleres Design (Kundenentscheidung) — bewusst NICHT das
   Navy-Flächen-Layout der Hauptseite (landing-page/DESIGN.md).

   Farblogik der Seite:
     Obere Hälfte  = die Sache. Papier, Tinte und das Gelb-Grün des deutschen
                     Haltestellenschilds (StVO Zeichen 224) — die Farbe des
                     Ortes, an dem eine Fahrt beginnt.
     Untere Hälfte = der Absender. Ab #402payment ausschließlich Navy,
                     Signal-Rot und Weiß, also die Markenfarben aus
                     brand-assets/colors.css. Der Farbwechsel ist der
                     Abschnittswechsel; deshalb taucht Gelb dort nirgends auf.

   Schrift: durchgehend Inter (Kundenwunsch). Die drei Rollen-Tokens
   (Anzeige / Text / Daten) bleiben getrennt, zeigen aber alle auf dieselbe
   Familie — die Hierarchie trägt Gewicht, Größe und Sperrung. Fällt der
   Webfont aus, greift die System-Kette und das Layout hält.

   Signatur der Seite: die Karte. Gezeichnet im echten ID-1-Format
   (85,60 × 53,98 mm → 1,586), Chip und Kontaktlos-Symbol als SVG-Sprite in
   index.html. Alle Innenmaße der Karte laufen über Container-Query-Einheiten
   (cqi), damit die Karte als EIN Objekt skaliert — im Hero klein, in der
   Projektliste groß, ohne zweiten Satz Regeln.

   JS: vier Dateien, drei davon unverändert aus der Hauptseite übernommen —
       scroll-reveal.js, mailchimp-popup.js und button-ripple.js — plus
       karten-lupe.js für die Kartenvergrößerung. Alle sind Progressive
       Enhancement: ohne JS ist alles sichtbar, die Whitepaper-Buttons bleiben
       Anker auf #whitepaper, der Lupen-Knopf ist ausgeblendet und die Knöpfe
       behalten Hover-, Active- und Focus-Zustand aus dem CSS.
   ========================================================================== */

:root {
  /* --- Bogen & Tinte (obere Seitenhälfte) ---
     Das Papier ist Weiß (Kundenwunsch). Was sich davon absetzt, trägt die
     Tönung aus --flaeche; siehe dort. */
  --bogen:       #FFFFFF;

  /* Die getönte Fläche der Seite. EIN Token für alles, was sich vom weißen
     Papier absetzt — seit 2026-09-09 ein aufgehelltes 402PAYMENT-Navy statt
     eines neutralen Graus.

     Daran hängen: der Abschnitt „Was ist eine Guthabenkarte", die Fragen, der
     Kreis hinter dem Kartenfächer, die getönte Spalte im Vergleich, der
     gemeinsame Kopf, der Quellenkasten, die Piktogramm-Scheiben, die
     Rohling-Schraffur, der Fortschrittsbalken im Popup und zwei
     Überfahr-Zustände. Also jede Fläche, die vorher grau war.

     Ausprobieren lässt sich die Tönung mit  ?farben  im Browser (farben.js).
     --bogen-tief zeigt auf denselben Wert und bleibt als eigener Name
     bestehen: es benennt die Rolle „Kleinteil-Tönung", falls die beiden
     später doch auseinanderlaufen sollen. */
  --flaeche:     #E9ECF5;
  --bogen-tief:  var(--flaeche);

  --weiss:       #FFFFFF;
  /* Die Schrift trägt seit 2026-09-09 das 402PAYMENT-Navy statt eines
     neutralen Schwarz. Über dieses Token laufen auch die gefüllten Knöpfe
     der zweiten Stufe — „Projekte ansehen" im Hero bekommt die Farbe damit
     ohne eigene Regel. */
  --tinte:       #0B0B23;
  --tinte-weich: #5A5D66;               /* 6,2:1 auf Weiß */
  --linie:       rgba(22, 24, 29, 0.14);
  --linie-stark: rgba(22, 24, 29, 0.28);

  /* --- Haltestellenschild (StVO Z. 224) — genau ein Abschnitt --- */
  --halt-gelb:   #FFC800;
  --halt-gruen:  #0B4A2F;               /* 6,6:1 auf Gelb */

  /* --- 402PAYMENT (untere Seitenhälfte), aus brand-assets/colors.css --- */
  --navy:        #0B0B23;
  --signal:      #FF4436;
  --navy-weich:  rgba(255, 255, 255, 0.68);   /* 9,1:1 auf Navy */
  /* Koralle aus der Infografik (2026-09-11), dort die Akzentfarbe neben
     Navy. Auf der Seite nur im Ablauf-Abschnitt: Haken, Guthabenbalken,
     Zeitbalken. 4,6:1 auf Navy, für Striche und Flächen ausreichend. */
  --koralle:     #F26B43;
  --linie-hell:  rgba(255, 255, 255, 0.16);

  /* Knopfschrift ist überall Weiß (Kundenwunsch). Auf Signal-Rot sind das
     3,42:1 statt der von WCAG AA geforderten 4,5:1 — dieselbe bewusste
     Abweichung, die auch die Hauptseite fährt (dort in styles.css als
     --on-primary dokumentiert). Betrifft ausschließlich Knopfschrift; alle
     übrigen Textfarben dieser Seite erfüllen AA. */
  --auf-knopf:   #FFFFFF;

  /* --- Schrift ---
     Alles Inter (Kundenwunsch 2026-08-24). Die drei Rollen bleiben als eigene
     Tokens bestehen, obwohl sie derselben Familie zeigen: die Seite
     unterscheidet Anzeige, Fließtext und Daten weiterhin über Gewicht, Größe
     und Sperrung — und ein späterer Rückbau auf eine eigene Anzeige- oder
     Datenschrift bleibt eine Änderung an genau diesen drei Zeilen.
     Was der Wechsel kostet, steht in der README unter „Schrift". */
  --schrift-anzeige: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  --schrift-text:    "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  --schrift-daten:   "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;

  /* Steilere Kurve als üblich: die Überschrift teilt sich ab 701 px die Zeile
     mit dem Kartenfächer und muss trotzdem bei 1280 px groß ankommen.
     Unter 700 px gilt der flachere Wert im Breakpoint weiter unten. */
  --fs-hero:  clamp(2.4rem, 0.6rem + 6vw, 5.75rem);
  --fs-h2:    clamp(1.85rem, 1.35rem + 2.1vw, 3rem);
  --fs-h3:    clamp(1.1rem,  1.02rem + 0.36vw, 1.35rem);
  --fs-lead:  clamp(1.03rem, 0.98rem + 0.28vw, 1.2rem);
  --fs-text:  1.0313rem;
  --fs-klein: 0.9063rem;
  --fs-marke: 0.75rem;

  /* --- Maß --- */
  --huelle: 1240px;
  --rand:   clamp(1.25rem, 5vw, 3.5rem);
  --luft:   clamp(4rem, 8.5vw, 7.5rem);
  --lesbar: 62ch;
  --tipp:   44px;                        /* WCAG 2.2 Target Size */

  --r-knopf: 4px;      /* Eingabefelder */
  --r-pille: 999px;    /* Knöpfe im Ruhezustand, siehe DESIGN.md §6.2 */
  /* Von 3 px auf 8 px (Vorlage 2026-09-07): die harten Kanten waren der
     zweite Grund, warum die Seite technisch statt wertig wirkte. */
  --r-flaeche: 8px;
  --r-karte: 14px;
  /* Ring statt Rahmen: eine Kontur, die die Fläche nicht einschließt,
     sondern nur andeutet. In der Vorlage ring-1 ring-foreground/5. */
  --ring: 0 0 0 1px rgba(22, 24, 29, 0.06);
  --schatten-karte-weich: 0 1px 2px rgba(22, 24, 29, 0.05), 0 12px 28px -14px rgba(22, 24, 29, 0.22);

  --aus: cubic-bezier(0.2, 0.7, 0.25, 1);

  /* MD3-Physik der Knöpfe (DESIGN.md §6.2): Federung mit Overshoot beim
     Loslassen, Standard-Easing zum Hineindrücken und für den Ripple. */
  --ease-feder:    cubic-bezier(0.2, 0.8, 0.2, 1.2);
  /* Glatt (2026-09-11): lange Bremsstrecke, kein Überschwingen. Für alles,
     was in den Ablaufbildern ankommt oder den Fokus wechselt. --aus ist
     dafür zu kurz im Auslauf, --ease-feder schwingt über. */
  --ease-glatt:    cubic-bezier(0.22, 0.85, 0.28, 1);
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);

  --schatten-sm:    0 6px 16px -8px rgba(22, 24, 29, 0.22);

  --schatten-karte: 0 2px 4px rgba(22, 24, 29, 0.14), 0 14px 34px -12px rgba(22, 24, 29, 0.42);
  --schatten-hoch:  0 4px 8px rgba(22, 24, 29, 0.16), 0 26px 56px -16px rgba(22, 24, 29, 0.48);
}

/* ---------- Reset & Basis ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

/* scroll-padding = Höhe der schwebenden Leiste plus Luft, damit ein
   Sprungziel nicht unter ihr landet. */
html { scroll-behavior: smooth; scroll-padding-top: 5.5rem; }

body {
  background: var(--bogen);
  color: var(--tinte);
  font-family: var(--schrift-text);
  font-size: var(--fs-text);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /* Inter bringt eigene Schnitte für kleine und große Grade mit; ohne
     optical-sizing bleibt überall derselbe. */
  font-optical-sizing: auto;
}

/* Tabellenziffern NUR dort, wo Zahlen untereinander stehen sollen. Auf dem
   ganzen Body wären sie falsch: im Fließtext laufen tabellarische Ziffern
   unnötig breit und reißen Löcher in Sätze wie „15, 30 oder 50 Euro". */
.fakten, .karte__nr, .schritt__nr, .status {
  font-variant-numeric: tabular-nums;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }

h1, h2, h3 {
  font-family: var(--schrift-anzeige);
  font-weight: 800;
  line-height: 1.05;
  /* Etwas enger als vorher (-0,015em): Inter läuft in großen Graden weit,
     die Überschriften wirkten dadurch locker gesetzt. */
  letter-spacing: -0.025em;
  text-wrap: balance;
}
h3 { font-weight: 700; font-size: var(--fs-h3); line-height: 1.2; letter-spacing: -0.005em; }

.huelle {
  width: 100%;
  max-width: var(--huelle);
  margin-inline: auto;
  padding-inline: var(--rand);
}

.abschnitt { padding-block: var(--luft); }

/* Sichtbarer Fokusring auf jedem Untergrund. Die Ringfarbe wird pro
   Abschnitt umgestellt, weil ein dunkler Ring auf Navy unsichtbar wäre. */
:where(a, button, summary, input, [tabindex]):focus-visible {
  outline: 3px solid var(--tinte);
  outline-offset: 2px;
  border-radius: var(--r-flaeche);
}
.ablauf :where(a, button, summary):focus-visible { outline-color: var(--koralle); }
:where(.absender, .whitepaper, .fuss, .lupe-dialog) :where(a, button):focus-visible { outline-color: var(--weiss); }
/* Der Lupen-Knopf deckt die Karte komplett ab; ein Ring auf seiner Außenkante
   wäre der Ring um die Karte. Genau das ist hier gewollt. */
.lupe:focus-visible { outline-offset: -2px; }

.skip-link {
  position: absolute;
  left: 0.5rem; top: 0.5rem; z-index: 1001;
  transform: translateY(-160%);
  background: var(--tinte); color: var(--bogen);
  padding: 0.75rem 1rem; border-radius: var(--r-knopf);
  font-weight: 600; font-size: var(--fs-klein);
  transition: transform 0.2s ease-out;
}
.skip-link:focus-visible { transform: none; }


/* ==========================================================================
   Bausteine
   ========================================================================== */

/* Kleine Marke über jeder Überschrift. Sagt, um welche Art von Information es
   geht — kein Nummerierungssystem, weil die Abschnitte keine Reihenfolge sind. */
.marke {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--schrift-daten);
  font-size: var(--fs-marke);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tinte-weich);
}
.marke--hell { color: var(--navy-weich); }
.marke--halt { color: var(--navy-weich); }

.kopfzeile { max-width: 46rem; }
.kopfzeile--breit { max-width: none; }
.kopfzeile h2 { margin-top: 0.9rem; font-size: var(--fs-h2); }
.kopfzeile .lead { margin-top: 1.1rem; }

.lead {
  font-size: var(--fs-lead);
  line-height: 1.58;
  color: var(--tinte-weich);
  max-width: var(--lesbar);
}
.lead--hell { color: var(--navy-weich); }

/* Unausgefüllte Angabe. Bewusst als solche erkennbar (Schraffur + gestrichelte
   Grundlinie) statt still gelassen — Publikum sind öffentliche Auftraggeber,
   eine erfundene Zahl kostet mehr als ein sichtbar leeres Feld.
   Vor Go-Live:  grep -n 'data-todo' index.html   */
.todo {
  font-family: var(--schrift-daten);
  font-size: 0.82em;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--tinte-weich);
  background: repeating-linear-gradient(45deg,
              rgba(22, 24, 29, 0.055) 0 5px, transparent 5px 10px);
  border-bottom: 1.5px dashed var(--linie-stark);
  padding: 0.12em 0.4em;
  white-space: nowrap;
}


/* ==========================================================================
   Knöpfe — MD3-Shape-Morph + Ripple, übernommen von der Hauptseite
   --------------------------------------------------------------------------
   Portiert aus ../landing-page/landingpage/styles.css (Spezifikation:
   DESIGN.md §6.2). Klassennamen und Mechanik bleiben identisch, damit
   button-ripple.js unverändert läuft und die Knöpfe im Whitepaper-Popup —
   mailchimp-popup.js schreibt fest .btn/.btn--primary/.btn--outline ins
   Markup — ohne Sonderregeln dasselbe Verhalten bekommen. Als einzige Klassen
   dieser Seite sind sie deshalb englisch benannt.

   Ruhezustand ist eine Pille. Beim Drücken zieht sich der Radius zusammen
   (schnell, ease-standard), beim Loslassen federt er mit Overshoot zurück
   (ease-spring). Der Ripple kommt von button-ripple.js; ohne JS bleibt alles
   andere intakt.

   Abweichungen von der Vorlage, jeweils aus Entscheidungen dieser Seite:
   · Der dunkle Knopf nimmt die Tinte dieser Seite. Die war lange ein
     neutrales #16181D, weil Navy im hellen Seitenteil sonst nirgends vorkam;
     seit 2026-09-09 IST die Tinte das Marken-Navy (#0B0B23), der Knopf trägt
     es also mit — ohne eigene Regel.
   · .btn--outline ist gefüllt statt umrandet, siehe Kommentar dort.
   ========================================================================== */
.btn {
  position: relative; overflow: hidden; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: var(--tipp);
  font-family: var(--schrift-anzeige);
  font-weight: 600; font-size: 0.9375rem; line-height: 1;
  padding: 0.8rem 1.6rem;
  border: 2px solid transparent;
  border-radius: var(--r-pille);
  cursor: pointer; text-align: center;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              transform 0.45s var(--ease-feder), border-radius 0.45s var(--ease-feder);
}
/* Beim Drücken schnell hinein, federnd zurück (Basis-Transition oben). Die
   volle Liste wird wiederholt — gäbe man nur border-radius an, verlöre der
   Knopf beim Drücken alle übrigen Übergänge. */
.btn:active {
  border-radius: 10px;
  transition: transform 0.1s var(--ease-standard), border-radius 0.1s var(--ease-standard),
              background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.btn--lg { padding: 1rem 2rem; font-size: 1.0625rem; }
.btn--lg:active { border-radius: 14px; }

.btn--primary { background: var(--signal); color: var(--auf-knopf); border-color: var(--signal); }
/* Abdunkeln beim Hover: mit weißer Schrift verbessert das den Kontrast sogar
   (3,42:1 → 4,34:1 auf #E13A2C). Wert aus der Hauptseite übernommen. */
.btn--primary:hover {
  background: #E13A2C; border-color: #E13A2C;
  transform: translateY(-1px); box-shadow: var(--schatten-sm);
}

.btn--secondary { background: var(--tinte); color: var(--auf-knopf); border-color: var(--tinte); }
/* Beim Überfahren eine Stufe dunkler — in der Navy-Familie, nicht Schwarz. */
.btn--secondary:hover { background: #05050F; border-color: #05050F; transform: translateY(-1px); }

.btn--outline-light { background: transparent; color: var(--weiss); border-color: rgba(255, 255, 255, 0.6); }
.btn--outline-light:hover { background: var(--weiss); color: var(--tinte); border-color: var(--weiss); }

/* Trägt den Namen der Vorlage, weil mailchimp-popup.js ihn fest ins Markup
   schreibt („Zurück"), ist hier aber KEIN Umriss-Knopf: auf dem hellen
   Dialoggrund wäre weiße Schrift unlesbar, und weiße Knopfschrift ist
   Kundenwunsch. Grau gefüllt hält den Knopf trotzdem klar zweitrangig. */
.btn--outline { background: var(--tinte-weich); color: var(--auf-knopf); border-color: var(--tinte-weich); }
.btn--outline:hover { background: var(--tinte); border-color: var(--tinte); }

.btn[disabled] { opacity: 0.6; cursor: default; }

/* Press-Feedback auf scale, NICHT auf border-radius: die Pille liegt bei
   999px, optisch gekappt wird sie aber schon bei halber Knopfhöhe. Der
   Overshoot des Springs landete dort in einem unsichtbaren Bereich.
   Steht absichtlich NACH den :hover-Regeln der Varianten: gleiche
   Spezifität, also entscheidet die Reihenfolge — Drücken schlägt Hover. */
.btn:active { transform: scale(0.96); }

/* Ripple: negativer z-index liegt über dem Knopfhintergrund, aber unter der
   Beschriftung. */
.btn__ripple {
  position: absolute; z-index: -1; pointer-events: none;
  border-radius: var(--r-pille);
  transform: translate(-50%, -50%) scale(0);
  background: radial-gradient(closest-side, currentColor 65%, transparent 100%);
  animation: btn-ripple 450ms var(--ease-standard) forwards;
}
@keyframes btn-ripple {
  from { transform: translate(-50%, -50%) scale(0); opacity: 0.28; }
  to   { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}

.btn-reihe { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2.1rem; }


/* ==========================================================================
   Die Karte — Signaturbaustein
   --------------------------------------------------------------------------
   .karte ist der Container (container-type: inline-size), .karte__flaeche die
   eigentliche Karte. Jedes Innenmaß in cqi = Prozent der Kartenbreite, deshalb
   skaliert die Karte überall gleich, ohne zweiten Regelsatz.
   ========================================================================== */
.karte {
  container-type: inline-size;
  width: 100%;

  --karte-grund:  #2B303B;
  --karte-tinte:  #F5F5F2;
  --karte-hoch:   rgba(255, 255, 255, 0.3);   /* Prägelicht oben */
  --karte-tief:   rgba(0, 0, 0, 0.5);         /* Prägeschatten unten */
}

.karte__flaeche {
  position: relative;
  aspect-ratio: 1.586;                        /* ID-1: 85,60 / 53,98 */
  border-radius: 3.7cqi;                      /* 3,18 mm auf 85,60 mm */
  padding: 7cqi;
  display: flex; flex-direction: column;
  background: var(--karte-grund);
  color: var(--karte-tinte);
  box-shadow: var(--schatten-karte);
  overflow: hidden;
}

/* Laminatglanz. Statisch, nicht animiert: das ist Material, keine Deko. */
.karte__flaeche::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(107deg,
              transparent 26%,
              rgba(255, 255, 255, 0.17) 42%,
              rgba(255, 255, 255, 0.04) 51%,
              transparent 64%);
}

.karte__kopf {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 4cqi;
}
.karte__marke {
  font-family: var(--schrift-anzeige);
  font-weight: 800;
  font-size: 10cqi;
  line-height: 1;
  letter-spacing: -0.01em;
}
.karte__funk { width: 8.4cqi; height: auto; opacity: 0.88; }

.karte__chip { width: 15.5cqi; height: auto; margin-top: 6.5cqi; }

.karte__nr {
  margin-top: auto;
  font-family: var(--schrift-daten);
  /* Die 19 Zeichen müssen in EINE Zeile zwischen die 7cqi-Ränder passen, also
     in 86cqi. Inters Tabellenziffern laufen schmaler als die frühere Fira Mono:
     gemessen 6,6cqi Schriftgröße → 72cqi Textbreite, rund 16 % Luft.
     Tabellenziffern, damit die Vierergruppen wie auf einer echten Karte auf
     gleicher Breite stehen; Inter setzt sonst proportionale Ziffern. */
  font-size: 6.6cqi;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  line-height: 1;
  /* Prägung: Licht von oben, Schatten nach unten — wie auf einer echten Karte. */
  text-shadow: 0 0.35cqi 0 var(--karte-hoch), 0 -0.35cqi 0 var(--karte-tief);
}

.karte__fuss {
  margin-top: 3.6cqi;
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 3cqi;
  font-family: var(--schrift-daten);
  font-size: 3.4cqi;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.7;
}

/* --- Kartenvarianten. Musterdarstellungen: die Farbflächen stammen aus dem
       ÖPNV-Umfeld, nicht aus den Hausfarben der Verkehrsunternehmen. Echte
       Kartenmotive werden hier bewusst nicht nachgebaut.

       DERZEIT UNGENUTZT: Seit alle fünf Projekte ihr Originalmotiv haben,
       läuft jede Karte der Seite über .karte--bild. Die gezeichnete
       Musterkarte (.karte__flaeche und die drei Farbvarianten hier) bleibt
       trotzdem stehen — sie ist der dokumentierte Platzhalter für ein neues
       Projekt, dessen Motiv noch nicht vorliegt, siehe
       assets/karten/LIESMICH.md. Wird sie dauerhaft nicht gebraucht, kann
       der ganze Block samt #i-wave im Sprite entfallen. --- */
.karte--gruen {
  --karte-grund: linear-gradient(152deg, #14663F 0%, #0B4A2F 56%, #073821 100%);
  --karte-tinte: #F3F7F3;
}
.karte--gelb {
  --karte-grund: linear-gradient(152deg, #FFD94E 0%, #FFC800 54%, #E7A600 100%);
  --karte-tinte: #1A1508;
  --karte-hoch:  rgba(255, 255, 255, 0.55);
  --karte-tief:  rgba(0, 0, 0, 0.3);
}
.karte--blau {
  --karte-grund: linear-gradient(152deg, #2A4E8F 0%, #1B3363 56%, #12224A 100%);
  --karte-tinte: #EEF2F9;
}

/* Bildkarte: liegt ein Originalmotiv vor (bislang nur RVV), ersetzt es die
   gezeichnete Musterkarte. Kein Laminatglanz und keine Prägung — auf echtem
   Artwork wäre beides ein aufgesetzter Effekt.
   Die Schraffur im Hintergrund ist der Platzhalter, falls die Datei fehlt:
   dieselbe Sprache wie .todo, damit „unfertig" überall gleich aussieht. */
.karte--bild .karte__bild {
  display: block;
  width: 100%;
  aspect-ratio: 1.586;
  object-fit: cover;
  border-radius: 3.7cqi;
  box-shadow: var(--schatten-karte);
  background:
    repeating-linear-gradient(45deg,
      rgba(22, 24, 29, 0.05) 0 7px, transparent 7px 14px),
    var(--bogen-tief);
  color: var(--tinte-weich);
  font-family: var(--schrift-daten);
  font-size: 0.75rem;
}


/* ==========================================================================
   TEXTUR (Feedback 2026-09-07)
   --------------------------------------------------------------------------
   Rückmeldung war, die Seite sehe aus „wie ein Word-Dokument mit ein paar
   Linien". Der Grund: durchgehend reine, flache Flächen. Zwei Mittel dagegen,
   beide bewusst an der Wahrnehmungsschwelle:

   1. Eine feine Körnung über der ganzen Seite. Ein 200 × 200 großes
      feTurbulence-Feld als data-URI, gekachelt, bei 3,5 % Deckkraft.
      Kurzzeitig auf 5 % erhöht, am 2026-09-08 zurückgenommen: sichtbares
      Rauschen auf Weiß liest sich als Schmutz, nicht als Textur.
   2. Verläufe innerhalb der farbigen Flächen (.ablauf, .absender,
      .whitepaper, .fuss). Nicht auf Weiß — dort bändern sie.

   Die Körnung liegt fix über allem, ist nicht anklickbar und wird bei
   „weniger Bewegung" nicht abgeschaltet — sie bewegt sich nicht.
   ========================================================================== */
/* Nur für Screenreader. Die Tabellenüberschrift (caption) steht im Markup,
   weil sie beim Vorlesen sagt, worum es in der Tabelle geht; auf dem Schirm
   sagt das die Überschrift darüber schon. Nicht display: none — das nähme sie
   auch der Vorlesesoftware. */
.nur-vorlesen {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='k'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23k)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}


/* ==========================================================================
   KEINE FLÄCHIGEN VERLÄUFE AUF WEISS (2026-09-08)
   --------------------------------------------------------------------------
   Hier lagen für ein paar Stunden Lichtkegel über die ganze helle Bahn
   (main::before mit z-index: -1). Wieder entfernt, Rückmeldung: „sieht extrem
   unsauber aus". Der Grund ist rechnerisch:

   Ein Kegel über rund 500 px, der nur etwa 30 Helligkeitsstufen durchläuft,
   wechselt auf 8-Bit-Schirmen im Schnitt alle 17 px die Stufe. Das sind
   sichtbare Streifen — Banding. Je flacher und heller der Verlauf, desto
   schlimmer; auf Weiß ist es am schlimmsten. Auch die dunklen Flächen haben
   deshalb ihre aufgesetzten hellen Radialverläufe wieder verloren.

   Verläufe gibt es weiter, aber nur INNERHALB der farbigen Flächen
   (.ablauf, .absender, .whitepaper, .fuss), wo sie über wenige Stufen laufen
   und nicht auffallen. Textur macht auf dieser Seite die Körnung und die
   Wellen, nicht der Verlauf.
   ========================================================================== */

/* Die Fragen liegen auf einer glatten Fläche in --bogen-tief. Zwischendurch
   waren die Enden ausgeblendet, damit keine Kante entsteht — auf Wunsch wieder
   raus (2026-09-08): die Blende war als Schmier sichtbar, die saubere Kante
   ist das kleinere Übel. Ein Panel darf sich absetzen. */
.fragen { background: var(--flaeche); }

/* ==========================================================================
   WELLEN (Feedback 2026-09-07)
   --------------------------------------------------------------------------
   Zwei Formen, beide als data-URI. Sie liegen als Maske auf einem
   Pseudoelement, das die Farbe der jeweiligen Sektion trägt: dadurch braucht
   es keine zweite Datei und keine feste Farbe im SVG.

   Am 2026-09-08 gab es zwei Versuche, den Übergang weicher zu machen: erst
   ein senkrechter Farbverlauf im Wellenband, dann drei gestaffelte Lagen
   unterschiedlicher Deckkraft. Beide sind wieder raus, ausdrücklich gewünscht
   ist die einfache Form: EIN Bogen, eine Farbe, keine Weichzeichnung.

   Was aus den Versuchen bleibt, ist die Farbwahl. --welle-farbe muss die
   Farbe der Sektion AN DIESER KANTE sein, in die die Welle hineinführt, nicht
   deren Grundton. Ablauf und 402PAYMENT sind selbst senkrechte Verläufe; ein
   Griff zu --halt-gelb bzw. --navy trifft deren Mitte und hinterlässt an der
   Naht eine sichtbare Linie. Deshalb steht die Farbe pro Pseudoelement.

   Sparsam eingesetzt: die gelbe Ablauf-Fläche und der Übergang in den dunklen
   402PAYMENT-Teil. Jede weitere Welle hätte die Seite unruhig gemacht.

   --welle-hoch  = Kamm oben, für eine Fläche, die nach oben in die helle
                   Sektion hineinragt.
   --welle-tief  = gespiegelt, für die Unterkante einer farbigen Fläche.
   ========================================================================== */
:root {
  --welle-hoch: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 100' preserveAspectRatio='none'%3E%3Cpath d='M0,64 C240,6 480,6 720,44 C960,82 1200,82 1440,30 L1440,100 L0,100 Z' fill='%23000'/%3E%3C/svg%3E");
  --welle-tief: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 100' preserveAspectRatio='none'%3E%3Cpath d='M0,36 C240,94 480,94 720,56 C960,18 1200,18 1440,70 L1440,0 L0,0 Z' fill='%23000'/%3E%3C/svg%3E");
  --welle-hoehe: clamp(1.75rem, 4vw, 3.75rem);
}

/* Gemeinsames Gerüst. Die Farbe setzt die jeweilige Sektion über
   --welle-farbe, die Form über --welle-form. */
.welle-oben, .welle-unten { position: relative; }
.welle-oben::before,
.welle-unten::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: var(--welle-hoehe);
  background: var(--welle-farbe);
  pointer-events: none;
  -webkit-mask: var(--welle-form) no-repeat center / 100% 100%;
  mask: var(--welle-form) no-repeat center / 100% 100%;
}
.welle-oben::before { bottom: 100%; --welle-form: var(--welle-hoch); }
.welle-unten::after  { top: 100%;    --welle-form: var(--welle-tief); }

/* Die Wellen liegen AUSSERHALB des Kastens (bottom:100% bzw. top:100%) und
   ragen damit in die Nachbarsektion. Ohne diesen Abstand legen sie sich über
   deren letzte Textzeile. Der Rand reserviert genau die Wellenhöhe. */
.welle-oben  { margin-top: var(--welle-hoehe); }
.welle-unten { margin-bottom: var(--welle-hoehe); }

/* Die gelbe Ablauf-Fläche ragt oben und unten in die weißen Nachbarn. Die
   Werte sind die Enden ihres eigenen Verlaufs, nicht --halt-gelb. */
.ablauf::before { --welle-farbe: var(--navy); }
.ablauf::after  { --welle-farbe: #15153A; }
/* Der dunkle Teil beginnt mit einer Welle statt einer Kante. #12122E ist der
   obere Anfang seines Verlaufs. */
.absender::before { --welle-farbe: #12122E; }

/* ==========================================================================
   NAV
   ========================================================================== */
/* Deckend, nicht durchscheinend (Kundenwunsch 2026-08-24): kein
   backdrop-filter, volle Deckkraft. Über der gelben Ablauf-Fläche und dem
   dunklen 402PAYMENT-Ende schiebt sich die Leiste damit sauber drüber, statt
   die Farbe dahinter durchschimmern zu lassen. */
/* Leiste über die volle Breite (2026-09-07). Löst die kurzzeitig schwebende
   Pille wieder ab; die Kante von links nach rechts war ausdrücklich gewünscht.

   Sie versteckt sich beim Herunterscrollen und kommt beim Hochscrollen zurück
   (nav.js setzt .nav--weg). Statt einer grauen Linie liegt erst dann ein
   Schatten unter ihr, wenn die Seite tatsächlich gescrollt ist — im Ruhezustand
   bleibt der Übergang zum Hero unsichtbar. */
.nav {
  position: sticky;
  top: 0;
  z-index: 900;
  background: rgba(255, 255, 255, 0.9);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
  backdrop-filter: saturate(1.6) blur(14px);
  transition: transform 0.28s var(--aus), box-shadow 0.2s ease;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav { background: var(--weiss); }
}
.nav--gescrollt {
  box-shadow: 0 1px 0 rgba(22, 24, 29, 0.06),
              0 10px 26px -18px rgba(22, 24, 29, 0.4);
}
/* Ausgefahren nach oben. translateY(-101%) statt -100%: bei gebrochenen
   Gerätepixeln bleibt sonst eine Haarlinie stehen. */
.nav--weg { transform: translateY(-101%); }
.nav--ohne-uebergang { transition: none; }

.nav__innen {
  display: flex; align-items: center; gap: 1rem;
  min-height: 4.25rem;
}

/* --- Burger. Über 1024 px unsichtbar. --- */
.nav__burger {
  display: none;
  margin-left: auto;
  width: var(--tipp); height: var(--tipp);
  align-items: center; justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  color: var(--tinte);
  transition: background-color 0.15s ease;
}
.nav__burger:hover { background: rgba(22, 24, 29, 0.055); }
.nav__burger-kasten {
  position: relative;
  display: block;
  width: 20px; height: 14px;
}
.nav__burger-strich {
  position: absolute;
  left: 0; right: 0;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.22s var(--aus), opacity 0.15s ease;
}
.nav__burger-strich:nth-child(1) { top: 0; }
.nav__burger-strich:nth-child(2) { top: 6px; }
.nav__burger-strich:nth-child(3) { top: 12px; }
/* Zum Kreuz: der mittlere Strich verschwindet, die äußeren drehen sich in
   die Mitte. */
.nav--offen .nav__burger-strich:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav--offen .nav__burger-strich:nth-child(2) { opacity: 0; }
.nav--offen .nav__burger-strich:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.nav__menue { display: contents; }

/* ==========================================================================
   NAVIGATION BIS 1024 px — Burger und Klappmenü (2026-09-07)
   --------------------------------------------------------------------------
   Bis hierher lagen Sprungmarken und Knopf als seitlich schiebbare Reihe in
   der Leiste. Auf Tablet-Breite war das eine unbeschriftete Scrollfläche, in
   der die Hälfte der Ziele unsichtbar blieb.

   Die Klasse "js" auf <html> setzt eine Inline-Zeile im Kopf von index.html,
   also vor dem ersten Zeichnen. Ohne JavaScript greift keine dieser Regeln:
   der Burger bleibt unsichtbar, das Menü bleibt offen und in der Leiste
   sichtbar. Es geht also nichts verloren.
   ========================================================================== */
@media (max-width: 1024px) {
  .js .nav__burger { display: inline-flex; }

  .js .nav__menue {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.25rem;

    position: absolute;
    left: 0; right: 0;
    top: 100%;
    padding: 0.75rem var(--rand) 1.25rem;
    background: var(--weiss);
    box-shadow: 0 1px 0 rgba(22, 24, 29, 0.06),
                0 18px 32px -20px rgba(22, 24, 29, 0.45);

    /* Eingeklappt: unsichtbar, nicht anklickbar, nicht in der Tabulatorfolge.
       visibility statt display, damit der Übergang läuft. */
    opacity: 0;
    visibility: hidden;
    transform: translateY(-0.5rem);
    transition: opacity 0.18s ease, transform 0.18s var(--aus), visibility 0.18s;
  }
  .js .nav.nav--offen .nav__menue {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  /* Die Leiste wird zum Bezugsrahmen für das Menü darunter. */
  .nav { position: sticky; }
  .nav__innen { position: relative; }

  .js .nav__marken {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-left: 0;
  }
  .js .nav__marken a {
    padding: 0.85rem 0.75rem;
    border-radius: var(--r-flaeche);
    font-size: 1.0625rem;
  }
  .js .nav__cta {
    margin-top: 0.75rem;
    justify-content: center;
    width: 100%;
  }
}

/* Über 1024 px gibt es kein Menü als eigenes Element: display: contents löst
   den Zwischen-<div> auf, damit Marken und Knopf direkt in der Flex-Zeile der
   Leiste liegen. Steht hier, damit es die Regeln oben überschreibt. */
@media (min-width: 1025px) {
  .nav__menue { display: contents; }
  .nav__burger { display: none; }
}

/* Wortmarke der Seite. Kein Bild, sondern gesetzte Schrift — sie skaliert
   mit, bleibt bei Textzoom scharf und braucht keine zweite Datei. */
.nav__wortmarke {
  font-family: var(--schrift-anzeige);
  font-weight: 800;
  font-size: clamp(0.98rem, 0.88rem + 0.42vw, 1.22rem);
  letter-spacing: -0.02em;
  color: var(--tinte);
  white-space: nowrap;
}
.nav__tld { font-weight: 600; color: var(--tinte-weich); }
.nav__wortmarke:hover .nav__tld { color: var(--tinte); }

/* Sprungmarken zu den Abschnitten (Feedback 2026-09-07). Weiterhin kein
   Burger-Menü: unter 900 px schiebt sich die Reihe seitlich, statt sich hinter
   einem Symbol zu verstecken. Ein Menü, das man erst öffnen muss, hätte auf
   einer Seite mit sechs Abschnitten mehr Klicks gekostet als gespart. */
.nav__marken {
  display: flex;
  align-items: center;
  gap: clamp(0.15rem, 0.8vw, 0.5rem);
  margin-left: auto;
  min-width: 0;
}
.nav__marken::-webkit-scrollbar { display: none; }
/* Gemischte Schreibung statt gesperrter Versalien: in der Pille wirkten die
   Kapitälchen wie eine zweite Überschriftenebene. Der Hover unterlegt jetzt
   eine weiche Fläche, statt eine Linie darunter zu ziehen. */
.nav__marken a {
  flex: none;
  font-size: 0.9375rem;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--tinte-weich);
  white-space: nowrap;
  padding: 0.45rem 0.7rem;
  border-radius: 999px;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.nav__marken a:hover { color: var(--tinte); background: rgba(22, 24, 29, 0.055); }

.nav__cta { flex: none; padding: 0.6rem 1.2rem; font-size: 0.9375rem; }


/* ==========================================================================
   HERO
   ========================================================================== */
/* Die frühere Welle am Fuß des Heros ist raus (Feedback 2026-09-07): eine
   harte, hellgraue Kante quer durch den Hero, die eher nach Trennlinie aussah
   als nach Hintergrund.

   Stattdessen weite Lichtkegel: einer hinter dem Kartenfächer rechts oben,
   einer links unten, dazu ein warmer Schimmer in der Mitte. Alle laufen auf
   transparent aus, es gibt also keine sichtbare Kante. Als background-image
   statt Pseudoelement, damit kein Stapelkontext entsteht, der mit dem Fächer
   ins Gehege kommt.

   2026-09-08 deutlich verstärkt (Rückmeldung: Verläufe zu schwach). Die Werte
   liegen jetzt über der Wahrnehmungsschwelle: der grüne Kegel nimmt dem Weiß
   rund vier Helligkeitsstufen statt einer. */
/* Die Kegel des Heros liegen seit 2026-09-08 in der gemeinsamen Ebene von
   <main> (siehe Block VERLÄUFE). Vorher endeten sie an der Unterkante des
   Heros und zogen dort eine Linie. */
.hero { padding-block: clamp(3rem, 6.5vw, 6rem) var(--luft); }

/* Drei Blöcke in einem Raster: Überschrift (kopf), Karten (bild), Fließtext
   und Knöpfe (fuss). Auf breiten Schirmen liegt „bild" rechts über beide
   Zeilen — optisch identisch zum früheren Zweispalter. Unter 700 px wird das
   Raster umgeschichtet, damit die Karten oben neben der Überschrift bleiben
   (siehe Breakpoint). Genau dafür sind es benannte Bereiche statt zweier
   getrennter Layouts. */
.hero__raster {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  grid-template-areas:
    "kopf bild"
    "fuss bild";
  gap: 0 clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}
.hero__kopf { grid-area: kopf; }
.hero__fuss { grid-area: fuss; }
.hero__bild { grid-area: bild; align-self: center; }

.hero__zeile {
  margin-top: 1.1rem;
  font-size: var(--fs-hero);
  letter-spacing: -0.025em;
}
.hero__lead { margin-top: 1.5rem; font-size: var(--fs-lead); line-height: 1.58; color: var(--tinte-weich); max-width: 34rem; }

/* --- Der Kartenfächer --- */
.faecher {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 0.8;
}
/* Zwei Kreise hinter den Karten (2026-09-09). Versetzt statt zentriert, damit
   sie nicht als Teller unter dem Fächer liegen, sondern als Flächen dahinter
   hervorschauen. Der zweite ist über Tokens einstellbar, siehe unten.

   Sitzt an .faecher und nicht an .hero__bild: der Zwischen-<div> wird unter
   700 px zu display: contents, und ein Pseudoelement daran würde dort
   verschwinden.

   Die Ebene regelt z-index, siehe unten: solange nur ein Kreis vor den
   Karten im DOM stand, ging es ohne — mit dem zweiten, der danach kommt,
   nicht mehr. */
.faecher::before,
.faecher::after {
  content: "";
  position: absolute;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--flaeche);
  /* Die Kartenplätze tragen z-index 1 bis 3 — mit 0 liegen beide Kreise
     darunter, unabhängig davon, wo sie im DOM stehen. Ohne diese Zeile läge
     das ::after über den Karten, weil es nach ihnen kommt. */
  z-index: 0;
}

/* Erster Kreis: fest gesetzt. */
.faecher::before {
  left: 13%;
  top: -14%;
  width: 95%;
}

/* Zweiter Kreis: über Tokens gesetzt, damit ihn das Werkzeug (kreis.js,
   Aufruf mit  ?kreis ) verschieben und in der Größe ändern kann. Die Werte
   hier sind der Auslieferungsstand; das Werkzeug überschreibt sie nur in der
   Ansicht.

   --kreis2-an ist die Deckkraft und damit zugleich der Schalter: 0 blendet
   den Kreis aus, ohne dass sich am Aufbau etwas ändert. */
.faecher::after {
  left:  var(--kreis2-x, 5%);
  top:   var(--kreis2-y, 50%);
  width: var(--kreis2-groesse, 45%);
  opacity: var(--kreis2-an, 1);
}

.faecher__platz {
  position: absolute;
  left: var(--l); top: var(--t);
  width: 64%;
  transform: rotate(var(--r));
  animation: austeilen 0.72s var(--aus) backwards;
  animation-delay: calc(var(--i) * 0.11s + 0.15s);
}
/* Der Fächer steigt nach rechts oben, vorne liegt die erste Karte, hinten der
   Rohling. Beide Richtungen zusammen sind der Punkt: so bleibt die vordere
   Karte ganz sichtbar UND die Markennamen der beiden hinteren, weil deren
   obere linke Ecke über der Oberkante der Vorderkarte liegt. Andersherum
   verdeckt ausgerechnet die leere Karte die beiden benannten Projekte. */
.faecher__platz:nth-child(1) { --l: 0%;  --t: 34%; --r: -8deg; --i: 0; z-index: 3; }
.faecher__platz:nth-child(2) { --l: 18%; --t: 17%; --r: 1deg;  --i: 1; z-index: 2; }
.faecher__platz:nth-child(3) { --l: 36%; --t: 0%;  --r: 9deg;  --i: 2; z-index: 1; }
@keyframes austeilen {
  from { opacity: 0; transform: translate(-5%, 15%) rotate(0deg) scale(0.94); }
}

.bildnachweis {
  margin-top: 1.4rem;
  font-family: var(--schrift-daten);
  font-size: 0.72rem;
  line-height: 1.55;
  letter-spacing: 0.02em;
  color: var(--tinte-weich);
  max-width: 30rem;
}


/* ==========================================================================
   GRUNDLAGE
   ========================================================================== */
/* Kein Trennstrich mehr (Feedback 2026-09-07). Die Sektionen trennen sich
   über Abstand, Farbe und Wellen; die Haarlinien wirkten daneben wie in ein
   Textdokument gezogene Striche. Erhalten bleibt genau einer: vor
   „Beteiligte", wo sonst gar keine Kante wäre. */
/* Getönte Fläche (2026-09-09): der Abschnitt stand vorher auf weißem Papier
   zwischen zwei weiteren weißen und war als eigener Teil kaum zu erkennen. */
.grundlage { background: var(--flaeche); }

.merkmale {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}
.merkmal { border-top: 2px solid var(--tinte); padding-top: 1.1rem; }
.merkmal p { margin-top: 0.6rem; color: var(--tinte-weich); font-size: var(--fs-klein); }


/* ==========================================================================
   EINORDNUNG — Open Loop neben Closed Loop als Tabelle
   --------------------------------------------------------------------------
   Bis 2026-09-08 stand hier ein Liniendiagramm: zwei Netzplan-Strecken mit
   denselben Halten, samt Schiene, Punkten und grauem Zulauf für den
   gemeinsamen Teil. Die Form war hübsch, aber sie hat den Vergleich eher
   illustriert als gezeigt — gefragt war „eher eine simple Tabelle", und das
   ist hier auch die ehrlichere Form: vier Merkmale, zwei Modelle.

   Der Gewinn liegt nicht nur im Aussehen. Die Zeilenbindung stellt jetzt die
   Tabelle selbst her; vorher standen die beiden Listen nur zufällig auf
   gleicher Höhe und liefen bei unterschiedlich langen Texten auseinander.
   ========================================================================== */
.einordnung { }

/* Der gemeinsame Kopf. Der Chip sitzt auf einer weißen Scheibe, damit das
   Goldmotiv nicht auf der Tönung klebt. */
.gemeinsam {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 1.6rem);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding: clamp(1.1rem, 2.5vw, 1.5rem) clamp(1.1rem, 3vw, 1.75rem);
  border: 1px solid var(--linie);
  border-radius: var(--r-flaeche);
  background: var(--bogen-tief);
}
/* Chip und Kontaktlossymbol nebeneinander (Feedback 2026-09-07): genau diese
   beiden Dinge sind in beiden Wegen dieselben, deshalb stehen sie zusammen im
   gemeinsamen Block. Aus dem Kreis wird dadurch eine Pille. */
.gemeinsam__scheibe {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.55rem;
  min-width: clamp(3.2rem, 7vw, 4rem);
  height: clamp(3.2rem, 7vw, 4rem);
  padding-inline: clamp(0.7rem, 1.6vw, 0.95rem);
  border-radius: 999px;
  background: var(--weiss);
  box-shadow: var(--schatten-sm);
}
.gemeinsam__chip { width: clamp(1.5rem, 3.2vw, 1.9rem); height: auto; }
.gemeinsam__funk {
  width: clamp(0.95rem, 2vw, 1.2rem);
  height: auto;
  color: var(--tinte);
}
.gemeinsam__titel { font-size: var(--fs-h3); font-weight: 700; }
.gemeinsam__text p + p {
  margin-top: 0.35rem;
  max-width: var(--lesbar);
  font-size: var(--fs-klein);
  color: var(--tinte-weich);
}

/* Look nach der gelieferten Compare-Vorlage (2026-09-08). Wieder nur der
   Look: die Vorlage ist React mit Tailwind und einem Icon-Paket aus npm, die
   Seite bleibt statisch und ohne Build — dieselbe Entscheidung wie beim
   Fragen-Akkordeon.

   Übernommen ist: zwei gleich breite Tafeln nebeneinander, die rechte auf
   getöntem Grund abgesetzt, mittige Überschriften je Tafel, viel Luft und vor
   jeder Angabe eine runde Plakette mit Haken.

   Nicht übernommen ist die Struktur. Die Vorlage stellt zwei voneinander
   unabhängige Listen nebeneinander; hier gehören die Angaben paarweise
   zusammen (Kartenherausgeber links wie rechts, dann Deckung und so weiter).
   Deshalb bleibt es eine <table>: sie hält die Paare auf einer Zeile, auch
   wenn ein Text umbricht, und Vorlesesoftware nennt zu jeder Zelle das
   Merkmal und das Modell. Die Merkmalsspalte steht links außerhalb beider
   Tafeln — dadurch steht jede Beschriftung einmal statt zweimal.

   border-collapse: separate, weil die getönte Tafel oben und unten runde
   Ecken bekommt; mit collapse ignorieren Zellen border-radius. */
.vergleich-rahmen {
  margin-top: clamp(2rem, 4vw, 3rem);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.vergleich {
  width: 100%;
  min-width: 42rem;
  border-collapse: separate;
  border-spacing: 0;
  text-align: left;
}
.vergleich__ecke { width: 9.5rem; }
.vergleich thead th { width: calc((100% - 9.5rem) / 2); }

/* Die Luft der Vorlage (px-6 py-20) auf die Seitenmaße heruntergerechnet. */
.vergleich :where(th, td) {
  padding: 1.15rem clamp(1.1rem, 2.2vw, 1.6rem);
  vertical-align: top;
}
.vergleich tbody th { padding-left: 0; }

/* --- Die beiden Tafeln --- */
/* Die rechte Spalte trägt den Ton durchgehend; die Ecken sitzen an der
   ersten und letzten Zelle, damit daraus eine Tafel wird und nicht vier
   gestapelte Kästchen. */
.vergleich__zu { background: var(--bogen-tief); }
.vergleich__zu--erste { border-radius: var(--r-flaeche) var(--r-flaeche) 0 0; }
.vergleich__zu--letzte { border-radius: 0 0 var(--r-flaeche) var(--r-flaeche); }

/* --- Kopfzeile --- */
.vergleich__kopf {
  --weg-farbe: var(--tinte);
  padding-top: clamp(1.75rem, 3.5vw, 2.75rem);
  padding-bottom: clamp(1.5rem, 3vw, 2.25rem);
  text-align: center;
  font-family: var(--schrift-anzeige);
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
}
.vergleich__kopf.vergleich__zu { --weg-farbe: var(--halt-gruen); }

.vergleich__marke {
  display: block;
  margin-bottom: 0.5rem;
  font-family: var(--schrift-daten);
  font-size: var(--fs-marke);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--weg-farbe);
}

/* --- Zeilen --- */
.vergleich tbody th {
  font-family: var(--schrift-daten);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tinte-weich);
  padding-top: 1.45rem;
}
.vergleich tbody td { font-size: var(--fs-klein); }

/* Plakette und Text nebeneinander. Als Flex-Zeile INNERHALB der Zelle, nicht
   als display: flex auf dem <td> selbst — das nähme der Zelle ihr
   Tabellenverhalten und die Spaltenbreiten liefen auseinander.

   Zuerst standen die beiden Spans nur nebeneinander im Textfluss. Das ist
   umgebrochen: der Zeilenumbruch im Quelltext wird zu einem Leerzeichen,
   und Plakette plus Abstand plus Leerzeichen plus Text kamen zusammen auf
   etwas mehr als die Zellbreite. Flex hat dieses Problem nicht. */
.vergleich__zeile {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
}

/* Haarlinien nur innerhalb der Tafeln, nicht quer über die Merkmalsspalte —
   sonst zerschneiden sie die Tafel, die als Fläche wirken soll. Die zweite
   Regel greift über die Gruppengrenze hinweg: die erste Unterschiedszeile
   braucht ihre Linie genauso, obwohl sie in einem eigenen tbody steht. */
.vergleich tbody tr + tr td,
.vergleich tbody + tbody tr:first-child td { border-top: 1px solid var(--linie); }
.vergleich tbody tr + tr .vergleich__zu,
.vergleich tbody + tbody tr:first-child .vergleich__zu { border-top-color: rgba(22, 24, 29, 0.09); }

/* ---------- Übereinstimmungen ---------- */
/* Eine Zelle über beide Tafeln. Sie trägt denselben Ton wie die rechte Tafel,
   sodass daraus EINE zusammenhängende getönte Form wird: oben die volle
   Breite, darunter nur noch die rechte Spalte. Die Form selbst sagt damit,
   wo die Wege noch deckungsgleich sind und ab wo nicht mehr.

   Gerundet wird nur links: rechts stößt die Zelle an die Kopfzeile darüber
   und die Unterschiedszeilen darunter, dort darf keine Kerbe entstehen. */
.vergleich__beide { background: var(--bogen-tief); }
.vergleich__gleich tr:first-child .vergleich__beide { border-top-left-radius: var(--r-flaeche); }
.vergleich__gleich tr:last-child .vergleich__beide { border-bottom-left-radius: var(--r-flaeche); }


/* --- Marken vor den Zellen --- */
/* Die Vorlage setzt hier eine gefüllte Plakette mit Haken (bg-primary +
   text-primary-foreground). Übernommen war das anfangs eins zu eins, ist aber
   am 2026-09-08 ersetzt worden: ein Haken bewertet ("gut, hat es"), und
   zwölfmal eine gefüllte schwarze Scheibe hat die Tabelle zugedeckt. Links wie
   rechts steht aber eine neutrale Tatsache, kein Vorteil.

   Unterschiedszeilen tragen jetzt den hohlen Haltestellenpunkt aus dem
   früheren Liniendiagramm dieses Abschnitts — dieselbe Bildsprache, nur ohne
   die Schiene. Die Farbe des Modells steckt im Ring, nicht mehr in einer
   Füllung; die Tabelle wird dadurch deutlich ruhiger.

   Gemeinsame Zeilen tragen ein Gleichheitszeichen auf grauem Grund. Als
   einzige gefüllte Marke sind sie das Schwerste in der Tabelle — richtig so,
   denn „Zwei Wege, ein Chip" ist die Aussage des Abschnitts. */
.vergleich__zeichen {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 1.15rem; height: 1.15rem;
  /* Auf die erste Textzeile ausgerichtet, nicht auf die Mitte des ganzen
     Absatzes: bei drei Zeilen Text säße die Marke sonst mittig daneben. */
  margin-top: 0.12rem;
  border-radius: 999px;
  color: var(--tinte);
}
.vergleich__zeichen svg { width: 100%; height: 100%; }
.vergleich__zu .vergleich__zeichen { color: var(--halt-gruen); }
/* Neutral, weil die Angabe für beide Wege gilt und keinem der beiden gehört.
   Muss NACH .vergleich__zeichen stehen: gleiche Spezifität, es entscheidet die
   Reihenfolge. Die Regel stand einmal weiter oben und wurde überschrieben. */
.vergleich__zeichen--beide {
  background: var(--tinte-weich);
  color: var(--weiss);
}
.vergleich__zeichen--beide svg { width: 0.8rem; height: 0.8rem; }

/* Am Handy fällt die Merkmalsspalte weg (Wunsch 2026-09-09). Damit passen
   die beiden Spalten nebeneinander auf den Schirm, und es muss überhaupt
   nicht mehr geschoben werden — vorher waren bei 375 px Fensterbreite 240 px
   der Tabelle außerhalb des Rahmens, darunter die ganze rechte Spalte.

   Der Umbruch liegt bei 760 px, also dort, wo die vollständige Tabelle nicht
   mehr in den Rahmen passt (42 rem = 672 px plus Seitenrand und Rollbalken),
   und zugleich dort, wo der Projektblock zweispaltig wird.

   Sie fällt nur optisch weg. Für Vorlesesoftware bleibt sie stehen: die
   Zeilenbeschriftung ist das, was jede Zelle zu einer Aussage über etwas
   macht, und ohne sie wäre die Tabelle für alle unbrauchbar, die sie sich
   vorlesen lassen. Dasselbe Muster wie .nur-vorlesen — aus dem Fluss
   genommen, aber nicht aus dem Dokument.

   Was bleibt: table-layout: fixed, sonst bestimmt das längste Wort die
   Spaltenbreite („Kartenkontoverwaltungssystem" hielt sie auf 265 px), dazu
   Silbentrennung und min-width: 0 am Textspan, der als Flex-Kind sonst nicht
   unter sein längstes Wort schrumpft. */
@media (max-width: 760px) {
  .vergleich { min-width: 0; table-layout: fixed; }
  .vergleich thead th { width: 50%; }

  .vergleich__ecke,
  .vergleich tbody th {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  .vergleich :where(th, td) { hyphens: auto; overflow-wrap: break-word; }
  .vergleich td { padding: 1rem 0.85rem; }
  .vergleich__zeile > span { min-width: 0; }
}

@media (max-width: 480px) {
  .vergleich td { padding: 0.9rem 0.7rem; }
  .vergleich__zeile { gap: 0.5rem; }
}

.vergleich__fuss {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  max-width: var(--lesbar);
  font-size: var(--fs-klein);
  color: var(--tinte-weich);
}

/* ==========================================================================
   ABLAUF — der eine laute Abschnitt
   ========================================================================== */
.ablauf {
  /* Navy statt Haltestellengelb (Kollegenfeedback 2026-09-11, „Farbe
     anpassen, einbinden": die Infografik kennt nur Navy, Koralle und helles
     Blaugrau, der gelbe Abschnitt war der einzige auf der Seite). Derselbe
     leichte Verlauf wie beim Absender unten, nur andersherum: oben das reine
     Navy, unten eine Spur heller — so hat die Fläche eine Richtung, ohne dass
     ein Verlauf auffällt. Der Abschnitt bleibt der laute in der oberen
     Seitenhälfte, jetzt in Markenfarbe. */
  background: linear-gradient(178deg, var(--navy) 0%, #10102A 46%, #15153A 100%);
  color: var(--weiss);
}
.ablauf h2 { font-size: var(--fs-h2); margin-top: 0.9rem; }

.schritte {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(1.75rem, 3.5vw, 3rem);
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
/* Rahmen statt Oberlinie (2026-09-11): sehr leicht, er trennt nur. Die
   Oberlinie in Tintenstärke hatte drei Kästen zu drei Überschriften gemacht.
   position und overflow für den Zeitbalken am unteren Rand. */
.schritt {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--r-flaeche);
  padding: 1.1rem 1.15rem 1.4rem;
  transition: opacity 0.6s var(--ease-glatt), border-color 0.6s var(--ease-glatt);
}
/* Die Dauer je Schritt steht hier, weil Keyframes und Script dieselbe Zahl
   brauchen: ablauf.js liest sie aus. */
.schritt:nth-child(1) { --dauer: 4.2s; }
.schritt:nth-child(2) { --dauer: 3.8s; }
.schritt:nth-child(3) { --dauer: 4.8s; }

/* Nur mit Script: wer nicht dran ist, tritt zurück. Ausgegraut heißt hier
   Deckkraft, nicht Farbe — die Grünstufen der Bilder bleiben so, wie sie sind. */
.ablauf-bereit .schritt { opacity: 0.55; }
.ablauf-bereit .schritt.ist-aktiv { opacity: 1; border-color: rgba(255, 255, 255, 0.42); }

/* Zeitbalken: läuft am unteren Rand von links nach rechts über die Dauer
   des Schritts. Linear, weil er Zeit anzeigt — eine Kurve würde lügen. */
.schritt::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  background: var(--koralle);
  opacity: 0.9;
  transform: scaleX(0);
  transform-origin: left center;
}
.ablauf-bereit .schritt.ist-aktiv::after {
  animation: ablauf-zeit var(--dauer) linear forwards;
}
@keyframes ablauf-zeit { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* --- Die bewegten Strichbilder der drei Schritte (2026-09-10/11) ---
   Vorbild ist der Abschnitt „How does it work" auf ovpay.nl/ov-pas. Dort
   liegen vier Lottie-Animationen; hier sind es drei Inline-SVG mit
   CSS-Keyframes. Kein Script fürs Zeichnen, keine Datei, kein JSON.

   Seit 2026-09-11 spielt jede Szene EINMAL, wenn ihr Schritt dran ist
   (.ist-aktiv aus ablauf.js), und bleibt dann im fertigen Bild stehen. Der
   Ruhezustand ohne Klasse IST dieses fertige Bild — deshalb springt nichts,
   wenn die Klasse wieder fällt, und ohne Script steht dasselbe da.

   Gezeichnet wird in currentColor, auf Navy also in Weiß, flach: .flaeche
   für Karten und Gerät, .schirm für den Bildschirm, beide als leichte
   Aufhellung der Fläche. Haken, Ring und Guthabenbalken tragen die Koralle
   der Infografik. Angedeutete Kanten sind am 2026-09-11 wieder
   herausgeflogen. */
.schritt__bild {
  display: block;
  width: 100%;
  max-width: 14rem;
  height: auto;
  margin-bottom: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* Der Bildrahmen ist die Bühne: was hinausläuft, wird abgeschnitten. */
}
/* Deckend, nicht durchscheinend: die Karte im dritten Bild liegt auf dem
   Gerät auf, mit Deckkraft schien das Lesefeld durch sie hindurch. #232339
   ist 10 % Weiß auf dem Navy, #37374B 18 % — dieselbe Anmutung, nur fest. */
.schritt__bild .flaeche     { fill: #232339; }
.schritt__bild .schirm      { fill: #37374B; stroke-width: 1.8; }
.schritt__bild .balken-spur { fill: rgba(255, 255, 255, 0.10); stroke-width: 1.6; }
.schritt__bild .bild-ok     { stroke: var(--koralle); }

/* 01 — die Karte kommt von links über die Theke und bleibt rechts stehen. */
.ist-aktiv .bild-karte-kommt { animation: ablauf-karte var(--dauer) var(--ease-glatt) 1 both; }
@keyframes ablauf-karte {
  0%        { transform: translateX(-150px); }
  55%, 100% { transform: translateX(0); }
}

/* 02 — drei Münzen kurz hintereinander, der Balken wächst je um ein Drittel.
   Ruhezustand: Münzen weg, Balken voll. */
.schritt__bild .muenze { opacity: 0; }
.ist-aktiv .muenze { animation: ablauf-muenze var(--dauer) 1 both; }
.ist-aktiv .muenze:nth-child(2) { animation-delay: 0.14s; }
.ist-aktiv .muenze:nth-child(3) { animation-delay: 0.28s; }
@keyframes ablauf-muenze {
  0%        { transform: translateY(-40px); opacity: 0; animation-timing-function: cubic-bezier(0.45, 0, 0.9, 0.5); }
  4%        { opacity: 1; }
  16%       { transform: translateY(26px); opacity: 1; animation-timing-function: linear; }
  20%, 100% { transform: translateY(30px); opacity: 0; }
}
.schritt__bild .bild-balken {
  fill: var(--koralle);
  stroke: none;
  transform-box: fill-box;
  transform-origin: left center;
  transform: scaleX(1);
}
.ist-aktiv .bild-balken { animation: ablauf-balken var(--dauer) var(--ease-glatt) 1 both; }
@keyframes ablauf-balken {
  0%, 12%   { transform: scaleX(0); }
  18%, 24%  { transform: scaleX(0.34); }
  30%, 36%  { transform: scaleX(0.67); }
  42%, 100% { transform: scaleX(1); }
}

/* 03 — die Karte legt sich an das Gerät; der Pfeil auf dem Bildschirm weicht
   dem Haken im Kreis, der sich zeichnet. Die Karte endet bei x=98 und das
   Gerät beginnt bei x=94: sie liegt also auf dem Lesefeld auf, wie in der
   Referenz. Ruhezustand: Karte am Gerät, Haken da, Pfeil weg. */
.ist-aktiv .bild-tapkarte { animation: ablauf-tap var(--dauer) var(--ease-glatt) 1 both; }
@keyframes ablauf-tap {
  0%        { transform: translateX(-120px); }
  30%       { transform: translateX(0); animation-timing-function: cubic-bezier(0.3, 0, 0.3, 1); }
  34%       { transform: translateX(3px); animation-timing-function: cubic-bezier(0.3, 0, 0.3, 1); }
  38%, 100% { transform: translateX(0); }
}
.schritt__bild .bild-pfeil { opacity: 0; }
.ist-aktiv .bild-pfeil { animation: ablauf-pfeil var(--dauer) 1 both; }
@keyframes ablauf-pfeil {
  0%, 30%   { opacity: 1; }
  36%, 100% { opacity: 0; }
}
/* Ring und Haken zeichnen sich über die Strichlücke: 48 ist der Umfang des
   Rings (r 7,5), 13 die Länge des Hakens, beide aufgerundet. */
.schritt__bild .bild-ok-ring  { stroke-dasharray: 48; stroke-dashoffset: 0; }
.schritt__bild .bild-ok-haken { stroke-dasharray: 13; stroke-dashoffset: 0; }
.ist-aktiv .bild-ok-ring  { animation: ablauf-ring  var(--dauer) var(--ease-glatt) 1 both; }
.ist-aktiv .bild-ok-haken { animation: ablauf-haken var(--dauer) var(--ease-glatt) 1 both; }
@keyframes ablauf-ring {
  0%, 34%   { stroke-dashoffset: 48; opacity: 0; }
  35%       { stroke-dashoffset: 48; opacity: 1; }
  50%, 100% { stroke-dashoffset: 0;  opacity: 1; }
}
@keyframes ablauf-haken {
  0%, 44%   { stroke-dashoffset: 13; opacity: 0; }
  45%       { stroke-dashoffset: 13; opacity: 1; }
  58%, 100% { stroke-dashoffset: 0;  opacity: 1; }
}

/* Ruhende Teile tragen keine Animation; die Klasse benennt das nur. */
.schritt__bild .ruht { animation: none !important; }
.schritt__nr {
  display: block;
  font-family: var(--schrift-daten);
  font-weight: 700;
  font-size: clamp(2rem, 3.6vw, 3rem);
  line-height: 1;
  margin-bottom: 0.7rem;
  /* Gleiche Ziffernbreite, damit 01/02/03 exakt untereinander stehen. */
  font-variant-numeric: tabular-nums;
}
.schritt p { margin-top: 0.6rem; font-size: var(--fs-klein); opacity: 0.86; }


/* ==========================================================================
   INKLUSION
   --------------------------------------------------------------------------
   Asymmetrisch: die Kopfzeile steht links und bleibt beim Scrollen stehen,
   rechts laufen drei Blöcke durch. Jeder Block hat bewusst eine eigene
   Bauform — Halteliste, Raster mit Seitenlinie, Quellenkasten. Drei gleich
   gebaute Raster untereinander hätten den Abschnitt beliebig aussehen lassen.
   ========================================================================== */
.inklusion { }

/* Der Abschnitt lief bis 2026-09-07 zweispaltig: links eine mitlaufende
   Kopfzeile in 19 rem Breite, rechts drei verschieden geformte Listen
   übereinander. Das las sich wie drei Abschnitte in einem und war die
   Rückmeldung „sieht durcheinander aus".

   Jetzt einspaltig über die volle Breite, jeder Teil mit eigener Überschrift
   und in sich gleichförmig. --fs-h2 wie in allen anderen Abschnitten, weil die
   Überschrift nicht mehr in einer schmalen Spalte steht. */

/* Zielgruppen: sechs gleich gebaute Kacheln. Gleiche Struktur, gleiche
   Reihenfolge von Titel und Erklärung, gleiche Höhe pro Reihe. */
/* Der gemeinsame Grund steht einmal über der Liste (Feedback 2026-09-09).
   Vorher trug jede der sechs Kacheln einen eigenen Erklärsatz — die sagten
   fast alle dasselbe und machten aus sechs Namen sechs Absätze. */
.zielgruppen__grund {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  max-width: var(--lesbar);
  font-size: var(--fs-klein);
  color: var(--tinte-weich);
}

/* Nur noch Namen: kurze Zeilen, deshalb eine schlichte Liste in Spalten statt
   Kacheln. Der Ring vorn ist der Haltestellenpunkt der Seite, dieselbe Marke
   wie im Vergleich „Zwei Wege, ein Chip". */
.zielgruppen {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.15rem clamp(1.5rem, 3vw, 2.5rem);
  margin-top: clamp(1.5rem, 3vw, 2rem);
}
@media (max-width: 900px) { .zielgruppen { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .zielgruppen { grid-template-columns: minmax(0, 1fr); } }

.zielgruppe {
  position: relative;
  padding: 0.62rem 0 0.62rem 1.6rem;
  border-bottom: 1px solid var(--linie);
  font-size: 1.0125rem;
}
/* Hohler Ring in Haltestellen-Grün, auf der Höhe der ersten Textzeile. */
.zielgruppe::before {
  content: "";
  position: absolute;
  left: 0; top: 1.02rem;
  width: 0.62rem; height: 0.62rem;
  border-radius: 50%;
  border: 2px solid var(--halt-gruen);
}
/* Die letzte Zeile jeder Spalte trägt keine Linie. Bei drei Spalten sind das
   die Einträge 4 bis 6, bei zwei die 5 und 6, bei einer nur die 6. */
.zielgruppe:nth-child(n + 4) { border-bottom: 0; }
@media (max-width: 900px) {
  .zielgruppe:nth-child(4) { border-bottom: 1px solid var(--linie); }
}
@media (max-width: 560px) {
  .zielgruppe:nth-child(5) { border-bottom: 1px solid var(--linie); }
}

/* Der Folgen-Block bekommt eine eigene Fläche, damit er sichtbar zu einer
   anderen Frage gehört als die Zielgruppen darüber. */
.folgen {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: clamp(2rem, 4vw, 2.75rem);
  border-top: 1px solid var(--linie-stark);
}
.folgen__titel { font-size: var(--fs-h3); }

/* Betreibersicht: je Punkt ein Piktogramm über der Beschriftung (Feedback
   2026-09-09). Vorher eine Liste mit farbiger Seitenlinie — vier gleich
   aussehende Textblöcke, an denen das Auge nichts festhalten konnte.

   Vier feste Spalten auf breiten Schirmen: bei auto-fit ergäbe sich sonst
   3 + 1 mit einer angebrochenen zweiten Reihe. */
.vorteile {
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}
@media (max-width: 1000px) { .vorteile { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .vorteile { grid-template-columns: minmax(0, 1fr); } }

.vorteil {
  padding: clamp(1.1rem, 2.2vw, 1.4rem);
  border: 1px solid var(--linie);
  border-radius: var(--r-flaeche);
  background: var(--weiss);
}
/* Scheibe wie beim gemeinsamen Kopf in „Zwei Wege, ein Chip" — dieselbe
   Bildsprache, damit die Piktogramme nicht wie Fremdkörper wirken. */
.vorteil__zeichen {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem; height: 2.6rem;
  border-radius: 999px;
  background: var(--bogen-tief);
  color: var(--halt-gruen);
}
.vorteil__zeichen svg { width: 1.4rem; height: 1.4rem; }

.vorteil__name {
  margin-top: 0.9rem;
  font-family: var(--schrift-daten);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--halt-gruen);
}
.vorteil__text {
  margin-top: 0.4rem;
  font-size: var(--fs-klein);
  line-height: 1.55;
  color: var(--tinte-weich);
}

/* Fremde Quellen stehen in einem eigenen Kasten: sie sollen nicht wie eigene
   Aussagen der Seite gelesen werden. */
.quellen {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  margin-top: clamp(2.25rem, 4.5vw, 3rem);
  padding: clamp(1.25rem, 3vw, 1.75rem);
  border: 1px solid var(--linie);
  border-radius: var(--r-flaeche);
  background: var(--bogen-tief);
}
.quellen__titel { font-size: var(--fs-h3); }
.referenzen { list-style: none; margin-top: 1.2rem; display: grid; gap: 1.1rem; }
.referenz {
  display: grid;
  grid-template-columns: minmax(0, 7.5rem) minmax(0, 1fr);
  gap: 0.2rem 1.25rem;
}
.referenz__ort {
  font-family: var(--schrift-daten);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tinte-weich);
  padding-top: 0.15rem;
}
.referenz__text { font-size: var(--fs-klein); color: var(--tinte-weich); }
.referenz strong { color: var(--tinte); font-weight: 600; }

/* Verweis auf die Seite des Betreibers. Klein und unter dem Text: die Aussage
   steht im Vordergrund, der Beleg dahinter. */
.referenz__link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.45rem;
  min-height: var(--tipp);
  padding-block: 0.35rem;
  font-family: var(--schrift-daten);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  font-weight: 500;
  color: var(--tinte);
  border-bottom: 1.5px solid var(--linie-stark);
  transition: color 0.15s ease, border-color 0.15s ease;
}
.referenz__link:hover { color: var(--signal); border-color: var(--signal); }
.referenz__pfeil { width: 0.95em; height: 0.95em; flex: none; }
/* Kleiner als die Referenzen darüber (Redaktionswunsch 2026-09-09): die
   Zeile ist eine Datumsangabe, kein Inhalt. */
.quellen__fuss {
  margin-top: 1.2rem;
  font-size: 0.7rem;
  color: var(--tinte-weich);
}

/* Offene Namensfrage neben dem Kartennamen. Die Marke darf die Titelzeile
   nicht auseinanderziehen, deshalb kleiner als der Umgebungstext. */
.projekt__zeile .todo { font-size: 0.7rem; }

/* ==========================================================================
   PROJEKTE
   ========================================================================== */
/* Nebensatz-Text unter einer Kopfzeile: Redaktionsstand, Bildhinweis,
   Quellennachweis. Kleiner als .lead, damit die Kopfzeile ihre Aussage behält. */
.hinweis {
  margin-top: 1rem;
  max-width: var(--lesbar);
  font-size: var(--fs-klein);
  color: var(--tinte-weich);
}

/* ==========================================================================
   KARTEN-KARUSSELL (2026-09-08)
   --------------------------------------------------------------------------
   Löst die zwei Gruppenlisten ab. Zwei Zonen übereinander:

     Bühne   die fünf Karten liegen lose übereinander. Die aktive vorn, fast
             aufrecht, in Originalgröße; die Nachbarn versetzt, gedreht und
             verkleinert; die beiden äußeren noch weiter draußen und blasser.
     Angaben darunter, mittig, und ausschließlich zur aktiven Karte.

   Alles hängt an .karussell-bereit auf <html>, das ausschließlich
   karussell.js setzt. Ohne JavaScript greift keine Regel: die fünf Projekte
   stehen dann untereinander, jedes mit allen Angaben. Es geht nichts
   verloren, und es gibt keine toten Bedienknöpfe.

   Die Positionen kommen aus data-pos (0 = aktiv, ±1 = Nachbarn, ±2 = außen).
   Die Startwerte stehen im Markup, damit die Bühne schon beim ersten Zeichnen
   sitzt; karussell.js ändert sie danach nur noch.
   ========================================================================== */

/* --- Ohne JavaScript: schlichte Liste --- */
/* Ausdrücklich an :not(.karussell-bereit) gebunden. Ohne diese Bindung
   begrenzt die Breite unten auch die Bühne. Die Karte muss hier gedeckelt
   werden: vorher stand sie in einem Raster aus drei Spalten, ohne Deckel
   liefe sie über die volle Hüllenbreite und wäre größer als der Hero. */
.karussell { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.projekt__text { margin-top: 1.4rem; }
/* Die Angaben lagen zeitweise in der Lupe, danach hinter einem Schalter zum
   Aufklappen. Beides ist wieder raus (2026-09-09): sie stehen jetzt einfach
   als Tabelle unter der aktiven Karte. Damit gibt es hier keinen Zustand mehr
   zu verwalten — kein Schalter, keine Klasse auf <html>, kein Script. */
.karussell__pfeil,
.karussell__punkte { display: none; }

html:not(.karussell-bereit) .projekt {
  max-width: 32rem;
  margin-inline: auto;
}
html:not(.karussell-bereit) .projekt + .projekt { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
html:not(.karussell-bereit) .projekt__karte { max-width: 20rem; }

/* --- Mit JavaScript: die Bühne --- */
.karussell-bereit .karussell {
  /* Kartenbreite ist die Leitgröße: Bühnenhöhe und Textbreite hängen daran.
     1.586 ist das Seitenverhältnis von ID-1 (ISO/IEC 7810), also der echten
     Scheckkarte — dieselbe Zahl wie bei den Kartengrafiken. */
  --karte-breite: clamp(13rem, 28vw, 18.5rem);
  --karte-hoehe: calc(var(--karte-breite) / 1.586);
  /* Luft für Drehung und Schatten der Nachbarkarten. */
  --buehne-hoehe: calc(var(--karte-hoehe) + 1.9rem);
  position: relative;
}

.karussell-bereit .karussell__buehne { display: grid; }

/* Alle fünf Projekte liegen in DERSELBEN Rasterzelle. Dadurch bestimmt das
   höchste die Höhe, und beim Blättern springt nichts — die Angaben sind
   unterschiedlich lang. */
.karussell-bereit .projekt {
  grid-area: 1 / 1;
  display: grid;
  grid-template-rows: var(--buehne-hoehe) auto;
  justify-items: center;
  margin-top: 0;
  /* WICHTIG. Alle fünf Artikel liegen in derselben Rasterzelle und decken
     einander vollständig ab — auch dort, wo gar nichts von ihnen zu sehen ist.
     Ohne diese Zeile fing der zuletzt im Markup stehende Artikel (NVMcard)
     jeden Klick auf den Text der aktiven Karte ab: Schalter und Link waren
     tot. Nachgemessen lag über beiden article.projekt [NVMcard].

     Klickbar sind deshalb nur die Karten und der Text der aktiven Karte —
     nicht die Artikelkästen selbst. */
  pointer-events: none;
}
.karussell-bereit .projekt__karte,
.karussell-bereit .projekt[data-pos="0"] .projekt__text { pointer-events: auto; }

/* Die Karte selbst: mittig in der Bühnenzeile, Position über data-pos. */
.karussell-bereit .projekt__karte {
  width: var(--karte-breite);
  align-self: center;
  transform-origin: 50% 60%;
  transition: transform 0.5s var(--aus), opacity 0.4s ease, filter 0.4s ease;
}

/* Nur die aktive Karte ist scharf. Die Unschärfe wächst mit dem Abstand und
   trennt die Ebenen deutlicher, als Größe und Deckkraft es allein könnten —
   das Auge liest Schärfe als Nähe. Die Werte sind bewusst über der
   Wahrnehmungsschwelle: 2,5 px sieht man, 1 px nicht.

   filter erzeugt einen eigenen Stapelkontext; das ist hier ohne Folgen, weil
   die Reihenfolge ohnehin über z-index steht. */
.karussell-bereit .projekt[data-pos="0"]  .projekt__karte { z-index: 5; opacity: 1;    filter: none;         transform: translateX(0)     rotate(-0.4deg) scale(1); }
.karussell-bereit .projekt[data-pos="-1"] .projekt__karte { z-index: 4; opacity: 1;    filter: blur(2.5px);  transform: translateX(-62%)  rotate(-5deg)   scale(0.9); }
.karussell-bereit .projekt[data-pos="1"]  .projekt__karte { z-index: 4; opacity: 1;    filter: blur(2.5px);  transform: translateX(62%)   rotate(6deg)    scale(0.9); }
.karussell-bereit .projekt[data-pos="-2"] .projekt__karte { z-index: 3; opacity: 0.55; filter: blur(5px);    transform: translateX(-105%) rotate(-9deg)   scale(0.8); }
.karussell-bereit .projekt[data-pos="2"]  .projekt__karte { z-index: 3; opacity: 0.55; filter: blur(5px);    transform: translateX(105%)  rotate(10deg)   scale(0.8); }

/* Nur die aktive Karte hat die Lupe. Die Nachbarn nehmen den Klick trotzdem
   entgegen — karussell.js blättert dann zu ihnen. */
.karussell-bereit .projekt:not([data-pos="0"]) .lupe { display: none; }
.karussell-bereit .projekt:not([data-pos="0"]) .projekt__karte { cursor: pointer; }

/* --- Die Angaben unter der Bühne --- */
/* visibility statt display: der Übergang soll laufen, und ein unsichtbarer
   Block darf weder anklickbar noch in der Tabulatorfolge sein. */
.karussell-bereit .projekt__text {
  width: min(34rem, 100%);
  margin-top: clamp(1rem, 2vw, 1.4rem);
  text-align: center;
  opacity: 0;
  visibility: hidden;
  transform: translateY(0.9rem);
  transition: opacity 0.18s ease, transform 0.28s var(--aus), visibility 0.28s;
}
/* Zeitversetzt: erst ist die alte Angabe weg, dann kommt die neue.

   Die Verzögerung muss LÄNGER sein als das Ausblenden oben. Bei 0,16 s gegen
   0,25 s überlappten sich beide Blöcke 90 ms lang — und weil alle Blöcke
   übereinanderliegen, standen in dieser Zeit zwei Texte ineinander. Jetzt
   0,22 s gegen 0,18 s: der alte ist weg, bevor der neue anfängt. */
.karussell-bereit .projekt[data-pos="0"] .projekt__text {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0.22s;
}

.karussell-bereit .projekt__meta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem 0.8rem;
  flex-wrap: wrap;
}
/* Logo und Betreibername bilden eine Einheit (Feedback 2026-09-08): sie
   stehen dicht beieinander, das Logo deutlich größer als vorher, und nichts
   steht mehr dazwischen. */
.karussell-bereit .projekt__logo {
  height: clamp(2.6rem, 5vw, 3.4rem);
  max-width: 9rem;
  object-position: center;
}
.karussell-bereit .projekt__betreiber {
  font-size: 1rem;
  line-height: 1.25;
  text-align: left;
}

/* Kartenname und Status in einer Zeile. Der Status stand einmal allein
   zwischen zwei zentrierten Zeilen und bezog sich dort auf nichts; neben dem
   Namen ist klar, wovon er etwas behauptet, und die Zeile bekommt Gewicht. */
.projekt__zeile {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.karussell-bereit .projekt__zeile {
  justify-content: center;
  margin-top: 1.2rem;
}
.karussell-bereit .status { margin-top: 0; }
/* Nur der Fließtext bekommt den Rand-Ausgleich. .projekt__betreiber liegt im
   Flex-Container .projekt__meta: dort schöbe margin-inline: auto es an den
   Rand, statt es zu zentrieren. */
.karussell-bereit .projekt__kurz { margin-inline: auto; }
.karussell-bereit .projekt__betreiber { margin-top: 0; }

/* --- Aktionszeile: Infoseite und Angaben-Schalter --- */
/* Beide waren vorher optisch ungleiche Partner in einer Zeile — ein
   unterstrichener Textlink neben einer Pille. Im Karussell sind sie jetzt
   gleichrangige Knöpfe nebeneinander, mit einer eigenen Zeile Abstand zum
   Fließtext darüber. */
.karussell-bereit .projekt__aktionen {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1.6rem;
}
.karussell-bereit .projekt__link {
  margin-top: 0;
  padding: 0.45rem 1rem;
  min-height: var(--tipp);
  border: 1px solid var(--linie-stark);
  border-bottom-width: 1px;
  border-radius: 999px;
}
.karussell-bereit .projekt__link:hover {
  background: var(--bogen-tief);
  border-color: var(--tinte-weich);
  color: var(--tinte);
}
/* Die Tabelle steht linksbündig, obwohl der Text daneben zentriert sein kann —
   zentriert ist eine Tabelle nicht lesbar. Ein zurückhaltender Rahmen fasst
   sie zusammen und begründet die andere Ausrichtung. */
/* Der Rahmen gilt in beiden Fassungen — auch in der Liste ohne JavaScript.
   Er war zuerst an .karussell-bereit gebunden; dort fehlte er dann genau in
   der Fassung, die ganz ohne Gestaltungshilfen auskommen muss. */
.projekt__details {
  margin-top: 1.5rem;
  padding: 0 clamp(0.9rem, 2vw, 1.35rem);
  border: 1px solid var(--linie);
  border-radius: var(--r-flaeche);
  background: var(--weiss);
  text-align: left;
}
/* Der Rahmen trägt die äußeren Kanten schon; die Linien der ersten und
   letzten Zeile lägen sonst doppelt darauf. */
.projekt__details .fakten { margin-top: 0; }
.projekt__details .fakten tr:first-child :where(th, td) { border-top: 0; }
.projekt__details .fakten tr:last-child :where(th, td) { border-bottom: 0; }

/* --- Ab 900 px: Angaben neben den Text statt darunter ---
   Gestapelt war der Block rund 640 px hoch, mit Kopfzeile und Bühne kam der
   Abschnitt auf 1487 px — man musste scrollen, um Karte und Angaben zusammen
   zu sehen. Nebeneinander überlagern sich die Höhen, statt sich zu addieren.

   Links wird dabei linksbündig gesetzt: eine zentrierte Spalte neben einer
   linksbündigen Tabelle sieht aus wie zwei verschiedene Seiten. */
@media (min-width: 760px) {
  .karussell-bereit .projekt__text {
    width: min(64rem, 100%);
    display: grid;
    grid-template-columns: minmax(0, 0.88fr) minmax(0, 1.3fr);
    grid-template-areas:
      "marke  angaben"
      "titel  angaben"
      "text   angaben"
      "tat    angaben";
    /* Die Angabenspalte ist höher als die linke und spannt alle vier Zeilen.
       Ohne 1fr in der letzten Zeile verteilt sich ihre Mehrhöhe gleichmäßig
       auf alle vier und reißt Marke, Titel und Text auseinander. So sammelt
       sich der Rest unter dem Knopf. */
    grid-template-rows: auto auto auto 1fr;
    align-content: start;
    column-gap: clamp(1.75rem, 3.5vw, 3rem);
    text-align: left;
  }
  .karussell-bereit .projekt__meta      { grid-area: marke;   justify-content: flex-start; }
  .karussell-bereit .projekt__zeile     { grid-area: titel;   justify-content: flex-start; }
  .karussell-bereit .projekt__kurz      { grid-area: text;    margin-inline: 0; }
  .karussell-bereit .projekt__aktionen  { grid-area: tat;     justify-content: flex-start; align-self: start; }
  .karussell-bereit .projekt__details   { grid-area: angaben; align-self: start; margin-top: 0; }
}

/* Am Handy steht alles untereinander, und der Block wird über einen
   Bildschirm hoch (gemessen 1137 px bei 375 px Fensterbreite). Ganz vermeiden
   lässt sich das nicht — Karte plus sechszeilige Tabelle sind mehr als ein
   Handybildschirm —, aber die Abstände waren für die breite Fassung gesetzt.

   Die Beschriftungsspalte der Tabelle wird zugleich schmaler: jeder Pixel,
   den sie abgibt, ist einer weniger, um den der Wert umbricht, und ein
   Umbruch weniger spart mehr Höhe als der Abstand darüber. */
@media (max-width: 700px) {
  .karussell-bereit .projekt__zeile    { margin-top: 0.85rem; }
  .karussell-bereit .projekt__aktionen { margin-top: 1.1rem; }
  .projekt__details                    { margin-top: 1.1rem; }
}

/* --- Pfeile --- */
/* Flankierend auf mittlerer Kartenhöhe, an den Außenkanten, damit sie die
   versetzten Nachbarkarten nicht verdecken. */
.karussell-bereit .karussell__pfeil {
  position: absolute;
  top: calc(var(--buehne-hoehe) / 2);
  transform: translateY(-50%);
  z-index: 6;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tipp); height: var(--tipp);
  border: 1px solid var(--linie-stark);
  border-radius: 999px;
  background: var(--weiss);
  color: var(--tinte);
  cursor: pointer;
  box-shadow: var(--schatten-sm);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.karussell-bereit .karussell__pfeil:hover {
  background: var(--tinte);
  border-color: var(--tinte);
  color: var(--weiss);
}
.karussell__pfeil--zurueck { left: 0; }
.karussell__pfeil--vor { right: 0; }
/* Ein eigenes Pfeilsymbol braucht es nicht: das Chevron des Fragen-Akkordeons
   zeigt nach unten und wird hier gedreht. */
.karussell__pfeil svg { width: 1.35rem; height: 1.35rem; }
.karussell__pfeil--zurueck svg { transform: rotate(90deg); }
.karussell__pfeil--vor svg { transform: rotate(-90deg); }

/* --- Punkte --- */
.karussell-bereit .karussell__punkte {
  display: flex;
  justify-content: center;
  gap: 0.55rem;
  margin-top: clamp(1.5rem, 3vw, 2rem);
}
.karussell__punkt {
  position: relative;
  width: 0.6rem; height: 0.6rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--linie-stark);
  cursor: pointer;
  transition: background-color 0.2s ease, transform 0.2s var(--aus);
}
.karussell__punkt:hover { background: var(--tinte-weich); }
.karussell__punkt[aria-current="true"] {
  background: var(--tinte);
  transform: scale(1.35);
}
/* Die Trefferfläche muss die Fingergröße erreichen, der Punkt selbst bleibt
   klein. */
.karussell__punkt::before {
  content: "";
  position: absolute;
  inset: -0.7rem;
}

/* Bei weniger Bewegung bleibt die Anordnung, nur ohne Fahrt dorthin. */
@media (prefers-reduced-motion: reduce) {
  .karussell-bereit .projekt__karte,
  .karussell-bereit .projekt__text,
  .karussell__punkt { transition: none; }
  .karussell-bereit .projekt__text { transform: none; }
}

/* Auf schmalen Schirmen rücken die Nachbarkarten näher heran, sonst stehen
   sie unter den Pfeilen. */
@media (max-width: 700px) {
  /* Die versetzten Nachbarkarten ragen unter etwa 600 px über den rechten
     Bildschirmrand hinaus — bei 375 px Breite ergab das 456 px Dokumentbreite
     und damit eine Seite, die sich seitlich schieben lässt. Das ist älter als
     die heutigen Änderungen und fiel nur nicht auf, weil die Karten beim
     Laden noch mittig stehen und erst über eine halbe Sekunde an ihren Platz
     fahren: wer sofort misst, misst den Zustand davor.

     clip statt hidden: hidden würde die andere Achse zu einem Scrollbereich
     machen und die Wellen oben und unten abschneiden. clip lässt sie stehen.
     Der Schnitt sitzt an der Sektion, nicht an der Bühne — so laufen die
     Karten bis zur Bildschirmkante und nicht nur bis zum Textrand. */
  .projekte { overflow-x: clip; }

  .karussell-bereit .karussell__punkte { gap: 1rem; }
  .karussell-bereit .karussell { --karte-breite: min(16rem, 62vw); }
  .karussell-bereit .projekt[data-pos="-1"] .projekt__karte { transform: translateX(-46%) rotate(-5deg) scale(0.86); }
  .karussell-bereit .projekt[data-pos="1"]  .projekt__karte { transform: translateX(46%)  rotate(6deg)  scale(0.86); }
  .karussell-bereit .projekt[data-pos="-2"] .projekt__karte { transform: translateX(-74%) rotate(-9deg) scale(0.74); }
  .karussell-bereit .projekt[data-pos="2"]  .projekt__karte { transform: translateX(74%)  rotate(10deg) scale(0.74); }
}

/* Metadaten-Zeile: Logo des Verkehrsunternehmens, Status und Betreiber
   (Feedback 2026-09-07, seit dem Karussell 2026-09-08 als eine Zeile).

   Die fünf Logos haben sehr unterschiedliche Seitenverhältnisse (0,84 bis
   3,46). Deshalb eine feste Höhe und object-fit: contain — so sitzen sie auf
   einer gemeinsamen Linie, statt je nach Zuschnitt zu springen. */
.projekt__meta {
  display: flex;
  align-items: center;
  gap: 0.55rem 0.8rem;
  flex-wrap: wrap;
}
.projekt__logo {
  flex: none;
  width: auto;
  height: 2.4rem;
  max-width: 5.5rem;
  object-fit: contain;
  object-position: left center;
}
.projekt__name { font-size: 1.15rem; }
.karussell-bereit .projekt__name { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.75rem); }
.projekt__betreiber {
  font-size: 0.8125rem;
  line-height: 1.3;
  color: var(--tinte-weich);
}

/* Kurzbeschreibung und Link stehen bewusst NICHT in .projekt__details:
   die Angaben dort verschwinden, sobald karten-lupe.js läuft, und wandern in
   die Lupe. Was man mit der Karte tun kann und wo der Betreiber darüber
   schreibt, muss aber ohne Klick sichtbar sein (Feedback 2026-09-07). */
.projekt__kurz {
  margin-top: 0.9rem;
  font-size: var(--fs-klein);
  line-height: 1.55;
  color: var(--tinte-weich);
}

.projekt__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.9rem;
  min-height: var(--tipp);
  padding-block: 0.4rem;
  font-weight: 600;
  font-size: var(--fs-klein);
  color: var(--tinte);
  border-bottom: 1.5px solid var(--linie-stark);
  transition: color 0.15s ease, border-color 0.15s ease;
}
.projekt__link:hover { color: var(--signal); border-color: var(--signal); }
.projekt__pfeil { width: 0.95em; height: 0.95em; flex: none; }

/* Leichte Drehung und ein tieferer Schatten: so liegt die Karte lose auf dem
   Papier, statt in einem Rahmen zu stecken. Die Winkel wechseln die Richtung,
   damit die Karten im Raster nicht wie eine Reihe wirken.
   Die Drehung sitzt am Container, nicht an der Karte: nur so dreht der
   Lupen-Knopf mit und liegt weiter deckungsgleich über der Karte. Der Winkel
   steht als --dreh bereit, damit der Hover-Zustand ihn mit scale() kombinieren
   kann, ohne ihn zu überschreiben. */
.projekt__karte {
  --dreh: -2.5deg;
  position: relative;
  transform: rotate(var(--dreh));
}
/* Ohne JavaScript stehen die Karten untereinander; die wechselnden Winkel
   lassen sie dort lose wirken. Im Karussell überschreibt data-pos das. */
.projekt:nth-child(2) .projekt__karte { --dreh: 1.8deg; }
.projekt:nth-child(3) .projekt__karte { --dreh: -1.2deg; }
.projekt:nth-child(4) .projekt__karte { --dreh: 2.2deg; }
.projekt:nth-child(5) .projekt__karte { --dreh: -1.6deg; }


/* --- Lupe: Auslöser über der Karte ---
   Unsichtbare Klickfläche über der ganzen Karte; das Lupenzeichen erscheint
   erst beim Überfahren. Ausgeblendet, bis karten-lupe.js `lupe-bereit` setzt —
   ohne JavaScript kein toter Knopf. */
.lupe { display: none; }

.lupe-bereit .lupe {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  border: 0; background: transparent;
  cursor: zoom-in;
  border-radius: 12px;
}
.lupe-bereit .projekt__karte { transition: transform 0.2s var(--aus); }
.lupe-bereit .projekt__karte:has(.lupe:hover),
.lupe-bereit .projekt__karte:has(.lupe:focus-visible) {
  transform: rotate(var(--dreh)) scale(1.03);
}
/* Im Karussell steht die Position in der Transformation — die Regel oben
   würde sie überschreiben und die Karte aus der Bühne springen lassen.
   Deshalb hier dieselbe Position, nur eine Spur größer. */
.karussell-bereit .projekt[data-pos="0"] .projekt__karte:has(.lupe:hover),
.karussell-bereit .projekt[data-pos="0"] .projekt__karte:has(.lupe:focus-visible) {
  transform: translateX(0) rotate(-0.4deg) scale(1.03);
}

/* Erscheint erst beim Überfahren (Kundenwunsch): mittig auf der Karte, damit
   sie im Ruhezustand nichts verdeckt. Dunkler Kreis, weil die Karten hell und
   farbig sind und ein weißer Kreis auf der gelben Karte untergehen würde. */
.lupe__pille {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.9rem; height: 2.9rem;
  border-radius: 50%;
  background: rgba(22, 24, 29, 0.72);
  color: var(--weiss);
  box-shadow: 0 4px 16px rgba(22, 24, 29, 0.4);
  opacity: 0;
  transform: scale(0.85);
  transition: opacity 0.15s ease, transform 0.15s var(--aus);
}
.lupe:hover .lupe__pille,
.lupe:focus-visible .lupe__pille { opacity: 1; transform: none; }

/* Ohne Hover-fähigen Zeiger (Touch) gäbe es sonst gar keinen Hinweis, dass
   die Karte anklickbar ist — dort bleibt die Lupe deshalb dauerhaft stehen. */
@media (hover: none) {
  .lupe__pille { opacity: 1; transform: none; }
}

.lupe__zeichen { width: 1.3rem; height: 1.3rem; }


/* --- Lupe: die vergrößerte Ansicht ---
   Natives <dialog>: Fokusfalle, Esc und Backdrop kommen vom Browser.
   Seit die Projektliste nur noch Karte, Name und Status zeigt, steht hier
   auch der Rest: Herausgeber und Stand kommen beim Öffnen als Kopie aus
   .projekt__details herein (karten-lupe.js). Auf breiten Schirmen liegen
   Karte und Angaben nebeneinander, darunter gestapelt. */
.lupe-dialog {
  width: 100%; height: 100%;
  max-width: 100vw; max-height: 100vh;
  margin: 0; padding: clamp(1rem, 4vw, 2.5rem);
  border: 0; background: transparent;
  display: flex; align-items: center; justify-content: center;
  overflow: auto;
  overscroll-behavior: contain;
  cursor: zoom-out;
}
/* Muss nach der Regel oben stehen und spezifischer sein, sonst überschreibt
   das display:flex die UA-Regel `dialog:not([open]) { display: none }`. */
.lupe-dialog:not([open]) { display: none; }
.lupe-dialog::backdrop { background: rgba(11, 11, 35, 0.9); }

/* margin:auto zentriert den Block, solange er passt, und lässt ihn oben
   stehen, sobald gescrollt werden muss — mit align-items:center allein
   wäre der obere Rand bei hohem Inhalt nicht mehr erreichbar. */
.lupe-dialog__inhalt {
  margin: auto;
  cursor: default;
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 21rem);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}

/* Die Kopie erbt keine der .projekt__karte-Regeln — Breite und Schatten
   deshalb hier eigens setzen. Die Neigung folgt dem Zeiger: karten-lupe.js
   setzt --kipp-x und --kipp-y, hier stehen nur Ruhezustand und Perspektive.
   Die Karte kippt von der Maus weg, als drückte man eine Ecke hinunter. */
.lupe-dialog__buehne .karte {
  width: min(78vw, 460px, calc(58vh * 1.586));
  transform:
    perspective(1400px)
    rotateX(var(--kipp-x, 0deg))
    rotateY(var(--kipp-y, 0deg));
  transition: transform 0.14s ease-out;
}
.lupe-dialog__buehne :where(.karte__flaeche, .karte__bild) {
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.55);
}

.lupe-dialog__info { color: var(--weiss); }
.lupe-dialog__name { font-size: clamp(1.4rem, 1.15rem + 1vw, 1.95rem); font-weight: 700; }
/* Status und Faktenliste standen bis 2026-09-08 ebenfalls in diesem Dialog.
   Sie sind auf die Seite gewandert (Status unter den Betreibernamen, Fakten
   hinter den Schalter „Angaben anzeigen"), der Dialog zeigt nur noch Karte und
   Namen. Die Regeln dafür sind mit ihnen entfallen. */

.lupe-dialog__zu {
  position: absolute; top: 1rem; right: 1rem;
  width: 2.75rem; height: 2.75rem;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, 0.15); color: var(--weiss);
  font-size: 1.7rem; line-height: 1; cursor: pointer;
  transition: background-color 0.15s ease;
}
.lupe-dialog__zu:hover { background: rgba(255, 255, 255, 0.28); }

.lupe-dialog[open] { animation: lupe-auf 0.22s var(--aus); }
.lupe-dialog[open]::backdrop { animation: lupe-blende 0.22s ease; }
@keyframes lupe-auf { from { opacity: 0; transform: scale(0.97); } }
@keyframes lupe-blende { from { opacity: 0; } }
/* Status als Anzeige, nicht als Bedienelement (Rückmeldung 2026-09-11: die
   Pille sah aus, als könnte man draufdrücken — und das konnte sie nicht).
   Der Grund lag im Aufbau: eine gefüllte Pille mit weißer Versalschrift ist
   auf dieser Seite die Form der Knöpfe. Jetzt ein Statuslicht: ein kleiner
   Punkt vor dem Wort, keine Fläche, keine Kontur, kein Rand. Nichts daran
   sieht nach Klick aus, weil es keine Form hat, die man drücken könnte.

   Gefüllt = live, hohl = in Umsetzung. Dasselbe Zeichen wie in der
   Vergleichstabelle: der Haltestellenpunkt, voll oder leer. */
.status {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.8rem;
  font-family: var(--schrift-daten);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tinte-weich);
}
.status::before {
  content: "";
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  flex: none;
}
.status--live { color: var(--halt-gruen); }
.status--live::before { background: var(--halt-gruen); }
/* „In Umsetzung" ist eine belegte Angabe, kein offener Punkt — deshalb ein
   hohler Ring in der Textfarbe, nicht die Schraffur der TODO-Marken. */
.status--umsetzung::before { border: 1.5px solid var(--tinte-weich); }

/* Angaben zur Karte als Tabelle (2026-09-09). Vorher eine Definitionsliste
   mit Raster, davor ein Aufklappmenü. Jetzt schlicht eine Tabelle: die Angaben
   sind Beschriftung und Wert, also genau das, wofür eine Tabelle da ist. Die
   Beschriftung ist der Zeilenkopf, damit Vorlesesoftware sie zu jedem Wert
   mitnennt. */
.fakten {
  width: 100%;
  margin-top: 1.6rem;
  border-collapse: collapse;
  text-align: left;
}
.fakten th,
.fakten td {
  padding: 0.5rem 0;
  vertical-align: top;
  border-top: 1px solid var(--linie);
}
.fakten tr:last-child th,
.fakten tr:last-child td { border-bottom: 1px solid var(--linie); }
.fakten th {
  width: 9.5rem;
  padding-right: 1.5rem;
  padding-top: 0.68rem;
  font-family: var(--schrift-daten);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tinte-weich);
}
.fakten td { font-size: var(--fs-klein); }

/* Auf schmalen Schirmen bleiben für den Wert sonst keine lesbaren dreißig
   Zeichen. Die Beschriftungen brechen dann lieber selbst um. */
@media (max-width: 700px) {
  /* Enger, weil der Block am Handy ohnehin über einen Bildschirm hoch ist. */
  .fakten th,
  .fakten td { padding-top: 0.42rem; padding-bottom: 0.42rem; }
  .fakten th { padding-top: 0.58rem; }
}
@media (max-width: 560px) {
  .fakten th { width: 5.25rem; padding-right: 0.8rem; }
}


/* ==========================================================================
   HÄUFIGE FRAGEN — natives <details>, kein JavaScript
   ========================================================================== */
/* Nach dem Vorbild der gelieferten shadcn-Komponente (2026-09-07), aber in
   reinem CSS auf dem vorhandenen <details>-Akkordeon: die Liste sitzt in einer
   Karte mit Ring und weichem Schatten, die Einträge trennen gepunktete Linien,
   der Auslöser trägt einen Chevron und normales statt fettes Gewicht.

   Bewusst NICHT die React-Fassung übernommen: die hätte Next.js, Radix und
   Tailwind ins Projekt geholt. Die Seite bleibt statisch, ohne Build. */
/* Die Fläche der Fragen steht weiter oben im Block VERLÄUFE: sie ist an
   beiden Enden durchsichtig, damit keine Kante entsteht. */

.fragenliste {
  margin-top: clamp(2rem, 4vw, 3rem);
  max-width: 56rem;
  background: var(--weiss);
  border-radius: var(--r-karte);
  padding: 0.25rem clamp(1.25rem, 3vw, 2rem);
  box-shadow: var(--ring), var(--schatten-karte-weich);
}

/* Gepunktet statt durchgezogen, wie in der Vorlage. Der letzte Eintrag
   bekommt keine Linie: sie säße sonst direkt auf der Kartenkante. */
.frage { border-bottom: 1px dotted var(--linie-stark); }
.frage:last-child { border-bottom: 0; }

.frage summary {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  min-height: var(--tipp);
  padding: 1.15rem 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--schrift-anzeige);
  /* Nicht fett (Feedback 2026-09-07), in der Vorlage font-medium. */
  font-weight: 500;
  font-size: 1.0625rem;
  line-height: 1.4;
  letter-spacing: -0.005em;
}
.frage[open] summary { font-weight: 600; }
.frage summary::-webkit-details-marker { display: none; }
.frage summary:hover { color: var(--tinte-weich); }

/* Chevron statt Plus. Dreht beim Öffnen um 180°. */
.frage__pfeil {
  width: 1.05rem; height: 1.05rem;
  flex: none;
  color: var(--tinte-weich);
  transition: transform 0.2s var(--aus), color 0.15s ease;
}
.frage[open] .frage__pfeil { transform: rotate(180deg); color: var(--tinte); }
.frage summary:hover .frage__pfeil { color: var(--tinte); }

.fragen__fuss {
  margin-top: 1.5rem;
  max-width: 56rem;
  font-size: var(--fs-klein);
  color: var(--tinte-weich);
}
.fragen__fuss a {
  color: var(--tinte);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-color: var(--linie-stark);
}
.fragen__fuss a:hover { text-decoration-color: currentColor; }

.frage__text a {
  color: var(--tinte);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-color: var(--linie-stark);
}
.frage__text a:hover { text-decoration-color: currentColor; }

.frage__text {
  padding-bottom: 1.4rem;
  max-width: var(--lesbar);
  color: var(--tinte-weich);
  animation: aufblenden 0.25s var(--aus);
}
@keyframes aufblenden {
  from { opacity: 0; transform: translateY(-0.35rem); }
}


/* ==========================================================================
   402PAYMENT — ab hier Navy/Rot/Weiß
   ========================================================================== */
.absender {
  /* Von oben eine Spur aufgehellt in das Marken-Navy. Der aufgesetzte helle
     Radialverlauf vom 2026-09-08 ist wieder raus, er hat auf der dunklen
     Fläche gebändert. */
  background: linear-gradient(180deg, #12122E 0%, var(--navy) 55%);
  color: var(--weiss);
}
.absender__raster {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
/* Wortmarke auf Navy. Die Datei liegt farbig vor und wird per Filter auf Weiß
   gedreht — gleicher dokumentierter Workaround wie im Fuß und auf der
   Hauptseite, weil es (noch) keine sauber beschnittene weiße Wide-Variante
   gibt. Siehe ../landing-page/brand-assets/README.md. */
.absender__logo {
  height: clamp(1.8rem, 1.5rem + 1vw, 2.4rem);
  width: auto;
  filter: brightness(0) invert(1);
}

.absender h2 { margin-top: 1.1rem; font-size: var(--fs-h2); }
.absender .lead { margin-top: 1.1rem; }
.absender .btn { margin-top: 2rem; }

.leistungen { padding-top: 0.35rem; }
.leistungen li {
  border-top: 1px solid var(--linie-hell);
  padding: 0.95rem 0;
  font-family: var(--schrift-anzeige);
  font-weight: 600;
  font-size: 1.075rem;
}
.leistungen li:last-child { border-bottom: 1px solid var(--linie-hell); }


/* ==========================================================================
   WHITEPAPER
   ========================================================================== */
.whitepaper {
  /* Kein Trennstrich zum Absender darüber (Feedback 2026-09-07): beide
     Flächen sind navy, der Verlauf führt ohne Kante ineinander. */
  background: linear-gradient(180deg, var(--navy) 0%, #0E0E29 100%);
  color: var(--weiss);
}
.whitepaper__raster {
  display: grid;
  grid-template-columns: minmax(0, 0.75fr) minmax(0, 1fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: center;
}
.whitepaper h2 { margin-top: 0.9rem; font-size: clamp(1.6rem, 1.2rem + 1.7vw, 2.5rem); }
.whitepaper .lead { margin-top: 1.1rem; }
.whitepaper .btn { margin-top: 2rem; }

/* Bogen. Ersetzt das frühere Heft (Feedback 2026-09-07): der Download ist eine
   Infografik, kein Whitepaper — ein Buchrücken mit Schnittkante wäre das
   falsche Versprechen. Deshalb ein einzelnes Blatt im Hochformat, leicht
   gedreht, mit einem zweiten Blatt dahinter.

   Die Klassen .whitepaper* bleiben, weil sie nur das Raster des Abschnitts
   beschreiben; umbenennen wäre Lärm ohne Gewinn. */
.whitepaper__bild { display: flex; justify-content: center; }
.bogen {
  position: relative;
  width: clamp(190px, 24vw, 280px);
  aspect-ratio: 1 / 1.414;          /* DIN A, das Format einer Infografik */
  transform: rotate(-3deg);
}
/* Zweites Blatt dahinter: deutet den Stapel an, ohne dass ein zweites Element
   im Markup dafür nötig wäre. */
.bogen::before {
  content: "";
  position: absolute; inset: 0;
  transform: rotate(3.5deg) translate(6px, 4px);
  background: #23233A;
  border-radius: 3px;
}
.bogen__blatt {
  position: absolute; inset: 0;
  background: var(--signal);
  color: var(--navy);
  border-radius: 3px;
  padding: 12% 10%;
  display: flex; flex-direction: column;
  box-shadow: 0 22px 48px -14px rgba(0, 0, 0, 0.6);
}
/* Angedeutete Diagrammlinien am Fuß: genug, damit der Bogen als Infografik
   lesbar ist, ohne Inhalte zu behaupten, die es noch nicht gibt. */
.bogen__blatt::after {
  content: "";
  position: absolute; left: 10%; right: 10%; bottom: 12%;
  height: 22%;
  background:
    linear-gradient(var(--navy), var(--navy)) left 100% / 12% 45% no-repeat,
    linear-gradient(var(--navy), var(--navy)) 29% 100% / 12% 80% no-repeat,
    linear-gradient(var(--navy), var(--navy)) 48% 100% / 12% 30% no-repeat,
    linear-gradient(var(--navy), var(--navy)) 67% 100% / 12% 65% no-repeat,
    linear-gradient(var(--navy), var(--navy)) right 100% / 12% 100% no-repeat;
  opacity: 0.28;
}
.bogen__marke {
  font-family: var(--schrift-daten);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  font-weight: 700;
}
.bogen__titel {
  margin-top: 1rem;
  font-family: var(--schrift-anzeige);
  font-weight: 800;
  font-size: clamp(0.95rem, 0.7rem + 1vw, 1.3rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
}
.bogen__fuss {
  margin-top: 0.6rem;
  font-family: var(--schrift-daten);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.75;
}


/* ==========================================================================
   BETEILIGTE — Logoleiste (Feedback 2026-09-07)
   --------------------------------------------------------------------------
   Weiße Kacheln auf Navy: die drei Marken sind unterschiedlich eingefärbt,
   Thales ist dunkelblau auf Weiß und wäre direkt auf dem Navy unsichtbar. Eine
   gemeinsame helle Fläche löst das, ohne an den Logos zu drehen oder sie per
   Filter umzufärben.
   ========================================================================== */
/* Hell statt dunkel (Feedback 2026-09-07). Damit brauchen die Logos keinen
   weißen Kasten mehr: sie stehen frei auf der Sektion und behalten ihre
   Originalfarben. Der dunkle Fuß beginnt wieder beim Absender darunter. */
.beteiligte {
  /* Der einzige verbliebene Trennstrich (Feedback 2026-09-07). Er darf
     bleiben, die Farbstufe darunter nicht — deshalb läuft .fragen darüber
     ins Weiß aus. */
  border-top: 1px solid var(--linie);
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.beteiligte__titel { margin-top: 0.9rem; font-size: var(--fs-h3); }

.partnerleiste {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}
.partner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
  padding: 0.5rem;
  text-align: center;
}
/* GLEICH GROSSE LOGOS (2026-09-08)
   --------------------------------------------------------------------------
   Vorher hatten alle drei denselben Kasten (height: 2.4rem) — und sahen
   trotzdem verschieden groß aus. Der Grund steckt in den Dateien: nachgemessen
   (Tintenkasten über den Alphakanal, weißer Grund abgezogen) füllt die
   eigentliche Marke

     402PAYMENT   1355 × 314 von 1386 × 344   = 91 % der Dateihöhe
     EMVCo         198 ×  42 von  200 ×  44   = 96 %
     Thales        924 × 110 von 1200 × 675   = 16 %

   Bei Thales ist also fünf Sechstel der Datei weißer Rand. Gleiche Kastenhöhe
   heißt bei so unterschiedlichen Dateien nicht gleiche Logogröße — genau
   deshalb wirkte Thales vorher deutlich größer: die alte Regel skalierte es
   mit object-fit: cover auf die Spaltenbreite, also unkontrolliert.

   Angeglichen wird jetzt nicht die Kastenhöhe, sondern die FLÄCHE der Marke.
   Reine Höhengleichheit wäre hier falsch: Thales ist mit 8,4 : 1 fast doppelt
   so breit gestreckt wie die anderen (4,3 : 1 und 4,7 : 1) und würde bei
   gleicher Höhe wieder zu groß wirken. Gleiche Fläche heißt Höhe ~ 1/√Format;
   daraus die drei Werte unten. Sie sind gerechnet, nicht geschätzt.

   Der Kasten .partner__bild ist bei allen dreien gleich hoch und beschneidet
   den weißen Rand von Thales. Sobald es eine eng beschnittene Thales-Datei
   gibt, fällt der Sonderwert weg und alle drei stehen auf derselben Höhe.
   TODO: eng beschnittene Datei besorgen. */
.partner__bild {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 2.4rem;
  overflow: hidden;
}
/* object-fit: contain als Notbremse: sollte ein Logo doch einmal in der Breite
   beschnitten werden, wird es dadurch kleiner statt verzerrt. */
.partner__logo { width: auto; flex: none; object-fit: contain; }

/* Zielhöhe der Marke selbst: 26 px / 24,9 px / 18,6 px — gleiche Fläche.
   Die Werte hier sind Zielhöhe geteilt durch den Anteil oben. */
.partner__logo--402    { height: 1.78rem; }   /* 26,0 / 0,91 */
.partner__logo--emvco  { height: 1.63rem; }   /* 24,9 / 0,96 */
/* Thales ist absichtlich breiter als sein Kasten — der weiße Rand der Datei
   soll ja weggeschnitten werden. Ohne max-width: none greift die globale Regel
   img { max-width: 100% }: sie stutzt bei genau drei Spalten die Breite,
   während die Höhe fest bleibt, und quetscht die Wortmarke. Nachgemessen:
   201,3 px statt 203,4 px, also rund 1 % zu schmal. Der weiße Rand ist mit
   23 px je Seite breit genug, dass der Beschnitt die Marke nicht berührt. */
.partner__logo--thales { height: 7.15rem; max-width: none; }   /* 18,6 / 0,16 */
.partner__rolle {
  font-family: var(--schrift-daten);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--tinte-weich);
}
.beteiligte__hinweis { margin-top: 1.25rem; }

/* ==========================================================================
   FUSS (neu geordnet 2026-09-09)
   --------------------------------------------------------------------------
   Vorher drei ungleiche Spalten: Marke, eine sechs Einträge lange
   Sprungmarkenliste und eine dritte Spalte mit einem einzigen Link ohne
   Überschrift. Die dritte sah aus wie vergessen, die lange Liste zog den
   ganzen Fuß in die Höhe, und die Spaltenbreiten (1,6 : 1 : 1) passten zu
   keinem der Inhalte.

   Jetzt zwei Blöcke und eine Schlusszeile:
     links   die Marke mit Einordnungssatz
     rechts  die Sprungmarken, zweispaltig — 3 + 3 statt 6 untereinander
     unten   Copyright links, Impressum rechts, durch eine Linie abgesetzt

   Das Impressum steht damit in der Rechtezeile statt als eigene Spalte für
   einen Link. Der Höhenausgleich für Spalten ohne Überschrift ist mit der
   dritten Spalte entfallen — es gibt keine mehr. */
.fuss {
  background: linear-gradient(180deg, #0E0E29 0%, #08081A 100%);
  color: var(--navy-weich);
  padding-block: clamp(2.75rem, 5vw, 4rem) clamp(1.5rem, 3vw, 2rem);
}

/* Die Marke bekommt mehr Raum als die Sprungmarken: sie trägt einen Satz,
   die Navigation nur Wörter. */
.fuss__raster {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}

/* Die Wortmarke liegt farbig vor und wird auf Weiß gedreht, weil der Fuß
   navy ist. Gleicher Behelf wie auf der Hauptseite: eine sauber
   beschnittene weiße Fassung gibt es noch nicht. */
.fuss__logo img { height: 1.6rem; width: auto; filter: brightness(0) invert(1); opacity: 0.92; }
.fuss__satz {
  margin-top: 1rem;
  font-size: 0.875rem;
  line-height: 1.6;
  max-width: 26rem;
}

.fuss__titel {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--weiss);
  margin-bottom: 0.35rem;
}

/* Zwei Spalten für sechs Sprungmarken. column-count füllt spaltenweise, also
   3 + 3 — genau die Aufteilung, die die Reihenfolge der Seite erhält. */
.fuss__marken-liste {
  column-count: 2;
  column-gap: clamp(1.25rem, 3vw, 2.5rem);
}
.fuss__marken-liste a {
  display: block;
  padding-block: 0.4rem;
  font-size: 0.875rem;
  transition: color 0.15s ease;
}
.fuss__marken-liste a:hover { color: var(--weiss); }

/* Schlusszeile: Copyright links, Impressum rechts. */
.fuss__schluss {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 2rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--linie-hell);
  font-size: 0.8125rem;
}
.fuss__schluss a {
  margin-left: auto;
  min-height: var(--tipp);
  display: inline-flex;
  align-items: center;
  transition: color 0.15s ease;
}
.fuss__schluss a:hover { color: var(--weiss); }

/* Zwei Spalten passen bis hinunter zu 560 px. Darunter stehen Marke und
   Navigation untereinander. */
@media (max-width: 900px) {
  /* Zwei Spalten bleiben, nur enger. Die frühere Regel, die die Marke hier
     über alle Spalten zog, stammte aus dem Fuß mit vier Spalten und hätte
     die Navigation jetzt darunter geschoben. */
  .fuss__raster { gap: 2rem; }
}
@media (max-width: 760px) {
  /* Zwei schmale Spalten nebeneinander wären zwei Wortsäulen. Der Umbruch
     liegt höher als der des Rasters: schon bei zwei Rasterfeldern à 236 px
     ist für zwei Textspalten darin kein Platz. */
  .fuss__marken-liste { column-count: 1; }
}
@media (max-width: 560px) {
  .fuss__raster { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; }
  .fuss__schluss a { margin-left: 0; }
  .fuss__schluss { flex-direction: column; align-items: flex-start; gap: 0.5rem; }
}



/* ==========================================================================
   Einblenden beim Scrollen (scroll-reveal.js)
   --------------------------------------------------------------------------
   Der Ausgangszustand hängt an .reveal-ready auf <html>, und die Klasse setzt
   nur das Script. Ohne JS steht alles sichtbar da — kein opacity:0 in der Basis.
   ========================================================================== */
.reveal-ready [data-reveal] {
  opacity: 0;
  transition: opacity 0.55s var(--aus), transform 0.55s var(--aus);
}
.reveal-ready [data-reveal="up"]    { transform: translateY(1.5rem); }
.reveal-ready [data-reveal="left"]  { transform: translateX(-2.5rem); }
.reveal-ready [data-reveal="right"] { transform: translateX(2.5rem); }
.reveal-ready [data-reveal].is-revealed { opacity: 1; transform: none; }

/* Seit 2026-09-09 blenden nur noch GRAFIKEN ein, kein Text: die Kartenbühne,
   die Chip-Scheibe, die vier Piktogramme und die Logoleiste. Fließtext,
   Überschriften, Tabellen und Listen stehen sofort da.
   Die Staffelungsregeln für .merkmal und .schritt sind damit entfallen —
   beide tragen kein data-reveal mehr. */

/* Die Piktogramme sind klein; 1,5 rem Weg wären dafür ein Sprung. */
.reveal-ready .vorteil__zeichen[data-reveal="up"] { transform: translateY(0.7rem); }
.reveal-ready .vorteil:nth-child(2) .vorteil__zeichen { transition-delay: 0.07s; }
.reveal-ready .vorteil:nth-child(3) .vorteil__zeichen { transition-delay: 0.14s; }
.reveal-ready .vorteil:nth-child(4) .vorteil__zeichen { transition-delay: 0.21s; }


/* ==========================================================================
   Whitepaper-Popup (mailchimp-popup.js)
   --------------------------------------------------------------------------
   Markup und Klassennamen kommen unverändert aus der Hauptseite; hier nur auf
   die Tokens dieser Seite umgestellt. Die Knopfklassen .btn/.btn--primary/
   .btn--outline erwartet das Script fest — deshalb bleiben sie so heißen.
   ========================================================================== */
.mc-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: 1.25rem;
  background: rgba(11, 11, 35, 0.6);
  opacity: 0; visibility: hidden;
  transition: opacity 0.2s ease, visibility 0.2s ease;
}
.mc-modal.is-open { opacity: 1; visibility: visible; }
.mc-modal[hidden] { display: none; }

.mc-modal__dialog {
  position: relative;
  width: 100%; max-width: 600px;
  max-height: calc(100vh - 2.5rem); overflow-y: auto;
  background: var(--weiss); color: var(--tinte);
  border-radius: 6px;
  padding: clamp(1.5rem, 4vw, 2.25rem);
  box-shadow: 0 28px 70px rgba(11, 11, 35, 0.45);
  transform: translateY(12px) scale(0.98);
  transition: transform 0.25s var(--aus);
}
.mc-modal.is-open .mc-modal__dialog { transform: none; }

.mc-modal__close {
  position: absolute; top: 0.6rem; right: 0.6rem;
  width: 2.5rem; height: 2.5rem;
  border: none; background: transparent; color: var(--tinte-weich);
  font-size: 1.6rem; line-height: 1; cursor: pointer;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.mc-modal__close:hover { background: var(--bogen-tief); color: var(--tinte); }

.mc-modal__eyebrow {
  font-family: var(--schrift-daten);
  font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--tinte-weich);
}
.mc-modal__title { margin-top: 0.4rem; font-family: var(--schrift-anzeige); font-weight: 800; font-size: 1.45rem; line-height: 1.1; }
.mc-modal__intro { margin-top: 0.55rem; font-size: var(--fs-klein); color: var(--tinte-weich); }

.mc-progress { margin: 1.35rem 0 1.4rem; }
.mc-progress__label { font-family: var(--schrift-daten); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--tinte-weich); }
.mc-progress__track { margin-top: 0.45rem; height: 4px; border-radius: 999px; background: var(--bogen-tief); overflow: hidden; }
.mc-progress__fill { height: 100%; background: var(--signal); border-radius: 999px; transition: width 0.3s var(--aus); }

.mc-step[hidden] { display: none; }

.mc-field { margin-bottom: 1rem; }
.mc-field > label { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 0.35rem; }
.mc-field__optional { color: var(--tinte-weich); font-weight: 400; }
.mc-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem 1rem; }

.mc-field input {
  width: 100%; font-family: inherit; font-size: 1rem; color: var(--tinte);
  padding: 0.75rem 0.9rem; background: var(--weiss);
  border: 1.5px solid var(--linie-stark); border-radius: var(--r-knopf);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.mc-field input::placeholder { color: var(--tinte-weich); }
.mc-field input:focus { outline: none; border-color: var(--tinte); box-shadow: 0 0 0 3px rgba(22, 24, 29, 0.12); }
.mc-field.is-invalid input { border-color: var(--signal); }

/* Fehlertext in Tinte statt Rot: das Rot-Signal trägt der Feldrahmen als
   grafisches Element (3:1 genügt dort), der Text selbst braucht 4,5:1. */
.mc-field__error { margin-top: 0.3rem; font-size: 0.8rem; font-weight: 600; color: var(--tinte); display: none; }
.mc-field.is-invalid .mc-field__error { display: block; }

.mc-form__error { margin: 0 0 0.9rem; font-size: 0.85rem; font-weight: 600; color: var(--tinte); }
.mc-form__error[hidden] { display: none; }

.mc-actions { display: flex; gap: 0.75rem; margin-top: 1.35rem; }
.mc-actions .btn { flex: 1; }

.mc-legal { margin-top: 1rem; font-size: 0.72rem; line-height: 1.55; color: var(--tinte-weich); }

.mc-done { text-align: center; padding: 0.5rem 0; }
.mc-done[hidden] { display: none; }
.mc-done__check {
  width: 3.25rem; height: 3.25rem; margin: 0 auto 1rem;
  border-radius: 50%; background: rgba(255, 68, 54, 0.12); color: var(--signal);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.6rem; font-weight: 700;
}
.mc-done__title { font-family: var(--schrift-anzeige); font-weight: 800; font-size: 1.35rem; }
.mc-done__text { margin-top: 0.6rem; font-size: var(--fs-klein); color: var(--tinte-weich); }
.mc-done .btn { margin-top: 1.5rem; width: 100%; }

body.mc-modal-open { overflow: hidden; }

/* Keine eigenen Knopfregeln mehr für das Popup: seit die Seite dieselben
   .btn-Klassen wie die Hauptseite fährt, greifen die Knöpfe im Dialog
   automatisch — samt Pillenform, Shape-Morph und Ripple. */


/* ==========================================================================
   Breakpoints
   ========================================================================== */

@media (max-width: 960px) {
  .absender__raster,
  .whitepaper__raster { grid-template-columns: minmax(0, 1fr); }

  .whitepaper__raster { gap: 2.5rem; }
  .whitepaper__bild { justify-content: flex-start; order: 2; }
}

/* Unter 760 px fällt die Blatt-Attrappe ganz weg (Wunsch 2026-09-09). Sie ist
   die gezeichnete Vorschau des Bogens, nicht der Bogen selbst — untereinander
   gestapelt standen dort 269 px Andeutung über dem, was der Abschnitt
   tatsächlich anbietet. Überschrift, Text und der Knopf zum Anfordern bleiben.

   display: none ist hier unbedenklich: der Kasten trägt aria-hidden, für
   Vorlesesoftware war er ohnehin nie da. */
@media (max-width: 760px) {
  .whitepaper__bild { display: none; }
}

@media (max-width: 960px) {

  /* Karte und Angaben passen nebeneinander nicht mehr in den Dialog. */
  .lupe-dialog__inhalt { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .lupe-dialog__info { width: min(100%, 28rem); }
}

@media (max-width: 700px) {
  /* Zwei Zeilen statt einer: oben Wortmarke und Knopf, darunter die
     Sprungmarken in einer seitlich schiebbaren Reihe. Nebeneinander blieben
     für sechs Marken keine zwölf Pixel übrig.

     Bewusst nicht ausgeblendet: die Sprungmarken sind der Grund, warum es die
     Reihe gibt (Feedback 2026-09-07). Auf dem Handy wären sie am nötigsten. */
  /* Die frühere zweizeilige Leiste mit schiebbarer Markenreihe ist entfallen:
     bis 1024 px übernimmt jetzt das Burger-Menü. */
  .nav__innen { min-height: 3.75rem; }

  /* Karten bleiben oben neben der Überschrift (Kundenwunsch); Fließtext und
     Knöpfe rücken darunter auf die volle Breite. Der Bildnachweis muss dafür
     aus .hero__bild heraus — display:contents hebt den Zwischen-<div> auf, so
     werden Fächer und Nachweis zu eigenen Rasterfeldern. */
  .hero__raster {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    grid-template-areas:
      "kopf      bild"
      "fuss      fuss"
      "nachweis  nachweis";
    gap: 1.5rem 0.9rem;
    align-items: start;
  }
  .hero__bild { display: contents; }
  .faecher { grid-area: bild; align-self: center; }
  .bildnachweis { grid-area: nachweis; margin-top: 0; }

  /* Enger gestapelt und breitere Karten: in einer 150-px-Spalte zählt jeder
     Millimeter, damit die Kartenmarken noch lesbar bleiben. Karte 3 endet bei
     24 % + 76 % = genau 100 % der Fächerbreite. */
  .faecher__platz { width: 76%; }
  .faecher__platz:nth-child(1) { --l: 0%;  --t: 36%; }
  .faecher__platz:nth-child(2) { --l: 12%; --t: 18%; }
  .faecher__platz:nth-child(3) { --l: 24%; --t: 0%; }

  /* Flacher als die Grundkurve: hier teilt sich die Überschrift die Zeile mit
     dem Fächer. Maßgeblich ist „Einsteigen." — das längste Wort bestimmt, wie
     groß die Überschrift in der schmalen Spalte werden darf. In Inter misst es
     das 5,31-fache der Schriftgröße; Fira Sans Condensed kam mit demselben Wort
     auf gut ein Viertel weniger, deshalb ist diese Kurve nach dem
     Schriftwechsel neu gerechnet. Sie hält bei 320 px wie bei 700 px rund 6 %
     Luft zur Spaltenbreite. */
  .hero__zeile { font-size: clamp(1.5rem, -0.3rem + 9.2vw, 3.2rem); }

  .schritt__bild { max-width: 9.5rem; margin-bottom: 0.9rem; }

  .fakt { grid-template-columns: minmax(0, 1fr); gap: 0.15rem; }
}

@media (max-width: 420px) {
  .hero__raster {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "kopf"
      "bild"
      "fuss"
      "nachweis";
    gap: 1.1rem 0;
  }
  /* Über die volle Breite darf die Überschrift wieder größer werden — die
     flache Kurve oben war für die halbe Spalte gerechnet. */
  .hero__zeile { font-size: clamp(2.2rem, 0.4rem + 9vw, 3rem); }
  /* Und der Fächer zurück auf die Grundwerte: die engere Staffelung war
     dafür da, in 150 px noch drei Kartenmarken unterzubringen.

     Die Breite ist nicht die volle Spalte, sondern knapp zwei Drittel. Mit
     ganzer Breite wurde der Fächer 268 px hoch, der Hero 882 px, und die
     beiden Knöpfe rutschten unter die Bildschirmkante (856 px bei 828 px
     Fensterhöhe). So bleibt der Einstieg samt Knöpfen sichtbar. */
  .hero { padding-top: 2rem; }
  .hero__lead { margin-top: 1.1rem; }
  .faecher { width: min(15.75rem, 82%); margin-inline: auto; }
  /* Der große Kreis ragt sonst 28 px über den Fächer hinaus und schneidet
     durch die letzte Zeile der Überschrift — nebeneinander war über dem
     Fächer nur Luft, gestapelt steht dort Text. Er beginnt deshalb an der
     Oberkante des Fächers statt darüber. */
  .faecher::before { top: 0; left: 10%; width: 90%; }
  .faecher__platz { width: 64%; }
  .faecher__platz:nth-child(1) { --l: 0%;  --t: 34%; }
  .faecher__platz:nth-child(2) { --l: 18%; --t: 17%; }
  .faecher__platz:nth-child(3) { --l: 36%; --t: 0%; }
}

@media (max-width: 700px) {
  .fakt dt { padding-top: 0; }

  .referenz { grid-template-columns: minmax(0, 1fr); gap: 0.2rem; }
  .referenz__ort { padding-top: 0; }
  .btn-reihe .btn { flex: 1 1 100%; }

  .fuss__innen { flex-direction: column; align-items: flex-start; }
  .fuss__links { margin-left: 0; }
}

@media (max-width: 640px) {
  /* Popup als Bottom-Sheet statt gestauchtem Mini-Dialog. */
  .mc-modal { padding: 0; align-items: flex-end; }
  .mc-modal__dialog {
    max-width: none; max-height: 92vh;
    border-radius: 16px 16px 0 0;
    padding: 1.4rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom, 0px));
    transform: translateY(100%);
  }
  .mc-modal.is-open .mc-modal__dialog { transform: none; }
  .mc-modal__dialog::before {
    content: ""; display: block; width: 2.25rem; height: 4px;
    margin: -0.4rem auto 1rem; border-radius: 999px; background: var(--bogen-tief);
  }
  /* font-size bleibt 16px — kleiner zoomt iOS beim Fokus ins Feld hinein. */
  .mc-field input { min-height: 3rem; }
}

@media (max-width: 480px) {
  .mc-actions { flex-direction: column-reverse; }
  .mc-row { grid-template-columns: 1fr; gap: 0; }
}


/* ==========================================================================
   Reduzierte Bewegung. scroll-reveal.js schaltet sich selbst ab; hier bleiben
   Kartenfächer, Akkordeon und Popup zu entschärfen.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Die Ablaufbilder: ihr Ruhezustand ist bereits das fertige Bild, und
     ablauf.js schaltet sich bei reduzierter Bewegung selbst ab. Hier nur die
     Sicherung, falls die Klasse doch einmal gesetzt wird. */
  .schritt__bild * { animation: none !important; }
  .schritt::after { animation: none !important; }
  .faecher__platz { animation: none; }
  .frage__text { animation: none; }
  .btn:hover, .btn:active { transform: none; }
  .btn__ripple { display: none; }
  .lupe-dialog[open],
  .lupe-dialog[open]::backdrop { animation: none; }
  .lupe-bereit .projekt__karte { transition: none; }
  .lupe-bereit .projekt__karte:has(.lupe:hover) { transform: rotate(var(--dreh)); }
  .lupe__pille { transition: none; }
  /* karten-lupe.js setzt die Kippwinkel hier gar nicht erst; der Rückfallwert
     0deg bleibt also stehen. Die Regel nimmt nur noch den Übergang heraus. */
  .lupe-dialog__buehne .karte { transition: none; }
  .frage summary::after,
  .mc-modal, .mc-progress__fill { transition: none; }
  /* Steht nach dem 640px-Block und hebt dessen translateY(100%) mit auf —
     ohne Bewegung darf das Sheet nicht unsichtbar unter dem Rand liegen. */
  .mc-modal__dialog { transform: none; transition: none; }
}
