/* ============================================================
   marcy - Design-System
   Quelle der Wahrheit: Brand & CI/marcy-ci.json v5.7.0
   Klassennamen sind 1:1 die Webflow-Klassen, damit der Übertrag
   ohne Umbenennen läuft.
   ============================================================ */

/* --- Schrift: relativ eingebunden, nie auf ~/Library/Fonts zeigen --- */
/* WOFF2 zuerst, auf Latin beschnitten: 1,83 MB OTF werden so 56 KB. Die OTF
   bleibt als zweite Quelle stehen - ein Browser ohne WOFF2 laedt sie, jeder
   andere ruehrt sie nicht an. Erzeugt mit _Fonts/schriften-bauen.py. */
@font-face { font-family: 'Inter'; src: url('schriften/Inter-Regular.woff2')  format('woff2'), url('schriften/Inter-Regular.otf')  format('opentype'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('schriften/Inter-Medium.woff2')   format('woff2'), url('schriften/Inter-Medium.otf')   format('opentype'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('schriften/Inter-SemiBold.woff2') format('woff2'), url('schriften/Inter-SemiBold.otf') format('opentype'); font-weight: 600; font-style: normal; font-display: swap; }

/* --- Variablen aus der CI --- */
:root {
  --weiss:   #FFFFFF;
  --ink:     #1A1A1A;
  --greige:  #EBEAE8;
  --neon:    #CEFA05;
  --neon-hover: #BEE800;
  --grau:    #6B6B69;
  --grau-dunkel: #ADADAB;   /* Sekundärtext nur auf Schwarz, 7,4:1 */
  --rahmen:  #DCDAD6;
  --rahmen-dunkel: #333333;
  --chrome:  #C7C4C2;

  --r-button: 8px;
  --r-karte: 14px;
  --r-karte-klein: 12px;
  --r-badge: 6px;
  --r-pille: 100px;

  --breite-max: 1200px;
  --rand: 120px;
  --sektion: 72px;   /* 11.8. von 96 gekuerzt und vereinheitlicht */
}

/* --- Grundlage --- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: 'Inter', 'Helvetica Neue', Arial, sans-serif;
  font-optical-sizing: none;
  -webkit-font-smoothing: antialiased;
  color: var(--ink);
  background: var(--weiss);
}
img, svg { max-width: 100%; display: block; }
h1, h2, h3, h4, p, ul, ol { margin: 0; }
ul { padding: 0; list-style: none; }
a { color: inherit; }

/* Textmarkierung: Neon als Fläche, darauf ausschliesslich Schwarz (14,34:1) */
::selection      { background: var(--neon); color: var(--ink); text-shadow: none; }
::-moz-selection { background: var(--neon); color: var(--ink); text-shadow: none; }

/* Ankersprünge unter der klebenden Nav-Pille */
h2[id], h3[id], section[id], article[id] { scroll-margin-top: 112px; }

.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.skip { position: absolute; left: -9999px; }
.skip:focus { left: 20px; top: 20px; background: var(--ink); color: var(--weiss); padding: 10px 16px; border-radius: var(--r-button); z-index: 200; }

/* ============================================================
   Typo-Skala - neun Stufen. Löst die 29 Einzelgrößen aus Figma auf.
   ============================================================ */
.t-h1      { font-size: 56px; font-weight: 600; line-height: 1.08; letter-spacing: -0.025em; }
.t-h2      { font-size: 40px; font-weight: 600; line-height: 1.15; letter-spacing: -0.02em; }
.t-h3      { font-size: 24px; font-weight: 600; line-height: 1.30; letter-spacing: -0.01em; }
.t-h4      { font-size: 20px; font-weight: 600; line-height: 1.35; }
.t-lead    { font-size: 18px; font-weight: 400; line-height: 1.55; color: var(--grau); }
.t-body    { font-size: 16px; font-weight: 400; line-height: 1.55; }
.t-small   { font-size: 14px; font-weight: 400; line-height: 1.50; color: var(--grau); }
.t-caption { font-size: 12px; font-weight: 500; line-height: 1.40; color: var(--grau); }
.t-micro   { font-size: 11px; font-weight: 600; line-height: 1.30; letter-spacing: 0.06em; text-transform: uppercase; color: var(--grau); }

/* ============================================================
   Sektionen und Raster
   ============================================================ */
.sektion {
  position: relative;
  overflow: hidden;
  width: 100%;
  padding: var(--sektion) var(--rand);
  background: var(--weiss);
}
.sektion.is-greige  { background: var(--greige); }
.sektion.is-schmal  { padding-top: 64px; padding-bottom: 64px; }
.sektion.is-schwarz { background: var(--ink); color: var(--weiss); }
.sektion.is-schwarz .t-h2,
.sektion.is-schwarz .t-h3 { color: var(--weiss); }
.sektion.is-schwarz .t-lead,
.sektion.is-schwarz .t-small { color: var(--grau-dunkel); }

.raster { position: relative; z-index: 1; width: 100%; max-width: var(--breite-max); margin: 0 auto; }

.luecke-12 { height: 12px } .luecke-16 { height: 16px } .luecke-20 { height: 20px }
.luecke-24 { height: 24px } .luecke-28 { height: 28px } .luecke-32 { height: 32px }
.luecke-40 { height: 40px } .luecke-48 { height: 48px } .luecke-64 { height: 64px }

.linie { height: 1px; background: var(--rahmen); border: 0; margin: 0; }
.sektion.is-schwarz .linie { background: var(--rahmen-dunkel); }
/* Der Fuss ist schwarz, aber KEINE .sektion.is-schwarz - die Regel oben
   griff dort nicht und die helle Haarlinie #DCDAD6 lag als heller Strich
   quer durch den schwarzen Fuss. Auf Schwarz gilt #333333
   (cardsOnBackground.onBlack). */
.fuss .linie { background: var(--rahmen-dunkel); }
/* Auf Greige ist #DCDAD6 unsichtbar (1,01:1). Chrome erreicht 1,38:1 - für
   einen Trenner genug, für Text waere es zu wenig. */
.sektion.is-greige .linie { background: var(--chrome); }

/* ============================================================
   Formmotiv: Viertelring-Kontur aus der Logo-Geometrie
   Aussenradius 420, Innenradius 279 - Verhältnis 76,5 : 115
   Genau einmal pro Seite, hinter dem Inhalt.
   ============================================================ */
.bogen {
  position: absolute;
  top: -70px; right: -100px;
  width: 420px; height: 420px;
  pointer-events: none;
  z-index: 0;
}

/* ============================================================
   Navigation - schwebende Pille
   ============================================================ */
/* Der Halter ist durchsichtig. Mit weissem Hintergrund zog er einen 114 px
   hohen weissen Streifen ueber jede greige und jede schwarze Sektion, die
   darunter durchlief - die Pille soll schweben, nicht auf einer Leiste sitzen. */
.nav-halter {
  position: sticky; top: 0; z-index: 100;
  display: flex; justify-content: center;
  padding: 20px var(--rand);
  background: transparent;
  pointer-events: none;
}
.nav-pille {
  pointer-events: auto;
  display: flex; align-items: center; column-gap: 44px;
  background: var(--weiss);
  border: 1px solid var(--rahmen);
  border-radius: var(--r-pille);
  padding: 10px 14px 10px 26px;
  transition: box-shadow 160ms ease;
}
/* Sobald Inhalt darunter durchlaeuft, hebt ein weicher Schatten die Pille ab.
   Kein Schatten im Ruhezustand - auf Weiss haette er nichts zu trennen. */
.nav-halter.is-gescrollt .nav-pille { box-shadow: 0 6px 28px rgba(26, 26, 26, 0.10); }

/* Verschachtelte Radien: in einer vollen Pille mit 10 px Innenabstand bleibt
   innen wieder eine Pille. 8 px wie bei den Seitenschaltflaechen saehen hier
   nach drittem Radius auf 48 px Hoehe aus. */
.nav-kontakt .btn { border-radius: var(--r-pille); }
.nav-logo { display: flex; align-items: center; }
.nav-logo img { height: 30px; width: auto; }
.nav-links { display: flex; align-items: center; column-gap: 28px; }
.nav-link {
  font-size: 15px; font-weight: 500; color: var(--grau); text-decoration: none;
  transition: color 120ms ease;
}
.nav-link:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.nav-link[aria-current="page"] { color: var(--ink); }
.nav-kontakt { display: flex; align-items: center; column-gap: 14px; }
.nav-portraet {
  width: 34px; height: 34px; flex: 0 0 auto;
  border-radius: var(--r-pille); overflow: hidden;
  background: var(--neon);
}
.nav-portraet img { width: 100%; height: 100%; object-fit: cover; }

/* ============================================================
   Schaltflächen - genau eine Primärfläche pro Ansicht
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; column-gap: 9px;
  font-family: inherit; font-size: 16px; font-weight: 600; line-height: 1.2;
  text-decoration: none; border: 0; cursor: pointer;
  border-radius: var(--r-button);
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.btn.is-primaer   { background: var(--neon); color: var(--ink); padding: 12px 22px; }
.btn.is-primaer:hover { background: var(--neon-hover); }
.btn.is-sekundaer {
  background: transparent; color: var(--ink);
  border: 1.5px solid var(--ink); padding: 10.5px 20.5px;
}
.btn.is-sekundaer:hover { background: var(--ink); color: var(--weiss); }
.btn.is-hell { border-color: var(--weiss); color: var(--weiss); }
.btn.is-hell:hover { background: var(--weiss); color: var(--ink); }
.btn.is-breit { width: 100%; justify-content: center; }
/* Portraet im Button: linker Innenabstand schrumpft, damit das Bild in der Pille sitzt */
.btn.is-mit-bild { padding-left: 6px; column-gap: 10px; }
.btn-bild {
  width: 28px; height: 28px; flex: 0 0 auto;
  border-radius: var(--r-pille); overflow: hidden; background: var(--ink);
}
.btn-bild img { width: 100%; height: 100%; object-fit: cover; }

/* Strichpfeil: nur an Schaltflächen, die von der Seite wegführen */
.pfeil { flex: 0 0 auto; transition: transform 120ms ease; }
.btn:hover .pfeil { transform: translate(2px, -2px); }
/* Waagerecht für Verweise, die auf der Website bleiben - gleiche Strichstärke,
   damit es dieselbe Linie ist, nur eine andere Richtung. */
.pfeil-rechts { flex: 0 0 auto; transition: transform 120ms ease; }

.link-unter {
  font-size: 16px; font-weight: 500; color: var(--ink);
  text-decoration: underline; text-underline-offset: 3px;
}
.link-unter:hover { color: var(--grau); }

/* ============================================================
   Karten
   ============================================================ */
.karte {
  background: var(--weiss);
  border: 1px solid var(--rahmen);
  border-radius: var(--r-karte);
  padding: 30px;
  transition: transform 200ms ease-out, border-color 200ms ease-out;
}
.karte.is-greige { background: var(--greige); border-color: transparent; }
.karte.is-dunkel { background: var(--ink); border-color: var(--rahmen-dunkel); }
/* Zwei Stufen, damit die Hebung kein falsches Versprechen ist:
   klickbar  → Hebung UND Haarlinie auf Schwarz. Der Zeiger ist eine Hand.
   is-hebt   → nur die Hebung, Linie bleibt hell, Zeiger bleibt ein Pfeil.
               Rueckmeldung auf Beruehrung, kein Klickversprechen.
   Werte aus marcy-ci.json -> layout.motion.cardHover: 180 ms, 4 px, kein Schatten. */
a.karte:hover, .karte.is-klickbar:hover { transform: translateY(-8px); border-color: var(--ink); }
/* Die Hebung von .is-hebt steht weiter unten, hinter dem Erscheinen-Effekt -
   Grund dort. */
.thema { transition: transform 200ms ease-out, background-color 200ms ease-out; }

.pille {
  display: inline-flex; align-items: center;
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink); background: var(--greige);
  border-radius: var(--r-pille); padding: 6px 12px;
}
.pille.is-neon { background: var(--neon); }
.pille.is-hell { background: var(--weiss); }

/* ============================================================
   Raster-Hilfen
   ============================================================ */
.reihe   { display: flex; column-gap: 24px; }
.reihe-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; }
.reihe-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.reihe-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.zwischen { display: flex; align-items: center; justify-content: space-between; }

/* ============================================================
   Startseite · Hero
   ============================================================ */
.hero { padding-top: 72px; }
.hero-lead { max-width: 660px; margin-top: 28px; }
.hero-cta  { margin-top: 40px; }

.logo-zeile { margin-top: 88px; border-top: 1px solid var(--rahmen); padding-top: 32px; }
/* Quadrat aus der Logo-Geometrie, 6 px, Abstand 9 - brand.motif.square.
   Steht vor jeder Eyebrow-Zeile; auf der Startseite derzeit ungenutzt. */
.marke-quadrat { display: inline-block; vertical-align: middle; width: 6px; height: 6px; background: var(--ink); margin-right: 9px; position: relative; top: -1px; }

/* ---- Logo-Laufband, endlos, Laufrichtung links nach rechts ----------------
   Der Abstand ist mit Absicht gross: bei vier Logos ist ein Satz sonst
   schmaler als das Band und man saehe dieselbe Marke zweimal gleichzeitig.
   Mit 128 px ist ein Satz breiter als der klare Bereich zwischen den beiden
   Verlaufsmasken - es steht nie ein Logo doppelt im Sichtbaren.        */
.laufband { overflow: hidden; position: relative; }
.laufband::before, .laufband::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 90px; z-index: 2; pointer-events: none;
}
.laufband::before { left: 0;  background: linear-gradient(90deg, var(--weiss), rgba(255,255,255,0)); }
.laufband::after  { right: 0; background: linear-gradient(270deg, var(--weiss), rgba(255,255,255,0)); }
.laufband-spur { display: flex; width: max-content; animation: laufband 42s linear infinite; }
/* Anhalten beim Zeigen - wer ein Logo lesen will, soll es lesen koennen. */
.laufband:hover .laufband-spur { animation-play-state: paused; }
.laufband-satz { display: flex; align-items: center; column-gap: 128px; padding-right: 128px; }
.laufband-satz img { height: 34px; width: auto; }
.laufband-satz .logo-niccos { height: 28px }
.laufband-satz .logo-gw     { height: 40px }
/* Zwei Sonderfaelle, beide aus dem Seitenverhaeltnis begruendet, nicht nach
   Gefuehl: Eis Five ist mit 1,96:1 die kompakteste Marke der Reihe und darf
   deshalb hoeher stehen. Select Living ist ein Schriftzug mit 11,4:1 - bei
   den regulaeren 34 px waere er 387 px breit und wuerde das Band beherrschen.
   Auf 20 px bleibt er mit 227 px zwar das breiteste Logo, aber lesbar. */
.laufband-satz .logo-eisfive      { height: 40px }
.laufband-satz .logo-selectliving { height: 20px }
/* Rechts nach links: das Gleis startet auf 0 und faehrt eine Satzbreite nach
   links. Bei zwei gleichen Saetzen ist der Ruecksprung unsichtbar. Das ist die
   Leserichtung - Logos wandern hinein statt einem entgegen. */
@keyframes laufband { from { transform: translateX(0) } to { transform: translateX(-50%) } }

/* ============================================================
   Startseite · Vorher/Nachher - waagerechter Vergleichs-Schieber
   Der Bereichsregler liegt unsichtbar darueber und liefert
   Maus, Touch und Tastatur ohne eigene Ereignisbehandlung.
   ============================================================ */
.vergleich {
  --x: 50%;
  position: relative; overflow: hidden;
  border: 1px solid var(--rahmen); border-radius: var(--r-karte);
  background: var(--weiss); aspect-ratio: 1200 / 620;
  touch-action: none;
}
.vergleich img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.vergleich-vorher { position: absolute; inset: 0; clip-path: inset(0 calc(100% - var(--x)) 0 0); }
.vergleich-griff {
  position: absolute; top: 0; bottom: 0; left: var(--x);
  width: 2px; background: var(--weiss); transform: translateX(-1px); z-index: 3; pointer-events: none;
}
.vergleich-knopf {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 56px; height: 56px; border-radius: var(--r-pille);
  background: var(--neon); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 600; letter-spacing: 2px;
}
.vergleich-regler {
  position: absolute; inset: 0; z-index: 4;
  width: 100%; height: 100%; margin: 0; padding: 0;
  appearance: none; background: transparent; cursor: ew-resize; opacity: 0;
}
.vergleich-regler:focus-visible { opacity: 1; outline: 2px solid var(--ink); outline-offset: -4px; }
.vergleich-marke {
  position: absolute; z-index: 2; bottom: 20px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink); background: var(--weiss);
  border: 1px solid var(--rahmen); border-radius: var(--r-badge); padding: 5px 10px;
}
.vergleich-links  { left: 20px; }
.vergleich-rechts { right: 20px; }

/* ============================================================
   Modulkarten mit Bildbereich
   ============================================================ */
.modul-bild {
  height: 158px; border-radius: var(--r-karte-klein);
  background: var(--greige); border: 1px solid var(--rahmen);
  overflow: hidden; margin-bottom: 18px;
}
.modul-bild img { width: 100%; height: 100%; object-fit: cover; object-position: center; }

/* ============================================================
   Strichicons - ein Satz, ein Raster, eine Konturbreite
   Quelle: 03 Brand & CI/02 Logo/Icons/marcy-icons.svg

   Die Kontur bleibt 1,5 px, egal wie gross das Icon steht. Genau das
   unterscheidet einen Satz von einer Sammlung: Pfeil 11 px, Icon 28 px,
   Icon in der Flaeche 64 px, Bogen 420 px - ueberall dieselbe Linie.
   ============================================================ */
.icon-flaeche,
.modul-bild.is-icon,
.beitrag-bild.is-icon {
  display: flex; align-items: center; justify-content: center;
}
/* Gleiche Flaechenhoehe wie die Modulkarten. Das 16:9 der Beitragsbilder galt
   fuer Motive - eine Kategoriekachel braucht keine Bildproportion, und auf
   Handybreite waere 16:9 bei voller Kartenbreite ein 200-px-Loch. */
.beitrag-bild.is-icon { aspect-ratio: auto; height: 158px; }
.icon-gross { width: 64px; height: 64px; flex: 0 0 auto; }
.icon-klein { width: 28px; height: 28px; flex: 0 0 auto; }
.icon-gross [stroke],
.icon-klein [stroke] { vector-effect: non-scaling-stroke; }
.modul-liste { margin-top: 12px; }
.modul-liste li { font-size: 14.5px; line-height: 1.7; color: var(--grau); }
.modul-liste li::before { content: "·"; margin-right: 8px; }

/* ============================================================
   Sichtbarkeit - drei Wege, schwarze Sektion
   Steht auf Startseite und Leistungen in derselben Fassung. Schwarz, weil die
   Sektion zwischen zwei helle Flaechen faellt und den Wechsel Weiss/Greige
   sonst kippen wuerde: Schwarz ist der Joker in der Folge, nicht ihr naechster
   Schritt.
   Gar kein Neon in dieser Sektion, auch nicht als Akzentmarke im Icon. Der Satz
   erlaubt die Marken (color.accentRule), aber bei 28 px ist die Linse der Lupe
   r=8 in einem 28er-Feld - gefuellt wird daraus ein Neonklecks mit Stiel, das
   Icon verliert seine Lesbarkeit. Auf Schwarz tragen die drei Icons deshalb nur
   ihre weisse Kontur. Der Akzent der Ansicht bleibt der Knopf im Hero.
   Die Kennzeichnung „Inklusive" traegt Weiss, nicht Neon.
   ============================================================ */
.sicht-kopf { display: flex; align-items: center; justify-content: space-between; column-gap: 14px; }
/* Ohne das haengen Trennlinie und Liste an der Textlaenge: die dritte Karte hat
   einen Absatz weniger und ihre Linie sass 18 px hoeher als die der Nachbarn.
   Der Fuss der Karte wird nach unten geschoben, die drei Linien liegen auf einer
   Hoehe. Greift nur, wenn die Karten gleich hoch sind - einspaltig auf dem Handy
   ist das ohnehin gegenstandslos. */
.sicht-karte { display: flex; flex-direction: column; }
.sicht-karte > hr.linie { margin-top: auto; }
.pille.is-umriss { background: transparent; border: 1px solid var(--rahmen); color: var(--grau); padding: 5px 11px; }
.sektion.is-schwarz .pille.is-umriss { border-color: var(--rahmen-dunkel); color: var(--grau-dunkel); }

/* Sekundaertext auf Schwarz: bisher stand an jedem <li> ein Inline-Stil, weil
   .modul-liste und .t-micro ihr Grau fuer Weiss festlegen. Als Regel gilt es
   fuer jede dunkle Sektion, nicht nur fuer diese. */
.sektion.is-schwarz .t-micro { color: var(--grau-dunkel); }
.sektion.is-schwarz .modul-liste li { color: var(--grau-dunkel); }
.sektion.is-schwarz .modul-liste li::before { color: var(--weiss); }
.sektion.is-schwarz .link-unter { color: var(--weiss); }
.sektion.is-schwarz .link-unter:hover { color: var(--grau-dunkel); }

/* ============================================================
   Drei Termine
   ============================================================ */
.termin-kopf { display: flex; align-items: center; column-gap: 12px; }
.nummer {
  width: 32px; height: 32px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--ink); border-radius: var(--r-pille);
  font-size: 14px; font-weight: 600;
}
.nummer.is-flaeche { border: 0; background: var(--greige); }
/* Neon als Fläche, Ziffer schwarz - 14,34:1. Die fünf Schritte auf /leistungen
   sind ein Bauteil in Wiederholung, nicht fünf einzelne Akzente. Deshalb bleibt
   der Primärknopf im Abschluss der einzige weitere Neonträger der Ansicht. */
.nummer.is-neon { border: 0; background: var(--neon); color: var(--ink); }

/* ============================================================
   Kundenstimmen
   ============================================================ */
.stimme { display: flex; flex-direction: column; }
/* Die Karte ist ein Link auf den Fall im Portfolio - damit greift a.karte:hover
   (4 px Hub, Haarlinie dunkelt). Der Name unterstreicht mit, damit auch ohne
   Hub erkennbar ist, dass die Karte irgendwohin fuehrt. */
a.stimme { text-decoration: none; }
/* Am 10.8. stand hier die Ausnahme `a.stimme:hover { border-color: var(--rahmen) }`
   mit der Begruendung, ein schwarzer Rahmen um eine 380 px breite weisse Karte
   lese sich als Auswahlrahmen statt als Hover. Auf Marcels Ansage aufgegeben:
   die Karte dunkelt jetzt wie jede andere. Ohne diese Zeile greift wieder
   `a.karte:hover` - Hebung plus Rand in Ink. */
/* Dazu die INNEREN Trennlinien: der Aussenrahmen war schon schwarz, die zwei
   Haarlinien im Zitatblock blieben grau. Eine Karte, die halb dunkelt, sieht
   nach unfertigem Zustand aus. Jetzt geht die ganze Linienfuehrung mit. */
a.stimme:hover .linie,
a.stimme:focus-within .linie { background: var(--ink); }
a.stimme .linie { transition: background 200ms ease-out; }
a.stimme:hover .person-name,
a.stimme:focus-visible .person-name { text-decoration: underline; text-underline-offset: 3px; }
a.stimme:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.stimme-logo { height: 26px; margin-bottom: 18px; }
.stimme-logo img { height: 100%; width: auto; }
.stimme-zitat { font-size: 17px; line-height: 1.6; margin: 18px 0; }
.person { display: flex; align-items: center; column-gap: 14px; margin-top: 18px; }
.person-foto { width: 44px; height: 44px; border-radius: var(--r-pille); overflow: hidden; flex: 0 0 auto; background: var(--greige); }
.person-foto img { width: 100%; height: 100%; object-fit: cover; }
.person-name { font-size: 15px; font-weight: 500; }
.person-rolle { font-size: 13.5px; color: var(--grau); }
.person-spacer { flex: 1 1 auto; }

/* ============================================================
   Abschluss - der eine Block, der über jedem Fuss gleich steht.
   Reihenfolge ist Absicht: erst das Gesicht, dann die Aussage,
   dann genau ein Ziel. Kein zweiter Knopf, damit der eine zieht.
   ============================================================ */
.abschluss { display: flex; flex-direction: column; align-items: center; text-align: center; }
.abschluss-foto {
  width: 88px; height: 88px; flex: 0 0 auto;
  border-radius: var(--r-pille); overflow: hidden;
  background: var(--ink);
}
.abschluss-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.abschluss-name { margin-top: 14px; font-size: 14px; font-weight: 500; color: var(--grau); }
.abschluss h2 { margin-top: 20px; max-width: 900px; }
.abschluss .t-lead { margin-top: 20px; max-width: 640px; }
.abschluss > .btn { margin-top: 32px; }
/* Zwei Knoepfe nebeneinander: Primaer fuehrt weiter, Sekundaer oeffnet die
   Paket-Praesentation. Der Abschluss ist eine Spalte - ohne diesen Halter
   staenden die beiden untereinander. */
.abschluss-knoepfe {
  display: flex; align-items: center; justify-content: center;
  column-gap: 14px; row-gap: 12px; flex-wrap: wrap;
  margin-top: 32px;
}
/* Linksbuendige Knopfreihe. `.hero-knoepfe` stand bisher ohne eigene Regel im
   Markup - die beiden Knoepfe lagen als inline-flex nebeneinander und der
   Abstand kam aus dem Leerzeichen im Quelltext. Damit gab es kein row-gap,
   wenn sie auf Handybreite umbrechen. Beide Reihen teilen jetzt eine Regel. */
.hero-knoepfe, .knopf-reihe {
  display: flex; align-items: center;
  column-gap: 14px; row-gap: 12px; flex-wrap: wrap;
}

/* ============================================================
   Akkordeon - auf Greige weisse Karten statt Haarlinien,
   weil #DCDAD6 auf #EBEAE8 nur 1,01:1 erreicht
   ============================================================ */
.akkordeon { display: flex; flex-direction: column; row-gap: 8px; }
.frage {
  background: var(--weiss); border: 1px solid var(--rahmen);
  border-radius: var(--r-karte-klein); padding: 22px 24px;
}
.frage > summary {
  display: flex; align-items: center; justify-content: space-between;
  cursor: pointer; list-style: none;
  font-size: 20px; font-weight: 600; letter-spacing: -0.01em;
}
.frage > summary::-webkit-details-marker { display: none; }
.frage > summary::after {
  content: ""; width: 14px; height: 14px; flex: 0 0 auto; margin-left: 20px;
  background: currentColor;
  clip-path: polygon(46% 0, 54% 0, 54% 46%, 100% 46%, 100% 54%, 54% 54%, 54% 100%, 46% 100%, 46% 54%, 0 54%, 0 46%, 46% 46%);
  transition: transform 240ms ease-in-out;
}
.frage[open] > summary::after { transform: rotate(45deg); }
.frage-antwort { font-size: 16.5px; line-height: 1.6; color: var(--grau); margin-top: 12px; max-width: 860px; }

/* ============================================================
   Kennzahlen - zählt beim Laden von 0 hoch
   ============================================================ */
.kennzahlen { display: grid; grid-template-columns: repeat(4, 1fr); }
.kennzahl { padding-right: 24px; }
/* Trenner auf Greige: Chrome #C7C4C2 (1,38:1). Die Haarlinie #DCDAD6 waere
   hier unsichtbar, #333 aus der schwarzen Fassung viel zu hart -
   layout.sectionRhythm.hairlineOnGreige. */
.kennzahl + .kennzahl { border-left: 1px solid var(--chrome); padding-left: 32px; }
.sektion.is-schwarz .kennzahl + .kennzahl { border-left-color: var(--rahmen-dunkel); }
.kennzahl-wert { font-size: 56px; font-weight: 600; line-height: 1.05; letter-spacing: -0.025em; }
.kennzahl-label { font-size: 16px; font-weight: 500; margin-top: 6px; }

/* ============================================================
   Projektfälle - graue Sektion, schwarze Schrift, je Fall
   genau eine Karte mit genau einer Verrundung.
   ============================================================ */
/* Zwei Fälle nebeneinander: bei 1.200 px Raster sind das 584 px je Karte.
   Vier Fälle untereinander waren 3.400 px Seite - nebeneinander die Hälfte,
   und man sieht zwei Projekte in einem Blick statt eins nach dem anderen. */
.faelle { display: grid; grid-template-columns: repeat(2, 1fr); gap: 32px 32px; }

/* Ein Fall ist EIN Element mit EINER Verrundung. Vorher waren es drei
   einzeln gerundete Teile - Browserrahmen, Logozeile, Zitatkasten - die
   frei auf Greige lagen und nicht zusammengehörten. Jetzt trägt die Karte
   die Rundung, und overflow:hidden schneidet die Leiste oben mit ab.
   Grau bleibt die Sektion, die Karte ist weiss: Greige auf Greige waere
   keine Karte mehr, und die Sektion muss greige bleiben, sonst stossen
   Projektsektion und weisser Abschluss aneinander. */
.fall {
  display: flex; flex-direction: column;
  background: var(--weiss);
  border: 1px solid var(--rahmen);
  border-radius: var(--r-karte);
  overflow: hidden;
}
.fall-inhalt { display: flex; flex-direction: column; flex: 1 1 auto; padding: 22px 24px; }
.fall-kopf { display: flex; align-items: center; justify-content: space-between; column-gap: 16px; }
.fall-zitat { margin-top: 18px; }

/* ============================================================
   Browserrahmen für Fallkarten
   ============================================================ */
.browser { border: 1px solid var(--rahmen); border-radius: var(--r-karte-klein); overflow: hidden; background: var(--weiss); }
.browser-leiste {
  display: flex; align-items: center; column-gap: 6px;
  background: var(--greige); padding: 9px 14px;
}
.browser-punkt { width: 6px; height: 6px; border-radius: 50%; background: var(--chrome); }
.browser-domain { flex: 1 1 auto; text-align: center; font-size: 10px; color: var(--grau); }
/* 240 statt 430: der Rahmen soll anteasern, nicht die Seite zeigen. Bei 584 px
   Kartenbreite ist das rund 2,4:1 - ein flacher Streifen, der neugierig macht,
   und der Scroll im Hover hat trotzdem etwas zu zeigen. */
.browser-bild { height: 240px; overflow: hidden; background: var(--greige); }
/* Ruhig zeigen, nicht durchhetzen: 1.200 px in 20 s sind rund 60 px/s - lesbares Tempo.
   Der Screenscroll von NICCOS ist bei 1.200 px Breite rund 6.900 px hoch; ihn ganz
   durchzufahren wären bei diesem Tempo fast zwei Minuten. Ein Ausschnitt genügt, um zu
   zeigen, dass die Seite Substanz hat.
   Beim Verlassen kurze Rückkehr - eine 20-s-Rückfahrt fühlt sich zäh an. */
.browser-bild img { width: 100%; height: auto; transition: transform 600ms ease-out; }
.fall:hover .browser-bild img,
.fall:focus-within .browser-bild img {
  transform: translateY(-1200px);
  transition: transform 20s linear;
}
/* is-kurz ist am 7.8. entfallen. G&W hatte nur einen Bildschirmausschnitt und
   damit 79 px Fahrweg - zu wenig zum Scrollen. Der echte Screenscroll ist jetzt
   da (1200 x 4437, aus der Kundenseite in 02 Clients/g&w/site/ gerendert), alle
   vier Fälle fahren gleich. */

/* ============================================================
   Formular - Fokus ist schwarz, niemals neon (Neon auf Weiss 1,21:1)
   ============================================================ */
.feld-gruppe { display: flex; flex-direction: column; row-gap: 8px; }
.feld-label { font-size: 14px; font-weight: 500; }
.feld, .feld-text, .feld-select {
  font-family: inherit; font-size: 16px; color: var(--ink);
  background: var(--weiss); border: 1px solid var(--rahmen);
  border-radius: var(--r-button); padding: 12px 14px; width: 100%;
}
.feld::placeholder, .feld-text::placeholder { color: var(--grau); }
.feld:focus, .feld-text:focus, .feld-select:focus { outline: none; border: 1.5px solid var(--ink); }
.feld-text { min-height: 196px; resize: vertical; }
.feld-select { appearance: none; background-image: none; }
.select-halter { position: relative; }
.select-pfeil { position: absolute; right: 14px; top: 50%; transform: translateY(-50%); pointer-events: none; }
.dsgvo { display: flex; align-items: flex-start; column-gap: 12px; font-size: 14px; color: var(--grau); }
.dsgvo input { width: 20px; height: 20px; flex: 0 0 auto; accent-color: var(--ink); margin: 0; }
.leitfrage { display: flex; column-gap: 14px; align-items: flex-start; }
.leitfrage-bild { width: 56px; height: 56px; flex: 0 0 auto; border-radius: var(--r-pille); overflow: hidden; background: var(--neon); }
.leitfrage-bild img { width: 100%; height: 100%; object-fit: cover; }
.leitfrage p { font-size: 16px; font-weight: 500; line-height: 1.5; }

/* ============================================================
   Mehrschritt-Formular · /kontakt

   Drei Schritte, nicht sechs. Schritt 1 kostet genau einen Klick
   und kein Tippen - das ist die eigentliche Wirkung des Musters.
   Wer einmal geklickt hat, macht weiter.

   Der Fortschrittsbalken traegt Ink, nicht Neon: die CI verbietet
   Neon als Linienfarbe, und ein 4-px-Balken ist eine Linie, keine
   Flaeche mit Schrift darauf. Neon bleibt am einen Weiter-Knopf.

   Ohne JavaScript stehen alle Schritte offen untereinander und der
   Fortschritt ist ausgeblendet - das Formular bleibt absendbar.
   ============================================================ */
/* Text links, Formular rechts - Schritt 1 soll ohne Scrollen im Bild sein.
   Auf Handybreite steht das Formular ZUERST: wer den Knopf schon geklickt
   hat, will nicht noch einmal die Erklaerung lesen. */
.kontakt-oben { display: grid; grid-template-columns: 1fr 560px; gap: 64px; align-items: start; }
.kontakt-text { padding-top: 8px; }
.kontakt-schritte { display: flex; flex-direction: column; row-gap: 14px; }
.kontakt-schritte li { display: flex; align-items: center; column-gap: 12px; }
@media screen and (max-width: 1119px) {
  .kontakt-oben { grid-template-columns: 1fr; gap: 40px; }
  .kontakt-formular { order: -1; }
}

.ms-kopf { display: flex; align-items: center; column-gap: 14px; }
.ms-kopf-bild { width: 48px; height: 48px; flex: 0 0 auto; border-radius: var(--r-pille); overflow: hidden; background: var(--ink); }
.ms-kopf-bild img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ms-kopf-name { font-size: 15px; font-weight: 600; }
.ms-kopf-zeile { font-size: 14px; color: var(--grau); margin-top: 2px; }

.ms-fortschritt { display: flex; column-gap: 8px; margin-top: 22px; }
.ms-balken { height: 4px; flex: 1 1 0; border-radius: 2px; background: var(--rahmen); transition: background 240ms ease; }
.ms-balken.is-voll { background: var(--ink); }
.ms-zaehler { font-size: 13px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--grau); margin-top: 20px; }

/* Der graue Kasten soll bei jedem Schritt gleich hoch bleiben. Alle drei
   Schritte liegen deshalb in DERSELBEN Rasterzelle uebereinander - die Hoehe
   der Buehne ist damit die des hoechsten Schritts, ohne festen Pixelwert, der
   bei jeder Textaenderung nachzuziehen waere.
   Verborgen wird mit visibility, nicht mit display: nur so behaelt der Schritt
   seinen Platz. visibility:hidden nimmt Felder gleichzeitig aus der Tabfolge
   und aus dem Vorlesebaum - display:none haette den Platz mitgenommen,
   opacity:0 haette die Felder anklickbar gelassen. */
.ms-buehne { display: grid; }
.ms-schritt { grid-area: 1 / 1; border: 0; padding: 0; margin: 0; min-width: 0; visibility: hidden; }
.ms-schritt.is-aktiv { visibility: visible; }
.no-js .ms-buehne { display: block; }
.no-js .ms-schritt { visibility: visible; }
.no-js .ms-fortschritt, .no-js .ms-zaehler, .no-js .ms-fuss { display: none; }
.no-js .ms-schritt + .ms-schritt { margin-top: 48px; }
/* Die Schritt-Knoepfe sind ohne JavaScript ausgeblendet - ohne diesen
   Ersatzknopf waere das Formular nicht absendbar. */
.ms-ohne-js { display: none; }
.no-js .ms-ohne-js { display: inline-flex; margin-top: 40px; }
.ms-schritt legend { padding: 0; }
.ms-frage { font-size: 34px; font-weight: 600; line-height: 1.18; letter-spacing: -0.02em; margin-top: 10px; }
.ms-hinweis { font-size: 15px; color: var(--grau); margin-top: 10px; }

/* Auswahlkarten: eine Zeile, ganze Breite anklickbar. Der Kreis links
   ist kein Systemknopf - Radios und Checkboxen lassen sich nicht in
   allen Browsern gleich gestalten, deshalb liegt das Feld unsichtbar
   darunter und die Karte zeigt den Zustand. */
.wahl-liste { display: flex; flex-direction: column; row-gap: 9px; margin-top: 22px; }
.wahl {
  position: relative; display: flex; align-items: center; column-gap: 14px;
  background: var(--weiss); border: 1px solid var(--rahmen);
  border-radius: var(--r-karte-klein); padding: 15px 20px;
  font-size: 16.5px; cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}
.wahl:hover { border-color: var(--ink); }
.wahl input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.wahl-punkt {
  width: 20px; height: 20px; flex: 0 0 auto;
  border: 1.5px solid var(--chrome); border-radius: var(--r-pille);
  display: flex; align-items: center; justify-content: center;
  transition: border-color 120ms ease, background 120ms ease;
}
.wahl-punkt::after {
  content: ""; width: 8px; height: 8px; border-radius: var(--r-pille);
  background: var(--ink); transform: scale(0); transition: transform 120ms ease-out;
}
.wahl input:checked ~ .wahl-punkt { border-color: var(--ink); }
.wahl input:checked ~ .wahl-punkt::after { transform: scale(1); }
.wahl:has(input:checked) { border-color: var(--ink); border-width: 1.5px; padding: 14.5px 19.5px; }
/* Tastaturfokus muss sichtbar sein, obwohl das Feld unsichtbar ist. */
.wahl:has(input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }

.ms-fuss { display: flex; align-items: center; justify-content: space-between; column-gap: 20px; margin-top: 28px; }
.ms-zurueck {
  display: inline-flex; align-items: center; column-gap: 10px;
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; font-size: 15px; font-weight: 500; color: var(--grau);
}
.ms-zurueck:hover { color: var(--ink); }
.ms-zurueck[hidden] { display: none; }
/* Nicht schrumpfen: im Flexraum wurde der Knopf auf 203 px gequetscht und
   brach seine Beschriftung um - 62 statt 43 px Zeilenhoehe. */
.ms-fuss .btn { margin-left: auto; flex: 0 0 auto; }
.ms-zurueck { flex: 0 0 auto; }
/* Fehlermeldung erscheint erst, wenn jemand ohne Pflichtangabe weiterwill.
   Rot ist nicht in der Palette - der Hinweis traegt Ink auf Weiss und
   wird durch Gewicht und Position erkannt, nicht durch Farbe. */
/* Sie steht IN der Knopfzeile: deren Hoehe bestimmt der 44-px-Knopf, eine
   20-px-Textzeile kostet dort keine Hoehe. Unter dem Schritt liess sie den
   grauen Kasten um 22 bis 34 px wachsen, sobald sie erschien. */
.ms-fehler {
  font-size: 14px; font-weight: 500; margin: 0 16px;
  /* Nicht schrumpfen und nicht umbrechen: in Schritt 3 quetschte der Flexraum
     die Meldung auf 148 px und damit in zwei Zeilen - die Fusszeile wuchs von
     43 auf 62 px. Alle drei Texte sind kurz genug, dass sie in eine Zeile
     passen (breitester Fall: 67 + 207 + 148 + 32 = 454 von 494 px). */
  flex: 0 0 auto; white-space: nowrap;
}
.ms-fehler[hidden] { display: none; }
.feld[aria-invalid="true"], .feld-text[aria-invalid="true"], .feld-select[aria-invalid="true"] { border: 1.5px solid var(--ink); }

@media screen and (max-width: 767px) {
  .ms-frage { font-size: 26px }
  .ms-fuss { flex-direction: column-reverse; align-items: stretch; row-gap: 16px }
  .ms-fuss .btn { margin-left: 0; justify-content: center }
  .ms-zurueck { justify-content: center }
  /* Gestapelte Fusszeile: die Meldung bekommt eine eigene Zeile. Damit der
     graue Kasten auch hier gleich hoch bleibt, ist die Zeile immer da und
     nur unsichtbar - sonst wuechse der Kasten um 33 px, sobald sie erscheint. */
  .ms-fehler { white-space: normal; text-align: center; margin: 0 }
  .ms-fehler[hidden] { display: block; visibility: hidden }
}

/* ============================================================
   Terminauswahl als Dialog
   ============================================================ */
dialog.termin {
  border: 1px solid var(--rahmen); border-radius: var(--r-karte);
  padding: 30px 32px 32px; width: min(760px, calc(100vw - 40px));
  background: var(--weiss); color: var(--ink);
}
dialog.termin::backdrop { background: rgba(26, 26, 26, 0.6); }
.dialog-kopf { display: flex; align-items: center; justify-content: space-between; }
.dialog-zu { background: none; border: 0; cursor: pointer; padding: 4px; line-height: 0; }
.embed-platz {
  display: flex; flex-direction: column; align-items: center; justify-content: center; row-gap: 8px;
  height: 360px; background: var(--greige);
  border: 1px solid var(--rahmen); border-radius: var(--r-karte);
  text-align: center; padding: 40px;
}

/* ============================================================
   Blog
   ============================================================ */
/* Beitragskarte ohne Bild und ohne Icon - zurueck zur ersten Fassung aus
   blog.md ("Kein Bild in der Karte"). Die Icons waren Kategoriekacheln, keine
   Motive: elf Karten mit vier wiederkehrenden Symbolen tragen keine Information,
   kosten aber 158 px Hoehe, in der der Titel stehen kann.
   Reihenfolge: Kategorie -> Datum und Lesezeit -> Titel -> Teaser -> Leseverweis.
   Kein row-gap, jede Zeile setzt ihren eigenen Abstand - die vier Abstaende sind
   verschieden gross, ein gemeinsamer Wert traf keinen davon. */
.beitrag { display: flex; flex-direction: column; text-decoration: none; }
.beitrag .pille { align-self: flex-start; }
.beitrag-meta { margin-top: 16px; }
.beitrag h3 { margin-top: 10px; }
.beitrag h3 + .t-small { margin-top: 12px; }
/* Unten angeschlagen, damit die Karten einer Reihe auf derselben Linie enden,
   auch wenn der Titel zwei und der Teaser vier Zeilen laeuft. */
.beitrag-fuss {
  margin-top: auto; padding-top: 24px;
  display: inline-flex; align-items: center; column-gap: 8px;
  font-size: 15px; font-weight: 500; color: var(--ink);
}
a.beitrag:hover .beitrag-fuss { text-decoration: underline; text-underline-offset: 3px; }
a.beitrag:hover .beitrag-fuss .pfeil-rechts { transform: translateX(3px); }

/* Bleibt fuer blog-artikel.html - die nirgends verlinkte Altvorlage benutzt
   .beitrag-bild noch. Aus den erzeugten Seiten ist die Klasse verschwunden. */
.beitrag-bild {
  aspect-ratio: 16 / 9; border-radius: var(--r-karte-klein);
  overflow: hidden; background: var(--greige); border: 1px solid var(--rahmen);
}
.beitrag-bild img { width: 100%; height: 100%; object-fit: cover; }

/* Artikel */
/* Altvorlage blog-artikel.html - mitgezogen, damit beide gleich breit laufen. */
.artikel-spalte { max-width: 100%; }
.artikel-spalte h2 { font-size: 24px; font-weight: 600; line-height: 1.3; letter-spacing: -0.01em; margin-top: 32px; }
.artikel-spalte h3 { font-size: 19px; font-weight: 600; line-height: 1.35; margin-top: 22px; }
.artikel-spalte p  { font-size: 18px; line-height: 1.6; color: var(--grau); margin-top: 12px; }
.kurz-gesagt { background: var(--greige); border: 1px solid var(--rahmen); border-radius: var(--r-karte); padding: 24px; }
.kurz-gesagt li { font-size: 15px; line-height: 1.6; margin-top: 8px; }
.kurz-gesagt li::before { content: "·"; margin-right: 8px; }
.ivz { border-left: 2px solid var(--rahmen); padding: 4px 0 4px 20px; }
.ivz li { margin-top: 7px; }
.ivz a { font-size: 15px; text-decoration: underline; text-underline-offset: 3px; }
.tabelle { width: 100%; border-collapse: collapse; border: 1px solid var(--rahmen); border-radius: var(--r-karte-klein); overflow: hidden; }
.tabelle th, .tabelle td { text-align: left; font-size: 14px; padding: 11px 16px; }
.tabelle th { background: var(--greige); font-weight: 600; }
.tabelle td { color: var(--grau); border-top: 1px solid var(--rahmen); }
.autor { display: flex; align-items: center; column-gap: 14px; }
.autor-bild { width: 56px; height: 56px; border-radius: var(--r-pille); overflow: hidden; background: var(--neon); flex: 0 0 auto; }
.autor-bild img { width: 100%; height: 100%; object-fit: cover; }

/* ============================================================
   Über mich
   ============================================================ */
/* Bild von 400 auf 320: es trieb die Hero-Höhe auf 648 px, obwohl der Text
   links nur 340 braucht. Kleiner heisst hier auch weniger Leerraum daneben. */
/* Bildspalte 280 statt 320, Abstand 48 statt 56. Das Portrait war 384 px hoch,
   die Textspalte daneben nur 287 - knapp 100 px Luft unter dem Knopf. Mit 336 px
   Bildhoehe bleiben 49, und die Textspalte gewinnt 48 px Laufweite. */
/* Grundfassung einspaltig - Portrait ueber dem Namen. Das gilt auf dem
   HANDY (Marcels Ansage 11.8.); auf dem Schreibtisch stellt marcy-v2.css
   ab 992 px wieder auf zwei Spalten mit dem Bild rechts, so wie es war.

   Das Bild steht im Quelltext VOR dem Textblock. Dadurch stimmt die
   Vorlesereihenfolge mit dem Bild ueberein, und die Handyfassung braucht
   keine Umsortierung per Grid - nur die Desktopfassung setzt Spalten. */
.person-hero { display: grid; grid-template-columns: 1fr; gap: 24px; align-items: start; justify-items: start; }
/* Auf 872 px Laufweite blieb „umsetzt." als einzelnes Wort in der letzten Zeile
   stehen. text-wrap: pretty zieht ein Wort mit herunter; Browser ohne
   Unterstuetzung brechen wie bisher. */
.person-hero .t-lead { text-wrap: pretty; }
/* Rund und 340 px - dieselben Masse wie das Hero-Portrait des One-Pagers
   (`.hero-bild` in marcy-v2.css), auf Marcels Ansage vom 11.8. Vorher ein
   abgerundetes Rechteck 280 x 336 mit einem anderen Motiv.
   Grund fuer #000 statt --ink: die Quelle ist auf reines Schwarz gerechnet;
   bei #1A1A1A staende an der Kreiskante eine Aufhellung gegen das Bild. */
.person-hero-bild { width: 340px; aspect-ratio: 1; border-radius: 50%; overflow: hidden; background: #000; }
.person-hero-bild img { width: 100%; height: 100%; object-fit: cover; }
.themen { display: flex; flex-wrap: wrap; gap: 12px; }
/* Neon seit 10.8. auf Entscheidung von Marcel. Schwarze Schrift auf der Flaeche
   ergibt 14,34:1 - CI-Regel 6 ist damit farbrichtig erfuellt, aber es sind
   dreizehn Flaechen in einer Ansicht. Notiert in 01 Inhalte/_offen.md.
   Neon traegt auf Weiss und auf Greige gleich gut, die fruehere Umschaltung
   greige/weiss je Sektionsgrund ist deshalb entfallen. */
.thema { font-size: 14px; color: var(--ink); background: var(--neon); border-radius: var(--r-pille); padding: 8px 16px; }
.dreieck-halter { display: flex; justify-content: center; }
.werdegang-spalten { display: grid; grid-template-columns: 1fr 400px; gap: 48px; align-items: center; }
.geisterzahl { font-size: 13px; font-weight: 600; letter-spacing: 0.06em; color: var(--grau); }

/* ============================================================
   Fuss
   ============================================================ */
.fuss { background: var(--ink); color: var(--weiss); padding: 72px var(--rand) 40px; }
/* Der Fuss trug am 10.8. testweise reines Schwarz und ist zurueckgenommen:
   #1A1A1A dagegen sind 1,21:1 - derselbe Wert, mit dem wir Neon auf Weiss
   als unsichtbar verworfen haben. Der Gewinn ist nicht wahrnehmbar, der
   Preis waeren ein dritter Schwarzton in der Marke und die harte Kante
   gegen die weissen Sektionen, fuer die #1A1A1A gemacht ist.
   ES GIBT GENAU EIN SCHWARZ: --ink #1A1A1A. Nicht wieder aufteilen. */
.fuss-zeile { display: grid; grid-template-columns: 1fr auto auto auto; gap: 64px; }
.fuss-marke img { height: 26px; }
.fuss-claim { font-size: 15px; color: var(--grau-dunkel); margin-top: 16px; }
.fuss-spalte h4 { font-size: 14px; font-weight: 600; margin-bottom: 12px; }
.fuss-spalte li { font-size: 14px; line-height: 1.9; color: var(--grau-dunkel); }
.fuss-spalte a { color: var(--grau-dunkel); text-decoration: none; }
.fuss-spalte a:hover { color: var(--weiss); text-decoration: underline; text-underline-offset: 3px; }
.fuss-schluss { font-size: 13px; color: var(--grau-dunkel); margin-top: 20px; }

/* ============================================================
   Erscheinen beim Scrollen
   Nur opacity und ein kleiner Versatz. Sektionen, die alleiniger
   Träger einer Aussage sind, starten NICHT unsichtbar.
   ============================================================ */
.rv { opacity: 0; transform: translateY(16px); transition: opacity 400ms ease-out, transform 400ms ease-out; }
.rv.in { opacity: 1; transform: none; }
/* Notbremse: greift nur, wenn gar nichts ausgelöst hat */
.no-js .rv { opacity: 1; transform: none; }

/* Kartenversatz - layout.motion.stagger: 60 ms je Karte, hoechstens vier Stufen.
   Der Traeger bleibt sichtbar und bewegt sich nicht; nur seine Kinder kommen
   nacheinander. Das ist der neverHideContent-Waechter: Ueberschrift und
   Vorlauftext einer Sektion stehen sofort, auch wenn der Beobachter ausfaellt -
   unsichtbar starten duerfen nur die Karten, und die wiederholen nur, was die
   Ueberschrift schon gesagt hat. */
.rv.is-versetzt { opacity: 1; transform: none; transition: none; }
.rv.is-versetzt > * { opacity: 0; transform: translateY(16px); transition: opacity 400ms ease-out, transform 400ms ease-out; }
.rv.is-versetzt.in > * { opacity: 1; transform: none; }
.rv.is-versetzt.in > :nth-child(2) { transition-delay: 60ms }
.rv.is-versetzt.in > :nth-child(3) { transition-delay: 120ms }
.rv.is-versetzt.in > :nth-child(4) { transition-delay: 180ms }
.no-js .rv.is-versetzt > * { opacity: 1; transform: none; transition-delay: 0s }

/* ============================================================
   Hebung unter dem Zeiger
   MUSS hinter dem Erscheinen-Effekt stehen. `.rv.is-versetzt.in > *` setzt
   transform: none und hat dieselbe Spezifitaet wie `.karte.is-hebt:hover` -
   bei Gleichstand gewinnt die spaetere Regel. Weiter oben im Blatt liefe der
   Hover auf den Bausteinkarten der Startseite ins Leere.

   Werte aus marcy-ci.json -> layout.motion.cardHover: 200 ms, 8 px, kein
   Schatten. Bewusst nicht die 12 px von maxwbr.de - auf /portfolio haetten die
   klickbaren Fallkarten sonst einen anderen Hub als diese hier.
   ============================================================ */
.karte.is-hebt { transition: transform 200ms ease-out, border-color 200ms ease-out; }
.karte.is-hebt:hover,
.karte.is-hebt:focus-within { transform: translateY(-8px); }

/* Pillen sind kleiner als Karten, also 3 px statt 4. Dazu ein Schritt dunkler
   in der eigenen Palette - bei Neon ist das --neon-hover, derselbe Schritt, den
   die Primaerschaltflaeche geht. Auf Greige braucht es keine Sonderregel mehr. */
.thema:hover { transform: translateY(-5px); background: var(--neon-hover); }

/* ============================================================
   Rechtstexte - Impressum und Datenschutzerklaerung
   Der einzige Ort im Blatt mit langem Fliesstext. Ueber die volle
   Rasterbreite von 1200 px waeren das 130 Zeichen je Zeile; bei
   720 px sind es rund 75. Groessen und Durchschuss bleiben die der
   Typo-Skala, nur die Abstaende zwischen den Bloecken sind groesser.
   ============================================================ */
.recht { max-width: 720px; }
.recht > h2 { font-size: 24px; font-weight: 600; line-height: 1.30; letter-spacing: -0.01em; margin-top: 56px; }
.recht > h2:first-child { margin-top: 0; }
.recht > h3 { font-size: 18px; font-weight: 600; line-height: 1.40; margin-top: 28px; }
.recht p,
.recht ul,
.recht address { font-size: 16px; font-weight: 400; line-height: 1.55; font-style: normal; margin-top: 14px; }
.recht ul { list-style: disc; padding-left: 22px; }
.recht li { margin-top: 6px; }
.recht address { padding: 20px 22px; background: var(--greige); border-radius: var(--r-karte-klein); }
/* Links im Rechtstext tragen dieselbe Unterstreichung wie .link-unter -
   Farbe ist bei marcy nie das Signal fuer einen Link. */
.recht a { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.recht a:hover { color: var(--grau); }

/* Sichtbarer Platzhalter fuer fehlende Angaben. Absichtlich auffaellig und
   absichtlich ohne Neon - Neon ist Akzent, kein Warnzeichen (Regel 6 der CI).
   Steht eine .ph noch im Blatt, darf die Seite nicht live gehen. */
/* inline, nicht inline-block: ein langer Platzhalter muss umbrechen koennen,
   sonst schiebt er auf dem Telefon die Seite seitlich auf. box-decoration-break
   setzt Polster und Linie an jedem Zeilenstueck neu an. */
.ph {
  display: inline;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  padding: 1px 7px;
  background: var(--greige);
  border-bottom: 2px solid var(--chrome);
  border-radius: var(--r-badge);
  font-weight: 500;
}

/* ============================================================
   Bewegungsverzicht respektieren - nicht optional
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .rv { opacity: 1; transform: none; }
  .rv.is-versetzt > * { opacity: 1; transform: none; transition-delay: 0s !important; }
  .ablauf.is-gefuehrt .ablauf-schritt { opacity: 1; }
  .ablauf-schritt:not(:last-child)::after { transform: scaleY(1); }
  /* Laufband steht still. Fruehere Fassung verliess sich darauf, dass ein
     Satz ins Band passt - das galt bei vier Logos (1.173 px), bei sechs
     nicht mehr (1.509 px gegen 1.200 px sichtbar). Die letzten Logos lagen
     dann dauerhaft hinter der rechten Verlaufsmaske und waren fuer jeden
     mit aktiviertem "Bewegung reduzieren" UNSICHTBAR.
     Deshalb im Stillstand: zweiter Satz raus, Masken raus, Umbruch an -
     alle Marken stehen in zwei Reihen nebeneinander. */
  .laufband-spur { animation: none; width: 100%; }
  .laufband-satz[aria-hidden] { display: none; }
  .laufband::before, .laufband::after { display: none; }
  .laufband-satz {
    flex-wrap: wrap; justify-content: flex-start;
    column-gap: 56px; row-gap: 22px; padding-right: 0;
  }
  /* Der Zaehler wird in marcy.js abgefangen und setzt den Endwert direkt. */
  .fall:hover .browser-bild img,
  .fall:focus-within .browser-bild img { transform: none; }
  /* Die Hebung ist Bewegung - hier steht sie still. */
  .karte.is-hebt:hover, .karte.is-hebt:focus-within,
  .thema:hover { transform: none; }
}

/* ============================================================
   Breakpoints - nur die vier Webflow-Standards
   ============================================================ */
@media screen and (max-width: 991px) {
  :root { --rand: 40px; --sektion: 56px; }
  .t-h1 { font-size: 42px } .t-h2 { font-size: 32px } .t-h3 { font-size: 22px }
  .reihe-4 { grid-template-columns: repeat(2, 1fr) }
  .reihe-3, .reihe-2 { grid-template-columns: 1fr }
  .person-hero, .werdegang-spalten { grid-template-columns: 1fr }
  /* Einspaltig steht das Portrait unter dem Knopf. 300 px statt voller Breite
     aus demselben Grund wie bei .person-hero-bild: bei 768 px waere das ein
     bildschirmfuellendes Gesicht. */
  /* Einspaltig zog das Portrait auf volle Breite - bei 768 px waren das
     688 x 826 px, also ein bildschirmfuellendes Gesicht. Es behaelt seine
     Groesse und steht linksbuendig unter dem Text. */
  .person-hero-bild { max-width: 280px }
  .kennzahlen { grid-template-columns: repeat(2, 1fr); row-gap: 32px }
  .kennzahl + .kennzahl { border-left: 0; padding-left: 0 }
  .fuss-zeile { grid-template-columns: 1fr 1fr; gap: 40px }
  .nav-links { display: none }
  /* Schmaleres Band, schmalerer Abstand - sonst laeuft zwischen zwei Logos
     eine halbe Bildschirmbreite Leere durch. */
  .laufband-satz { column-gap: 84px; padding-right: 84px }
}
@media screen and (max-width: 767px) {
  :root { --rand: 20px; --sektion: 44px; }
  .t-h1 { font-size: 36px } .t-h2 { font-size: 28px }
  .reihe-4 { grid-template-columns: 1fr }
  .faelle { grid-template-columns: 1fr }
  .icon-gross { width: 56px; height: 56px }
  .browser-bild { height: 200px }
  .fall:hover .browser-bild img,
  .fall:focus-within .browser-bild img { transform: translateY(-700px); transition-duration: 12s }
  .fuss-zeile { grid-template-columns: 1fr }
  .bogen { width: 260px; height: 260px; top: -40px; right: -70px }
  .abschluss-foto { width: 72px; height: 72px }
  .abschluss h2 { margin-top: 16px }
}
@media screen and (max-width: 479px) {
  .t-h1 { font-size: 32px }
  .nav-pille { column-gap: 14px; padding-left: 18px }
}

/* Blogartikel - Kopfzeile, Fließtext, Listen, Definitionskasten.
   Ergänzt am 7.8.2026 für die aus 01 Inhalte/blog/ erzeugten Artikel.
   Die Kategorie-Pille war bis 10.8. greige, damit der Abschluss-Button der
   einzige Akzent der Ansicht bleibt (CI § 6). Seit 10.8. trägt sie auf
   Entscheidung von Marcel Neon mit schwarzer Schrift (14,34:1). Damit stehen
   auf der Übersicht elf Neonflächen in einer Ansicht - die Farbe ist regel-
   konform, die Anzahl nicht. Offen in 01 Inhalte/_offen.md. */
/* Artikelseiten stehen in einem eigenen, schmalen Raster.
   Vorher lief das Raster auf die volle Breite von 1200 px, waehrend der
   Fliesstext bei 720 px endet - die Differenz stand als 480 px Leere
   ausschliesslich RECHTS, weil alles linksbuendig im Raster klebte.
   Jetzt ist das Raster selbst 780 px breit; `.raster` bringt `margin: 0 auto`
   schon mit, damit sitzt Kopfzeile, H1, Vorlauf, Linie und Textspalte auf
   einer Achse und die Leere liegt gleich verteilt auf beiden Seiten.

   Am 11.8. auf Marcels Ansage aufgehoben: die Artikelsektion lief auf 780 px,
   waehrend „Weiterlesen" und Fuss die 1200 px des Rasters nutzten - der Text
   stand schmaler und an keiner Kante des uebrigen Seitenrasters. Jetzt laeuft
   er wie alles andere.

   Das kostet Lesbarkeit: bei 18 px Schrift traegt eine 1200-px-Zeile rund 130
   Zeichen, die typografische Spanne liegt bei 60 bis 80. Gemessener Wert steht
   in 01 Inhalte/_offen.md. *

.artikel-kopfzeile { display: flex; column-gap: 12px; align-items: center; flex-wrap: wrap; }
/* Fuellt das schmale Raster aus; die 960 px von vorher waren am 1200er Raster
   gemessen und wuerden hier nichts mehr begrenzen. */
.artikel-h1 { max-width: 100%; font-size: 46px; }
.artikel-antwort { max-width: 100%; font-size: 19px; }
.artikel-h2-gross { font-size: 28px; }
.artikel-spalte p a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.artikel-spalte p a:hover { color: var(--grau); }
.artikel-spalte p strong, .artikel-spalte li strong { font-weight: 500; color: var(--ink); }
.artikel-spalte .liste { margin-top: 14px; }
.liste li { position: relative; font-size: 17px; line-height: 1.55; color: var(--grau); margin-top: 9px; padding-left: 20px; }
.liste li::before { content: "\00b7"; position: absolute; left: 5px; color: var(--ink); font-weight: 600; }
.liste.is-haken li::before { content: "\2713"; left: 0; font-size: 13px; top: 1px; }
.liste li a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.definition { background: var(--greige); border: 1px solid var(--rahmen); border-radius: var(--r-karte); padding: 20px 24px; margin-top: 22px; }
.definition p { margin-top: 0; font-size: 17px; line-height: 1.55; color: var(--ink); }
.tabelle-halter { margin-top: 22px; overflow-x: auto; }
.tabelle-halter .tabelle { min-width: 480px; }

/* Datum und Lesezeit stehen seit 10.8. oben in der Karte und tragen .t-micro
   (11 px, Versalien, Sperrung) - eine eigene Größe braucht die Zeile nicht.
   Die Fußzeile trägt jetzt den Leseverweis, Regeln oben im Blog-Abschnitt. */

/* Der Artikel-H1 steht nach den Medienabfragen und wuerde deren t-h1-Stufen
   sonst ueberschreiben. Deshalb hier noch einmal, in derselben Leiter. */
@media screen and (max-width: 991px) {
  .artikel-h1 { font-size: 38px; max-width: 100%; }
  .artikel-h2-gross { font-size: 26px; }
}
@media screen and (max-width: 767px) {
  .artikel-h1 { font-size: 32px; }
  .artikel-antwort { font-size: 18px; }
  .artikel-spalte p { font-size: 17px; }
  .artikel-h2-gross { font-size: 24px; }
}
@media screen and (max-width: 479px) {
  .artikel-h1 { font-size: 28px; }
}

/* ============================================================
   Leuchten - weicher Neonschein, folgt dem Zeiger
   Portiert aus einer React/Tailwind-Vorlage. Dieses Projekt ist
   statisches HTML/CSS, deshalb CSS-Variablen statt React-State
   und eine Schicht, die marcy.js erzeugt.

   Liegt HINTER dem Inhalt (z-index 0), nie darueber - eine
   Neonflaeche ueber Text wuerde den Kontrast senken, und Neon
   darf nach CI nie Textfarbe beruehren.
   ============================================================ */
.leuchten {
  position: fixed; inset: 0; z-index: 0;
  pointer-events: none; overflow: hidden;
}
.leuchten-punkt {
  position: absolute; top: 0; left: 0;
  width: 460px; height: 460px; border-radius: 50%;
  /* Neon #CEFA05 als Flaeche, weich auslaufend. Der Spitzenwert ist
     bewusst gedeckelt: auf voller Neonflaeche faellt der graue
     Fliesstext #6B6B69 auf 4,42:1 und damit unter AA. */
  background: radial-gradient(circle,
    rgba(206,250,5,0.45) 0%,
    rgba(206,250,5,0.18) 40%,
    rgba(206,250,5,0) 70%);
  filter: blur(40px);
  transform: translate3d(calc(var(--lx, 50vw) - 50%), calc(var(--ly, 40vh) - 50%), 0);
  transition: transform 320ms cubic-bezier(.22,.61,.36,1),
              width 300ms ease-out, height 300ms ease-out,
              opacity 500ms ease;
  opacity: 0;
  will-change: transform;
}
/* Erst sichtbar, wenn der Zeiger das erste Mal bewegt wurde - sonst
   klebt der Schein beim Laden in der linken oberen Ecke. */
.leuchten.is-an .leuchten-punkt { opacity: 1; }
/* Schrumpft in der Bewegung, dehnt sich im Stillstand - wie in der Vorlage. */
.leuchten.is-bewegt .leuchten-punkt { width: 380px; height: 380px; }

/* Damit der Schein ueberhaupt zu sehen ist, duerfen die weissen
   Sektionen nicht mehr selbst weiss deckend sein - den Grund traegt
   jetzt der Body. Greige und Schwarz bleiben deckend und verdecken
   den Schein bewusst. */
.sektion { background: transparent; }

@media (prefers-reduced-motion: reduce) {
  .leuchten { display: none; }
}

/* ============================================================
   Startseite · „Das erwartet dich" - nummerierte Karten auf Schwarz
   Vorbild: soenkesproll.de/webflow-designer. Uebernommen ist die
   Struktur (Geisterzahl, Ueberschrift, kurzer Absatz, 3 × 2),
   nicht die Farbwelt: die Referenz laeuft schwarz mit Blau, marcy
   hat kein Blau - und seit dem 10.8. auch kein Schwarz an dieser
   Stelle. Karten nach layout.sectionRhythm.cardsOnBackground.onWhite
   - weiss mit Haarlinie #DCDAD6.
   KEIN Neon in dieser Sektion: sechs Akzente waeren sechs zu viel.
   ============================================================ */
.reihe-6 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.erwartung {
  position: relative;
  background: var(--weiss);
  border: 1px solid var(--rahmen);
  border-radius: var(--r-karte);
  padding: 34px 30px 30px;
}
/* Hover auf Marcels Ansage (10.8.), identisch mit `a.karte:hover`:
   8 px Hebung, Haarlinie dunkelt auf #1A1A1A. Die Karten sind KEINE Links -
   das widerspricht `interaktionen.md § 4` („Hover nur auf Klickbarem"),
   ist aber ausdruecklich so gewuenscht. */
.erwartung { transition: transform 200ms ease-out, border-color 200ms ease-out; }
.erwartung:hover { transform: translateY(-8px); border-color: var(--ink); }
/* Die grosse Zahl liegt als Ton-in-Ton-Marke im Hintergrund. Greige auf
   Weiss sind 1,20:1 - bewusst fast unsichtbar, wie zuvor #262626 auf
   Schwarz (1,17:1). Sie traegt keine Information, die Reihenfolge steht
   schon in der Leserichtung, deshalb ist sie aria-hidden und darf unter
   jedem Kontrastwert liegen.

   Am 10.8. war die Zahl kurz DAUERHAFT neon und ist zurueckgenommen: sechs
   gesaettigte Marken gleichzeitig ziehen mehr Aufmerksamkeit als eine
   Hintergrundmarke haben soll. Neon ist stattdessen in den Hover gewandert
   (unten) - dort steht immer nur EINE Zahl neon, weil immer nur eine Karte
   gehovert wird. Damit ist „ein Akzent pro Ansicht" erfuellt statt gebrochen. */
.erwartung-zahl {
  font-size: 56px; font-weight: 600; line-height: 1;
  letter-spacing: -0.03em; color: var(--greige);
  margin-bottom: 22px;
  transition: color 200ms ease-out;
}
/* Im Hover wird die Zahl neon. Das ist die einzige Stelle der Website, an
   der Neon Text einfaerbt - vertretbar, weil die Zahl keine Leseinformation
   ist: sie ist `aria-hidden`, die Reihenfolge steht in der Leserichtung,
   und der Kontrast bleibt bei 1,21:1 wie mit Greige (1,20:1). Es wechselt
   nur der Farbton, nicht die Lesbarkeit.
   NICHT als Beleg dafuer nehmen, dass Neon anderswo Text einfaerben darf:
   sobald etwas gelesen werden soll, ist 1,21:1 unbrauchbar. */
.erwartung:hover .erwartung-zahl { color: var(--neon); }
.erwartung p { margin-top: 12px; color: var(--grau); font-size: 14px; line-height: 1.55; }

/* ============================================================
   Startseite · „So laeuft dein Projekt" - Zeitstrahl I–IV
   Vorbild: derselbe Referenzabschnitt. Die Ziffern sind roemisch und
   schwarz, nicht neon: Neon darf nach CI nie Textfarbe sein, und vier
   Neonpunkte waeren vier Akzente in einer Ansicht.
   ============================================================ */
.ablauf { position: relative; }
.ablauf-schritt {
  position: relative; display: grid;
  grid-template-columns: 56px 1fr; column-gap: 28px; align-items: start;
}
.ablauf-schritt + .ablauf-schritt { margin-top: 40px; }
/* Das Verbindungsstueck haengt am Schritt, nicht an der Sektion: eine
   durchgehende Linie ueber die ganze Hoehe haette unter der letzten Ziffer
   einen Stummel stehen lassen. „bottom: -40px" ueberbrueckt genau den
   Abstand zum naechsten Schritt. Chrome statt Haarlinie, weil #DCDAD6 auf
   Greige 1,01:1 erreicht und unsichtbar waere (hairlineOnGreige). */
.ablauf-schritt:not(:last-child)::before,
.ablauf-schritt:not(:last-child)::after {
  content: ""; position: absolute; left: 27px; top: 56px; bottom: -40px; width: 1px;
}
.ablauf-schritt:not(:last-child)::before { background: var(--chrome); }
/* Die Fuellung waechst beim Scrollen ueber die graue Grundlinie - das ist
   der Fortschrittsbalken der Referenz, nur ohne GSAP.
   scaleY statt height, weil die Segmenthoehe vom Textumbruch abhaengt und
   nicht als fester Wert ausdrueckbar ist. Die CI-Regel „keine Skalierung
   ueber 1,02" meint Elemente, die beim Erscheinen aufploppen - eine 1 px
   breite Linie, die sich zeichnet, ist kein skaliertes Objekt. */
.ablauf-schritt:not(:last-child)::after {
  background: var(--ink);
  transform: scaleY(0); transform-origin: top center;
  transition: transform 550ms ease-out;
}
.ablauf-schritt.is-erreicht:not(:last-child)::after { transform: scaleY(1); }

/* Abblenden nur, wenn JavaScript laeuft: die Klasse setzt marcy.js.
   Ohne sie stehen alle vier Schritte voll lesbar da - faellt das Skript
   aus, fehlt die Bewegung, nicht der Inhalt (interaktionen.md § 5).
   0,45 statt der 0,25 der Referenz: bei 0,25 waere der graue Fliesstext
   auf Greige nicht mehr lesbar, waehrend er noch im Bild steht. */
.ablauf.is-gefuehrt .ablauf-schritt { opacity: 0.45; transition: opacity 400ms ease-out; }
.ablauf.is-gefuehrt .ablauf-schritt.is-erreicht { opacity: 1; }
/* Drei Zustaende je Station, wie im Stepper der Vorlage: noch nicht dran,
   dran, erledigt. Die Vorlage faerbt den erreichten Punkt in ihrer
   Akzentfarbe - hier ist das Neon als FLAECHE mit schwarzer Ziffer
   (14,34:1). Damit greift die CI-Regel, nicht ihre Ausnahme: Neon traegt
   Flaeche, nie Linie und nie Schrift.

   Am 7.8. umgestellt. Vorher stand hier „Kein Neon: vier Neonpunkte waeren
   vier Akzente in einer Ansicht." Auf Marcels Ansage aufgegeben - mit
   derselben Begruendung wie bei den fuenf Schrittziffern auf /leistungen:
   vier gleiche Stationen sind ein Bauteil in Wiederholung, nicht vier
   Einzelakzente. Der Primaerknopf im Abschluss bleibt der einzige weitere
   Neontraeger der Seite. */
.ablauf.is-gefuehrt .ablauf-ziffer {
  border: 1.5px solid var(--chrome); color: var(--grau);
  transition: background 400ms ease-out, border-color 400ms ease-out, color 400ms ease-out;
}
.ablauf.is-gefuehrt .is-erreicht .ablauf-ziffer {
  background: var(--neon); border-color: var(--neon); color: var(--ink);
}
/* Ohne JavaScript sind alle Stationen erreicht - dann tragen alle Neon,
   sonst waere die Sektion grau und der Effekt spurlos verschwunden. */
.ablauf:not(.is-gefuehrt) .ablauf-ziffer { background: var(--neon); }
/* Weisser Kreis auf Greige - nach CI die Kartenfuellung fuer greige Flaechen.
   Vorher trug die Ziffer Greige auf Greige und stanzte nur ein Loch in die
   Linie; das las sich als Abriss statt als Station. */
.ablauf-ziffer {
  position: relative; z-index: 1;
  width: 56px; height: 56px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--weiss); border-radius: var(--r-pille);
  font-size: 18px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--ink);
}
.ablauf-text h3 { margin-top: 14px; }
.ablauf-text p { margin-top: 10px; max-width: 620px; }

@media screen and (max-width: 991px) {
  .reihe-6 { grid-template-columns: repeat(2, 1fr); }
}
@media screen and (max-width: 767px) {
  .reihe-6 { grid-template-columns: 1fr; }
  .ablauf-schritt { grid-template-columns: 44px 1fr; column-gap: 18px; }
  .ablauf-schritt:not(:last-child)::before { left: 21px; top: 44px; bottom: -32px; }
  .ablauf-schritt + .ablauf-schritt { margin-top: 32px; }
  .ablauf-ziffer { width: 44px; height: 44px; font-size: 16px; }
}

/* ============================================================
   Herausforderungen - nummerierte Zeilen mit Haarlinie
   Vorbild: soenkesproll.de/webflow-designer. Uebernommen ist die
   STRUKTUR (Nummer, eine Aussage je Zeile, Linie dazwischen),
   nicht die Optik - dort blaues Kursiv, hier Inter in Ink.
   Kursiv ist nach CI ausgeschlossen, und Blau ist nicht marcy.

   Aussage und Nummer stehen beide in --ink, nicht in --grau:
   --grau kommt auf Greige nur auf 4,44:1 und reisst AA. Die
   Hierarchie laeuft ueber das Gewicht, nicht ueber die Farbe.
   ============================================================ */
.hf {
  list-style: none; margin: 0; padding: 0;
  max-width: 760px;
  border-top: 1px solid var(--rahmen);
}
.hf li {
  position: relative;
  display: flex; column-gap: 18px; align-items: baseline;
  padding: 21px 0;
  border-bottom: 1px solid var(--rahmen);
  font-size: 18px; line-height: 1.45;
  /* Abgesenkter Zustand. Der Effekt laeuft ueber die FARBE, nicht ueber
     opacity: bei opacity dimmt die Haarlinie mit und das Raster flackert.
     #636362 ist der dunkelste Wert, der auf Greige noch AA haelt -
     genau 5,00:1. Die Vorlage nimmt 35 % Deckkraft, das waere hier
     2,15:1 und damit unlesbar. Nicht heller setzen. */
  color: #636362;
  transition: color 260ms ease;
}
.hf li.is-aktiv { color: var(--ink); }   /* 14,48:1 */

/* Fortschrittsbalken auf der Grundlinie der aktiven Zeile - das Gegenstueck
   zum `progress`-State der Vorlage. Er laeuft ueber die vorhandene
   Haarlinie, es kommt also kein Bauteil dazu.
   Als ANIMATION, nicht als Transition: nur eine Animation laesst sich mit
   `animation-play-state` anhalten. Und sie ist gleichzeitig die UHR - ihr
   `animationend` schaltet die naechste Zeile frei (marcy.js § 9). Damit
   koennen Balken und Takt nicht auseinanderlaufen, was bei einem
   getrennten setInterval unvermeidlich waere. */
.hf { --hf-dauer: 3500ms; }
.hf li::after {
  content: ""; position: absolute; left: 0; bottom: -1px;
  height: 1px; width: 100%; background: var(--ink);
  transform: scaleX(0); transform-origin: left center;
}
.hf li.is-aktiv::after { animation: hf-fortschritt var(--hf-dauer) linear forwards; }
/* Angehalten, solange die Maus darauf steht oder die Liste ausserhalb des
   Bildes ist - wer liest, soll nicht weitergeschaltet werden, und ausserhalb
   des Bildes laeuft nichts ins Leere. */
.hf.is-pause li.is-aktiv::after { animation-play-state: paused; }
@keyframes hf-fortschritt { from { transform: scaleX(0) } to { transform: scaleX(1) } }
.hf-nr {
  flex: 0 0 auto;
  font-weight: 500; font-variant-numeric: tabular-nums;
  color: inherit;
}
@media (prefers-reduced-motion: reduce) {
  .hf li { transition: none; }
  /* Kein laufender Balken. Nicht auf scaleX(1) setzen - ohne Durchschalten
     gibt es keine „aktive" Zeile, ein Balken waere dann eine Behauptung. */
  .hf li::after { animation: none; transform: scaleX(0); }
}
@media screen and (max-width: 767px) {
  .hf li { font-size: 17px; padding: 18px 0; column-gap: 14px; }
}

/* ============================================================
   Startseite · Kundenstimmen als Laufband
   Portiert aus einer React/Tailwind-Vorlage (testimonials-with-
   marquee). Dieses Projekt ist statisches HTML/CSS, deshalb
   dieselbe Mechanik wie beim Logo-Laufband: zwei identische
   Saetze, Animation ueber genau eine Satzbreite, Naht unsichtbar.

   Aus der Vorlage NICHT uebernommen:
   - `bg-gradient-to-b` auf den Karten. Die CI verbietet Farb-
     verlaeufe; die Karten bleiben flaechig weiss mit Haarlinie.
   - zentrierte Ueberschrift. Alle anderen Sektionen der Seite
     setzen links an.
   - vier Kartensaetze. Zwei reichen fuer eine fugenlose Schleife
     und laden halb so viel.
   Die Verlaufsmasken an den Raendern sind uebernommen - sie sind
   keine Dekoration, sondern verhindern die harte Schnittkante.
   ============================================================ */
/* Volle Breite: bricht aus der Sektionspolsterung aus, damit das Band
   von Rand zu Rand laeuft. .sektion hat overflow:hidden, das haelt. */
.stimmen-band {
  position: relative; overflow: hidden;
  margin-left: calc(var(--rand) * -1);
  margin-right: calc(var(--rand) * -1);
  /* Senkrecht Luft, damit die gehobene Karte im Hover nicht an der
     Schnittkante haengt. `overflow: hidden` schneidet beide Achsen - eine
     reine x-Beschneidung gibt es in CSS nicht (overflow-x:hidden mit
     overflow-y:visible rechnet der Browser zu `auto` um und setzt eine
     Bildlaufleiste). Die 14 px sind der 8-px-Hub plus Reserve; die
     negativen Aussenabstaende holen die Hoehe wieder heraus, damit die
     Sektion nicht wandert. */
  padding-top: 14px; padding-bottom: 14px;
  margin-top: -14px; margin-bottom: -14px;
}
.stimmen-band::before, .stimmen-band::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 140px;
  z-index: 2; pointer-events: none;
}
.stimmen-band::before { left: 0;  background: linear-gradient(90deg,  var(--greige), rgba(235,234,232,0)); }
.stimmen-band::after  { right: 0; background: linear-gradient(270deg, var(--greige), rgba(235,234,232,0)); }
.stimmen-spur { display: flex; width: max-content; animation: stimmenband 46s linear infinite; }
/* Anhalten beim Zeigen - ohne das waere eine Karte ein bewegtes Klickziel. */
.stimmen-band:hover .stimmen-spur,
.stimmen-band:focus-within .stimmen-spur { animation-play-state: paused; }
.stimmen-satz { display: flex; align-items: stretch; column-gap: 24px; padding-right: 24px; }
/* Feste Breite: im Raster fuellte die Karte eine Spalte, im Band braucht
   sie ein Mass. 380 statt der 320 der Vorlage, weil die Zitate hier
   drei bis vier Zeilen lang sind und die Karte sonst zu hoch wird. */
.stimmen-satz .stimme { width: 380px; flex: 0 0 380px; }
/* Rechts nach links wie in der Vorlage. Das Logo-Laufband im Hero laeuft
   andersherum - das ist Absicht, nicht Zufall: zwei Baender in derselben
   Richtung wirken wie ein durchlaufender Streifen ueber die ganze Seite. */
@keyframes stimmenband { from { transform: translateX(0) } to { transform: translateX(-50%) } }

@media screen and (max-width: 767px) {
  .stimmen-band::before, .stimmen-band::after { width: 48px; }
  .stimmen-satz .stimme { width: 300px; flex: 0 0 300px; }
}
@media (prefers-reduced-motion: reduce) {
  .stimmen-spur { animation: none; }
}

/* ============================================================
   Schriftgroessen auf dem Telefon zuruecknehmen
   Marcels Rueckmeldung 11.8.: „manche Texte wirken zu gross".
   Gemessen bei 375 px vor der Aenderung: FAQ-Frage 20 px bei
   Gewicht 600 auf zwei Zeilen, Fuss-Fliesstext 14/15 px mit
   Zeilenabstand 1,9. Auf 375 px Breite ist das dieselbe Stufe
   wie eine Zwischenueberschrift - auf dem Rechner traegt die
   Spaltenbreite das, auf dem Telefon nicht.
   Nur Groessen und Zeilenabstaende, keine Farben und keine
   Abstaende der Sektionen.
   ============================================================ */
@media screen and (max-width: 767px) {
  /* Frage: 20 → 17. Bleibt deutlich ueber dem Fliesstext (16,5) und
     damit als Frage erkennbar, ohne wie eine Sektionsueberschrift
     zu wirken. Der Plus-Marker rueckt naeher, damit zweizeilige
     Fragen mehr Zeile haben. */
  .frage > summary { font-size: 17px; }
  .frage > summary::after { margin-left: 14px; }
  .frage { padding: 18px 20px; }
  .frage-antwort { font-size: 16px; }

  /* Fuss: eine Stufe kleiner, Zeilenabstand von 1,9 auf 1,7.
     Der lockere Abstand war fuer drei enge Spalten gedacht; auf
     dem Telefon stehen die Spalten breit und die Liste wirkt
     dadurch gross. Farben unveraendert - #ADADAB auf Ink haelt
     7,74:1 auch bei 13,5 px. */
  .fuss-claim { font-size: 14px; }
  .fuss-spalte h4 { font-size: 13px; }
  .fuss-spalte li { font-size: 13.5px; line-height: 1.7; }
  .fuss-schluss { font-size: 12.5px; }
}
