/* =============================================================
   VOELKEL – Design System
   Typografie: Hanken Grotesk (display + body + Hero-Buchstaben-Portal) + Libre Caslon Text Italic (Akzent).

   Breakpoints (Zielraster): 480 · 640 · 768 · 900 · 1024 · 1440.
   Hero-spezifische Regeln nutzen bewusst 767px (nicht 768px) — passend
   zu isMobile in script.js, das dieselbe Grenze per matchMedia liest.
   Bekannter Ausreißer: .referenz-grid/.sizes-Attribut auf
   den Referenz-Bildern nutzt weiterhin 700px (an das 502px/2-Spalten-
   Layout gekoppelt) — Umstellung auf 640px verschöbe den Spaltenwechsel und
   bräuchte eine Live-Sichtprüfung im 640–700px-Bereich, bewusst zurückgestellt.
   ============================================================= */

/* ─── FONTS (selbst gehostet, DSGVO: keine Verbindung zu Google) ─ */
@font-face {
  font-family:  'Hanken Grotesk';
  font-style:   normal;
  font-weight:  400 700;
  font-display: swap;
  src: url("fonts/hanken-grotesk-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2192, U+2193, U+2212, U+2215, U+22EE, U+2605, U+FEFF, U+FFFD;
}
@font-face {
  font-family:  'Hanken Grotesk';
  font-style:   normal;
  font-weight:  400 700;
  font-display: swap;
  src: url("fonts/hanken-grotesk-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family:  'Libre Caslon Text';
  font-style:   italic;
  font-weight:  400;
  font-display: swap;
  src: url("fonts/libre-caslon-text-italic-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2192, U+2193, U+2212, U+2215, U+22EE, U+2605, U+FEFF, U+FFFD;
}
@font-face {
  font-family:  'Libre Caslon Text';
  font-style:   italic;
  font-weight:  400;
  font-display: swap;
  src: url("fonts/libre-caslon-text-italic-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ─── TOKENS ─────────────────────────────────────────────── */
:root {
  /* Farben */
  --c-bg:         #FCFCFD; /* kuehles Fast-Weiss. Bewusst 3 Stufen unter --c-card (#FFFFFF): randlose Karten leben allein von diesem Abstand */
  --c-navy:       #14213D;
  --c-navy-deep:  #0E1827;
  --c-navy-hover: #1E3358; /* Button-Hover/Active: heller als --c-navy, bleibt in der Navy-Familie statt eine neue Flächenfarbe einzuführen */
  --c-accent:        #2E4A85; /* ersetzt Gold: Text-Hover/Fokus/Icons UND Verlauf-Mitte des Leucht-Akzents (8.4:1 auf #FCFCFD) */
  --c-accent-hover:  #3D5C9C;
  --c-accent-light:  #4A6BB0; /* Verlauf-Anfang (hellste Stelle) des Leucht-Akzents, 5.1:1 auf #FCFCFD */
  --c-accent-glow:   rgba(46, 74, 133, .35);
  --c-accent-bright: #9FB6E8; /* dunkler-Grund-Variante: nur für UI auf dem Navy-Hero (Buchstaben-Portal-Auswahl), 7.9:1 auf #14213D */
  --c-accent-light-ondark: #E7EDFB; /* Verlauf-Anfang auf Navy-Karten, 13.6:1 */
  --c-accent-deep-ondark:  #7B94D1; /* Verlauf-Ende auf Navy-Karten, 5.3:1 — laeuft bewusst nicht bis zur Hintergrundfarbe aus */
  --c-accent-glow-ondark:  rgba(159, 182, 232, .5);
  --c-text:       #1A1A1A;
  --c-muted:      #5C5852;
  --c-light:      #FAFAF8;
  --c-card:       #FFFFFF;
  --c-border:     rgba(26, 26, 26, 0.08);
  /* Ziegelrot statt Signalrot: wirkt auf der hellen Fläche nicht wie eine
     Fehlermeldung (6.0:1 auf #FCFCFD). Nur für die Kreuze der Problem-Punkte. */
  --c-negative:   #A6402F;

  /* Typografie */
  --f-display: 'Hanken Grotesk', system-ui, sans-serif;
  --f-body:    'Hanken Grotesk', system-ui, -apple-system, sans-serif;
  --f-portal:  'Hanken Grotesk', system-ui, sans-serif; /* Hero-Buchstaben-Portal (.hp-static), muss mit CFG.fontSpec in script.js uebereinstimmen */
  --f-accent:  'Libre Caslon Text', Georgia, serif;
  --tr-accent: -0.055em; /* Serif enger gesetzt als die Sans, siehe Referenz-Analyse skool/akquise */

  /* Typoskala */
  --t-xs:   0.75rem;     /* 12 */
  --t-sm:   0.875rem;    /* 14 */
  --t-base: 1rem;        /* 16 */
  --t-lg:   1.125rem;    /* 18 */
  --t-xl:   clamp(1.25rem, 4.5vw, 1.375rem);   /* 20 → 22 */
  --t-2xl:  clamp(1.5rem, 6vw, 1.875rem);      /* 24 → 30 */
  --t-3xl:  clamp(1.75rem, 4.8vw, 3.5rem);

  /* Spacing (4/8-Raster) */
  --s-1:  0.25rem;
  --s-2:  0.5rem;
  --s-3:  0.75rem;
  --s-4:  1rem;
  --s-5:  1.25rem;
  --s-6:  1.5rem;
  --s-8:  2rem;
  --s-10: 2.5rem;
  --s-12: 3rem;
  --s-16: 4rem;
  --s-20: 5rem;
  --s-24: 6rem;
  --s-32: 8rem;

  /* Layout */
  --max-w:        1240px;
  --max-w-narrow: 680px;
  /* Boden auf 3.5rem (statt 5rem) abgesenkt: unter ~800px Viewportbreite
     greift ohnehin immer der Boden (10vw bleibt unter 5rem), macht auf dem
     Handy sonst 80px Padding oben UND unten in jeder der zwölf Sektionen. */
  --sec-pad:      clamp(var(--s-14), 10vw, var(--s-32));
  --gutter:       clamp(var(--s-4), 4vw, var(--s-6));

  /* Radius */
  --r-sm: 8px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-xl: 32px;

  /* Schatten */
  --shadow-card:       0 1px 4px rgba(20,33,61,.05), 0 4px 16px rgba(20,33,61,.07);
  --shadow-card-hover: 0 2px 8px rgba(20,33,61,.09), 0 8px 28px rgba(20,33,61,.13);

  /* Übergänge */
  --tr-fast: 150ms ease;
  --tr-base: 250ms ease;

  /* Z-Ebenen */
  --z-base:       0;
  --z-hero-mesh:  0;   /* WebGL canvas – unterste Ebene im Hero */
  --z-hero-svg:   1;   /* SVG-Linien über dem Canvas */
  --z-hero:       2;   /* Textinhalt über allem */
  --z-header:   100;

  /* Ergänzter Spacing-Schritt */
  --s-14: 3.5rem;
}

/* ─── RESET ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 100px; /* Freiraum für die fixe Header-Pille bei Anker-Sprüngen */
  -webkit-text-size-adjust: 100%;
}

/* Scroll-Lock, solange ein modaler Overlay offen ist (Cookie-Banner,
   mobiles Menü) — siehe consent.js/script.js. */
html.has-modal-open {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration:        0.01ms !important;
    animation-delay:           0ms    !important;
    animation-iteration-count: 1      !important;
    transition-duration:       0.01ms !important;
    transition-delay:          0ms    !important;
  }
}

body {
  font-family:              var(--f-body);
  font-size:                var(--t-base);
  line-height:              1.65;
  color:                    var(--c-text);
  background-color:         var(--c-bg);
  -webkit-font-smoothing:   antialiased;
  -moz-osx-font-smoothing:  grayscale;
}

/* Der Leucht-Effekt am Porträt (.edge-light, 50 px über den Kartenrand)
   ragte bei 800–1300 px Breite über das Fenster hinaus und erzeugte einen
   waagerechten Scrollbalken. Am Inhaltsbereich gekappt, nicht am Body:
   dort würde es zum Fenster-Overflow. clip statt hidden: kein Scroll-
   Container, position:sticky (Hero, Ablauf) bleibt intakt. */
main { overflow-x: clip; }

/* height:auto als Default: width+height-Attribute (reservieren die Box
   gegen CLS) skalieren so proportional mit, statt zu verzerren. Einzelne
   Bilder (.portrait-wrap img, .call-tile img, ...) überschreiben das
   gezielt mit eigener Höhe/object-fit, per Klassenselektor spezifischer
   als dieser Reset. */
img      { height: auto; }
img, svg { display: block; max-width: 100%; }
a        { color: inherit; text-decoration: none; }
ul       { list-style: none; }
address  { font-style: normal; }

/* Braucht !important: die Browser-Regel [hidden] { display: none } hat dieselbe
   Spezifität wie ein Klassenselektor, und Autor-CSS schlägt das
   User-Agent-Stylesheet immer. Jede display-Regel auf einer Klasse hebelt das
   Attribut damit still aus — genau daran blieb die Cal.com-Ersatzkarte
   (.cal-consent-gate, display:flex) trotz gate.hidden = true stehen. */
[hidden] { display: none !important; }

/* ─── SKIP LINK ──────────────────────────────────────────── */
.skip-link {
  position:      absolute;
  top:          -100%;
  left:          var(--s-4);
  background:    var(--c-accent);
  color:         var(--c-navy);
  padding:       var(--s-2) var(--s-4);
  border-radius: var(--r-sm);
  font-size:     var(--t-sm);
  font-weight:   600;
  z-index:       9999;
}
.skip-link:focus,
.skip-link:focus-visible { top: var(--s-4); }
.skip-link:hover  { background: var(--c-accent-hover); }
.skip-link:active { transform: scale(0.97); }

/* ─── AKZENT STUFE 1: KURSIVE SERIF ──────────────────────────
   Jedes <em> wird automatisch zur kursiven Serif und erbt die
   Textfarbe — nie eingefärbt. Trägt so auf jedem Grund gleich. */
em {
  font-family:    var(--f-accent);
  font-style:     italic;
  font-weight:    400;
  letter-spacing: var(--tr-accent);
  color:          inherit;
}

/* ─── AKZENT STUFE 2: NAVY MIT LEUCHTEN ──────────────────────
   Verlaufstext + weicher Schein, aber in derselben Schrift wie
   der Rest — nie kursiv/serif kombiniert (siehe Referenz-Analyse:
   skool trennt beide Mechanismen strikt, akquise nicht — hier
   bewusst dem strengeren Modell gefolgt). Für helle Flächen
   kalibriert; auf Navy-Grund würde der dunkle Verlaufsteil
   verschwinden — dort nicht ungeprüft einsetzen. */
.text-accent {
  background-image: linear-gradient(100deg, var(--c-accent-light) 0%, var(--c-accent) 55%, var(--c-navy) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  text-shadow: 0 0 14px var(--c-accent-glow), 0 0 3px var(--c-accent-glow);
  font-weight: 600;
}

/* Variante für Navy-Karten (z.B. .kontakt-hero): heller Verlauf statt
   dunkel, sonst verschwindet das Verlaufsende im gleichfarbigen Grund. */
.text-accent--dark {
  background-image: linear-gradient(100deg, var(--c-accent-light-ondark) 0%, var(--c-accent-bright) 55%, var(--c-accent-deep-ondark) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  text-shadow: 0 0 16px var(--c-accent-glow-ondark), 0 0 4px rgba(255,255,255,.35);
  font-weight: 600;
}

/* ─── LAYOUT HELPERS ─────────────────────────────────────── */
.container {
  width:          100%;
  max-width:      var(--max-w);
  margin-inline:  auto;
  padding-inline: var(--gutter);
}

/* narrow inner wrapper – used inside .container */
.container-narrow {
  max-width:     var(--max-w-narrow);
  margin-inline: 0;          /* left-aligned on light sections */
}

.section-problem .container-narrow {
  margin-inline: auto;
  text-align:    center;
}

/* Der Abschnitt setzt direkt an der Unterkante des Hero-Portals an. Das
   Radial von .section-light steht an seiner Oberkante schon fast voll und
   ist dort zudem waagerecht ungleich (warme Mitte, blasse Ecken) — gegen die
   gleichmäßige Endfarbe des Portals ergab das eine sichtbare Kante.
   Deshalb hier eine zusätzliche Deckschicht: oben exakt die Farbe, mit der
   das Portal aufhört (--c-bg + 6,2% Akzent), über 220px nach transparent. Als
   Background-Layer, nicht als ::before — so bleibt der Inhalt ohne
   z-index-Akrobatik darüber. Beide Klassen im Selektor, sonst gewinnt das
   später notierte .section-light bei gleicher Spezifität. */
.section-light.section-problem {
  background:
    linear-gradient(to bottom, rgb(239, 241, 246) 0, rgba(239, 241, 246, 0) 220px),
    radial-gradient(circle at 50% 40%, rgba(46, 74, 133, 0.07) 0%, transparent 68%),
    var(--c-bg);
}

/* ─── BUTTONS ────────────────────────────────────────────── */
.btn {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  gap:              var(--s-2);
  font-family:      var(--f-body);
  font-size:        var(--t-base);
  font-weight:      600;
  letter-spacing:   0.01em;
  line-height:      1;
  padding:          var(--s-4) var(--s-8);
  border-radius:    9999px; /* Shape-Lock: alle CTAs sind Pills */
  border:           1.5px solid transparent;
  cursor:           pointer;
  white-space:      nowrap;
  min-height:       48px;
  -webkit-tap-highlight-color: transparent;
  touch-action:     manipulation;
  transition:
    background-color var(--tr-fast),
    color            var(--tr-fast),
    border-color     var(--tr-fast),
    box-shadow       var(--tr-fast),
    transform        var(--tr-fast);
}

.btn:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 3px;
}

/* Pill CTA – used in header. Nur ab 768px sichtbar (siehe .header-pill
   .btn-header{display:none} weiter unten), das schließt aber Tablets mit
   Touch nicht aus — deshalb 44px Mindesthöhe und Hover hinter
   (hover:hover) gekapselt, damit die Hover-Füllung nach dem Antippen nicht
   hängen bleibt. */
.btn-header {
  background-color: var(--c-navy);
  color:            var(--c-light);
  border-color:     var(--c-navy);
  border-radius:    9999px;
  font-size:        var(--t-sm);
  min-height:       44px;
  padding:          var(--s-2) var(--s-5);
  white-space:      nowrap;
  touch-action:     manipulation;
}
@media (hover: hover) and (pointer: fine) {
  .btn-header:hover {
    background-color: var(--c-navy-hover);
    border-color:     var(--c-navy-hover);
    color:            var(--c-light);
    transform:        none;
    box-shadow:       none;
  }
  .site-header.is-scrolled .btn-header:hover {
    background-color: #FFFFFF;
    border-color:     #FFFFFF;
    color:            var(--c-navy);
  }
}
.btn-header:active {
  background-color: var(--c-navy-hover);
  border-color:     var(--c-navy-hover);
  color:            var(--c-light);
}

/* Gescrollt ist die Pill selbst Navy: ein Navy-Button verschwände darin.
   Hell gefüllt, damit er als Knopf erkennbar bleibt. */
.site-header.is-scrolled .btn-header {
  background-color: var(--c-light);
  border-color:     var(--c-light);
  color:            var(--c-navy);
}
.site-header.is-scrolled .btn-header:active {
  background-color: #FFFFFF;
  border-color:     #FFFFFF;
  color:            var(--c-navy);
}

/* Navy – primary CTA */
.btn-navy {
  background-color: var(--c-navy);
  color:            var(--c-light);
  border-color:     var(--c-navy);
}
.btn-navy:hover {
  background-color: var(--c-navy-hover);
  transform:        translateY(-1px);
  box-shadow:       0 4px 16px rgba(20,33,61,.35);
}
.btn-navy:active { transform: translateY(0); }

/* Creme-gefüllt – Primary-CTA für Stellen auf dunklem Grund (aktuell nur der Hero). */
.btn-light {
  background-color: var(--c-light);
  border-color:     var(--c-light);
  color:            var(--c-navy);
}
.btn-light:hover {
  transform:  translateY(-1px);
  box-shadow: 0 4px 16px rgba(20, 33, 61, .18);
}
.btn-light:active { transform: translateY(0); }

/* Outline – secondary CTA on light bg */
.btn-outline {
  background-color: transparent;
  color:            var(--c-navy);
  border-color:     var(--c-navy);
}
.btn-outline:hover,
.btn-outline:active {
  background-color: var(--c-navy);
  color:            var(--c-light);
}

/* Outline – secondary CTA on dark/navy backgrounds */
.btn-outline-light {
  background-color: transparent;
  color:            var(--c-light);
  border-color:     rgba(243, 240, 234, 0.45);
}
.btn-outline-light:hover,
.btn-outline-light:active {
  background-color: var(--c-light);
  color:            var(--c-navy);
  border-color:     var(--c-light);
}

/* ─── SHARED TYPOGRAPHY ──────────────────────────────────── */
.headline-display {
  font-family:    var(--f-display);
  font-size:      var(--t-3xl);
  font-weight:    600;
  line-height:    1.15;
  letter-spacing: -0.03em;
  color:          var(--c-text);
  margin-bottom:  var(--s-8);
}

.headline-light  { color: var(--c-light); }

.headline-mid {
  font-family:    var(--f-display);
  font-size:      var(--t-xl);
  font-weight:    600;
  line-height:    1.3;
  letter-spacing: -0.02em;
  color:          var(--c-text);
  margin-bottom:  var(--s-4);
}

.eyebrow {
  font-family:    var(--f-body);
  font-size:      var(--t-xs);
  font-weight:    600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color:          var(--c-accent);
  margin-bottom:  var(--s-4);
}

.body-text {
  font-size:  var(--t-lg);
  line-height: 1.78;
  color:       var(--c-text);
  max-width:   60ch;
}

.body-text--muted { color: var(--c-muted); }
.body-text--light { color: rgba(243,240,234,.82); }

/* ─── SCROLL FADE-IN ─────────────────────────────────────── */
.fade-in {
  opacity:          0;
  transform:        translateY(22px) scale(0.97);
  transition:
    opacity   0.55s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: var(--reveal-delay, 0ms);
}
.fade-in.is-visible {
  opacity:   1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .fade-in { opacity: 1; transform: none; transition: none; }
}

/* =============================================================
   HEADER
   ============================================================= */
.site-header {
  position:           fixed;
  inset-block-start:  0;
  inset-inline:       0;
  z-index:            var(--z-header);
  display:            flex;
  justify-content:    center;
  padding-block-start: var(--s-4);
  padding-inline:     var(--gutter);
  pointer-events:     none;
  transition:
    transform 400ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity   400ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Im Kontaktbereich ausblenden: der Pill-CTA würde sonst den
   identischen Formular-CTA überlappen (Doppel-CTA-Kollision).
   Nur ab Tablet: .btn-header (der CTA in der Pill) ist unter 768px
   ohnehin display:none — der Kollisionsgrund existiert auf dem Handy gar
   nicht, würde dort aber das Burger-Menü für die ganze Kontaktsektion
   unerreichbar machen. */
@media (min-width: 768px) {
  .site-header.is-suppressed {
    transform: translateY(-120%);
    opacity:   0;
  }
  .site-header.is-suppressed .header-pill { pointer-events: none; }
}

/* Im Eröffnungsbild des Hero ausblenden: dort trägt die Bühne ihre eigene
   Kopfzeile (.hp-toprow, Bildmarke + Kategorie), die Pill wäre eine zweite.
   Bewusst OHNE Breakpoint-Schranke, anders als .is-suppressed oben: das
   Eröffnungsbild endet bei 16% Scrub-Fortschritt, mobil rund 180px Scrollweg
   — die Pill ist nach einem Daumenwisch zurück, das Burger-Menü also nicht
   für eine ganze Sektion unerreichbar, sondern nur im ersten Bild. */
.site-header.is-hero-hidden {
  transform: translateY(-130%);
  opacity:   0;
}
.site-header.is-hero-hidden .header-pill { pointer-events: none; }

/* Die Pill startet versteckt — dann darf sie auch nicht erst einfliegen:
   fx-drop-in setzt transform und schlüge die Klasse sonst 700ms lang. */
html.js.is-loaded .site-header.is-hero-hidden { animation: none; }

.header-pill {
  display:        flex;
  align-items:    center;
  gap:            var(--s-4);
  max-width:      960px;
  width:          100%;
  background:     rgba(252, 252, 253, 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-radius:  9999px;
  padding:        var(--s-3) var(--s-3) var(--s-3) var(--s-5);
  box-shadow:
    0 2px 8px  rgba(20, 33, 61, .10),
    0 8px 32px rgba(20, 33, 61, .12);
  border:         1px solid rgba(243, 240, 234, .55);
  pointer-events: auto;
  transition:
    background-color var(--tr-base),
    box-shadow       var(--tr-base);
}

.site-header.is-scrolled .header-pill {
  background: rgba(20, 33, 61, 0.96);
  box-shadow:
    0 2px 8px  rgba(0, 0, 0, .18),
    0 8px 32px rgba(0, 0, 0, .22);
}

/* Logo-Crossfade auf dem Pill-Hintergrund: navy Bildmarke default (cremer
   Pill), weiße Bildmarke blendet beim Scroll-Zustand (navy Pill) ein. */
.site-header.is-scrolled .header-pill .logo-img--navy { opacity: 0; }
.site-header.is-scrolled .header-pill .logo-img--white { opacity: 1; }

/* Nav-Links */
.header-nav {
  display:         flex;
  align-items:     center;
  gap:             var(--s-6);
  flex:            1;
  justify-content: center;
}

.nav-link {
  position:       relative;
  font-family:    var(--f-body);
  font-size:      var(--t-sm);
  font-weight:    500;
  color:          var(--c-navy);
  letter-spacing: 0.01em;
  white-space:    nowrap;
  transition:     color var(--tr-fast);
}
.nav-link:hover         { color: var(--c-accent); }
.nav-link:active        { color: var(--c-accent); }
.nav-link:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 3px; border-radius: 2px; }

/* Scroll-Spy: Akzent-Unterstrich slidet unter dem aktiven Abschnitt ein */
.nav-link::after {
  content:          '';
  position:         absolute;
  left:             0;
  right:            0;
  bottom:           -6px;
  height:           2px;
  border-radius:    1px;
  background:       var(--c-accent);
  transform:        scaleX(0);
  transform-origin: left center;
  transition:       transform 250ms cubic-bezier(0.16, 1, 0.3, 1);
}
.nav-link:hover::after,
.nav-link.is-active::after { transform: scaleX(1); }

.site-header.is-scrolled .nav-link       { color: rgba(243, 240, 234, .82); }
.site-header.is-scrolled .nav-link:hover { color: var(--c-accent); }

@media (max-width: 767px) { .header-nav { display: none; } }

/* ─── BURGER + MOBILE NAV (Pill-Stil) ─────────────────────── */
.nav-burger {
  display:        none;
  flex-direction: column;
  justify-content: center;
  gap:            6px;
  width:          44px;
  height:         44px;
  padding:        0 10px;
  background:     none;
  border:         none;
  cursor:         pointer;
  border-radius:  9999px;
  -webkit-tap-highlight-color: transparent;
  transition:     transform var(--tr-fast), background-color var(--tr-fast);
}
@media (hover: hover) and (pointer: fine) {
  .nav-burger:hover { background: rgba(20, 33, 61, 0.06); }
  .site-header.is-scrolled .nav-burger:hover { background: rgba(255, 255, 255, 0.08); }
}
.nav-burger:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 2px;
}
.nav-burger:active { transform: scale(0.92); }

.nav-burger-line {
  display:       block;
  width:         22px;
  height:        2px;
  border-radius: 2px;
  background:    var(--c-navy);
  transition:    transform 300ms cubic-bezier(0.16, 1, 0.3, 1);
}
.site-header.is-scrolled .nav-burger-line { background: var(--c-light); }

.nav-burger.is-open .nav-burger-line:first-child { transform: translateY(4px) rotate(45deg); }
.nav-burger.is-open .nav-burger-line:last-child  { transform: translateY(-4px) rotate(-45deg); }

.mobile-nav {
  position:       fixed;
  z-index:        calc(var(--z-header) - 1);
  left:           var(--gutter);
  right:          var(--gutter);
  /* Aus der Pill-Höhe hergeleitet statt hart codiert: .site-header
     padding-top (--s-4) + Burger (44px) + Pill-Padding (2×--s-2, mobile)
     + Pill-Border (2×1px). */
  top:            calc(var(--s-4) + 44px + 2 * var(--s-2) + 2px);
  display:        none;
  flex-direction: column;
  gap:            var(--s-1);
  padding:        var(--s-4);
  background:     var(--c-navy);
  border-radius:  24px;
  box-shadow:
    0 4px 12px  rgba(20, 33, 61, .18),
    0 16px 48px rgba(20, 33, 61, .28);
  opacity:        0;
  visibility:     hidden;
  transform:      translateY(-8px) scale(0.98);
  transform-origin: top center;
  pointer-events: none;
  transition:
    opacity    250ms cubic-bezier(0.16, 1, 0.3, 1),
    transform  250ms cubic-bezier(0.16, 1, 0.3, 1),
    visibility 250ms;
}

.mobile-nav.is-open {
  opacity:        1;
  visibility:     visible;
  transform:      none;
  pointer-events: auto;
}

.mobile-nav-link {
  padding:         var(--s-3) var(--s-4);
  font-family:     var(--f-body);
  font-size:       var(--t-base);
  font-weight:     600;
  color:           rgba(243, 240, 234, .88);
  text-decoration: none;
  border-radius:   12px;
  transition:      background-color var(--tr-fast), color var(--tr-fast);
  touch-action:    manipulation;
}
.mobile-nav-link:hover  { background: rgba(255, 255, 255, .06); color: var(--c-light); }
.mobile-nav-link:active { background: rgba(255, 255, 255, .10); }
.mobile-nav-link:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: -2px;
}

.mobile-nav-cta {
  margin-top:    var(--s-2);
  background:    var(--c-accent);
  color:         var(--c-navy);
  text-align:    center;
  border-radius: 9999px;
}
.mobile-nav-cta:hover  { background: var(--c-accent-hover); color: var(--c-navy); }
.mobile-nav-cta:active { background: var(--c-accent-hover); }

@media (max-width: 767px) {
  .nav-burger { display: inline-flex; }
  .mobile-nav { display: flex; }
  /* CTA wandert ins Menü → Pill bleibt schlank (Logo + Burger) */
  .header-pill .btn-header { display: none; }
  /* Pill kompakter: weniger Padding, dezenterer Schatten (Plan 5.3) */
  .header-pill {
    padding: var(--s-2) var(--s-2) var(--s-2) var(--s-4);
    box-shadow:
      0 1px 4px  rgba(20, 33, 61, .08),
      0 6px 20px rgba(20, 33, 61, .12);
  }
}

/* Logo: zwei deckungsgleiche Bildmarken (navy + weiß) übereinander, siehe
   Crossfade-Regel weiter oben. */
.logo {
  position:        relative;
  display:         inline-flex;
  align-items:     center;
  text-decoration: none;
  transition:      opacity var(--tr-fast);
}
.logo:hover         { opacity: .85; }
.logo:active         { opacity: .7; }
.logo:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 4px; border-radius: 2px; }

.logo-img {
  height:     1.8rem;
  width:      auto;
  display:    block;
  transition: opacity var(--tr-fast);
}
.logo-img--white {
  position: absolute;
  inset:    0;
  opacity:  0;
}


/* =============================================================
   HERO – Buchstaben-Portal (Glyph Portal)
   Der Schriftzug "VOELKEL" ist eine clipPath-Maske auf navy Bühne:
   sichtbar ist die cremefarbene Fläche dahinter NUR innerhalb der
   Buchstaben. Beim Scrollen zoomt die Maske in das dickste Tintenfeld
   eines Buchstabens ("Loch") hinein, bis das Creme den Schirm füllt —
   dann fällt die Maske, und der Abschnitt darunter (#problem,
   .section-light) trägt exakt dasselbe Creme weiter: keine Naht.
   ============================================================= */

.glyph-portal {
  --hp-paper:        var(--c-navy);   /* Bühne = Eröffnungsbild */
  --hp-height:       100svh;          /* JS überschreibt mit dem px-Messwert der Sonde */
  --hp-length:       2.0;             /* Pin-Höhen gesamt = Länge des Scrubs */
  --hp-caption:      1;               /* Deckkraft Eröffnungsbild */
  --hp-field-scale:  1;
  --hp-word-top:     30%;             /* von JS präzisiert, sobald das Wort vermessen ist */
  --hp-word-bottom:  46%;
  /* Höhe der gemessenen Wortmarke, die Maßeinheit des vertikalen Rhythmus: alle
     Abstände im Eröffnungsbild wachsen mit ihr, statt fest in px zu stehen. Das Wort
     ist breitenbegrenzt und damit je nach Viewport 50px (Handy) bis 193px (Desktop)
     hoch — feste Abstände können dabei nicht auf beiden Enden stimmen.
     Form ist bewusst affin (Sockel + Anteil), nicht max(Sockel, Anteil): ein Boden
     hätte im mittleren Bereich (Tablet, ~103px) einen Knick, an dem die Abstände
     eine Zeitlang gar nicht mitwachsen. */
  --hp-word-h:       calc(var(--hp-word-bottom) - var(--hp-word-top));
  position:   relative;
  /* Nicht --hp-paper: sichtbar ist die Sektionsfläche nur an der Unterkante,
     und dort steht das Creme des Folgeabschnitts — navy wäre ein Strich. */
  background: var(--c-bg);
  height:     calc(var(--hp-height) * var(--hp-length));
}

@media (max-width: 767px) {
  /* Kürzerer Weg fürs Daumen-Scrolling. */
  .glyph-portal { --hp-length: 1.8; }
}

/* Reduced Motion: kein Pinning, ein Standbild. Das Wort bleibt ein
   Fenster auf das Feld, statt einer leeren Fläche zu weichen. */
.glyph-portal.is-static { --hp-length: 1; }

/* 100svh-Sonde: misst den kleinen Viewport einmal als px, damit die
   ein-/ausklappende mobile Adressleiste die Scrollstrecke nicht laufend
   ändert. visibility:hidden statt display:none, sonst bliebe offsetHeight 0. */
.hp-viewport {
  position:   absolute;
  inset:      0 auto auto 0;
  width:      0;
  height:     100vh;
  height:     100svh;
  visibility: hidden;
  pointer-events: none;
}

.hp-pin {
  position: sticky;
  top:      0;
  height:   var(--hp-height);
  overflow: hidden;
}

.hp-stage {
  position:         relative;
  height:           100%;
  overflow:         hidden;
  /* Navy Bühne als beleuchteter Raum statt gleichmäßig ausgemalter Fläche:
     Licht knapp über dem Wort, zu den Ecken hin --c-navy-deep. Beide Farben
     stehen schon in den Tokens, das Muster kopiert den Footer (radial-
     gradient über --c-navy-deep, weiter unten bei .site-footer). Bewusst
     knapp gehalten (Plateau bis 48%, Endfarbe erst bei 130% erreicht) —
     in der Bildmitte über dem Wort ändert sich nichts, nur die vier Ecken
     dunkeln sichtbar ab. */
  background-color: transparent;
  background-image: radial-gradient(circle at 50% 36%,
    var(--c-navy) 0%, var(--c-navy) 48%, var(--c-navy-deep) 130%);
  /* Ersetzt den Stapelkontext, den vorher das transform der Schluss-Geste
     aufgespannt hat — die z-index-Kinder (Feld, Front, Wahl) brauchen ihn. */
  isolation:        isolate;
}

/* Trägt den drop-shadow-Schein unten: .hp-field selbst kann ihn wegen
   seines eigenen clip-path nicht tragen (filter greift VOR clip-path, ein
   drop-shadow direkt am geclippten Element würde mit weggeschnitten). */
.hp-field-wrap {
  position: absolute;
  inset:    0;
  /* Licht tritt durch die Buchstaben nach außen aus — aus cremefarbenen
     Buchstaben werden Löcher mit einem weichen Schein dahinter, statt
     einer Fläche mit harter Kante. Trennt die Ebenen optisch voneinander,
     ohne dass irgendwo eine neue Farbe hinzukommt. */
  filter:   drop-shadow(0 0 16px rgba(243, 240, 234, 0.16));
}

/* Fläche, die nur innerhalb der Buchstaben sichtbar ist — also der Verlauf,
   den man IM Wort sieht: oben fast reines Creme, zur Wortunterkante hin ein
   warmer Hauch Akzent. Bewusst waagerecht gleichmäßig und KEIN Radial: ein
   zweites Radial neben dem von .section-light hat eine andere Geometrie
   (anderer Kasten, dazu --hp-field-scale) — an den unteren Ecken entstand
   damit ein deutlich sichtbarer Sprung.
   Der Endwert ist nicht frei gewählt: er ist die Farbe, mit der #problem
   oben ansetzt (--c-bg + 6,2% Akzent, gemessen: rgb(239,241,246) bei
   --c-bg #FCFCFD). Ab 72% deshalb konstant —
   --hp-field-scale (bis 1.16) verschiebt den sichtbaren Ausschnitt, die
   Naht trifft so in jedem Zoomzustand dieselbe Farbe. */
.hp-field {
  position: absolute;
  inset:    0;
  transform: scale(var(--hp-field-scale));
  background:
    /* Oben ein Hauch Navy: kühl nach warm liest sich als Verlauf deutlicher
       als derselbe Helligkeitsunterschied in einem Ton. Vor 46% restlos
       transparent, rührt die Endfarbe unten also nicht an. */
    linear-gradient(to bottom,
      rgba(20, 33, 61, 0.035) 0%,
      rgba(20, 33, 61, 0)     46%),
    linear-gradient(to bottom,
      rgba(46, 74, 133, 0)     0%,
      rgba(46, 74, 133, 0.014) 30%,
      rgba(46, 74, 133, 0.055) 56%,
      rgba(46, 74, 133, 0.062) 72%,
      rgba(46, 74, 133, 0.062) 100%),
    var(--c-bg);
}

/* Wird von JS gesetzt: solange t < 1 clippt die Maske, danach füllt die
   Fläche den ganzen Schirm (das Loch ist dann größer als der Bildschirm). */
.hp-stage.is-clipped .hp-field {
  clip-path: url(#hp-clip);
}

/* Unsichtbare Clip-Definition. width/height 0 statt display:none — eine
   display:none-Teilbaum-Referenz ist als Clip-Quelle nicht überall
   verlässlich. */
.hp-defs {
  position: absolute;
  width:    0;
  height:   0;
  overflow: hidden;
}

/* Muss mit CFG.fontSpec in initGlyphPortal() übereinstimmen — sonst misst
   JS eine andere Form, als hier gerendert wird. Kein letter-spacing, keine
   Variationsachse (ctx.font kann font-variation-settings nicht ausdrücken). */
.hp-defs text {
  font-family:            var(--f-portal);
  font-kerning:           none;
  font-variant-ligatures: none;
  letter-spacing:         0;
}

/* Buchstabenwahl: transparente Radiogroup-Buttons, von JS über die
   gemessenen Buchstaben-Trefferflächen positioniert. Nur aktiv, solange
   der Fortschritt < 4% ist (JS toggelt .is-choosing). */
.hp-choices {
  position:       absolute;
  inset:          0;
  z-index:        3;
  visibility:     hidden;
  pointer-events: none;
}
.glyph-portal.is-choosing .hp-choices {
  visibility: visible;
}
.hp-letter {
  box-sizing:     border-box;
  position:       absolute;
  border:         0;
  padding:        0;
  margin:         0;
  background:     transparent;
  cursor:         pointer;
  pointer-events: auto;
  touch-action:   pan-y;
}
.hp-letter:disabled { pointer-events: none; }
.hp-letter:hover {
  outline:        2px solid rgba(46, 74, 133, 0.5);
  outline-offset: 3px;
}
.hp-letter:focus-visible {
  outline:        2px solid var(--c-accent-bright);
  outline-offset: 3px;
}
.hp-letter:active {
  outline:        2px solid var(--c-accent-bright);
  outline-offset: 2px;
}

/* Touch-Pendant zur Buchstabenwahl, nur bei grobem Zeigegerät sichtbar
   (Maus/Trackpad wählen per Hover). Sitzt über dem Scroll-Hinweis am
   Fuß der Bühne statt direkt unter dem Wort: dort stünde es im zentrierten
   Stapel aus SYSTEMS, Subline und CTAs. */
.hp-picker {
  display:    none;
  position:   absolute;
  z-index:    3;
  bottom:     9%;
  left:       50%;
  transform:  translateX(-50%);
  visibility: hidden;
}
.glyph-portal.is-choosing .hp-picker { visibility: visible; }

.hp-select {
  min-height:    44px;
  min-width:     120px;
  border:        1px solid rgba(243, 240, 234, .4);
  border-radius: var(--r-sm);
  background:    rgba(20, 33, 61, .9);
  color:         var(--c-light);
  padding:       0 var(--s-3);
  font:          inherit;
  font-size:     var(--t-sm);
}
.hp-select:focus-visible {
  outline:        2px solid var(--c-accent-bright);
  outline-offset: 3px;
}

/* Vordergrund = Eröffnungsbild. Eigener Stacking-Context je Textelement
   (statt einem gemeinsamen z-index auf .hp-front) — dieselbe Aufteilung
   wie beim alten Hero, nur dass hier keine verschachtelte Ebene mehr
   mitgezogen werden könnte: Feld → Scrim → Front stehen als eigene
   Geschwister in .hp-stage, in genau dieser Reihenfolge im DOM. */
.hp-front {
  position:       absolute;
  inset:          0;
  z-index:        2;
  opacity:        var(--hp-caption);
  pointer-events: none;
}
/* --hp-caption-hit: von JS gesetzt (p < 8% → "auto", sonst "none") — die
   Copy ist längst unsichtbar, bevor die CTAs unerreichbar werden sollen;
   kein Klick geht ins Leere, sobald die Kamera zu zoomen beginnt. */
.hp-front a,
.hp-front button { pointer-events: var(--hp-caption-hit, auto); }

.hp-front .container {
  position: relative;
  height:   100%;
}

/* Kopfzeile der Bühne: Bildmarke links, Kategorie rechts. Sitzt dort, wo
   sonst die Header-Pill steht — die ist im Eröffnungsbild ausgeblendet
   (.is-hero-hidden) und kommt bei 18% Fortschritt zurück.
   Der Gutter steht hier als eigenes padding-inline: das Containing Block
   einer absolut positionierten Box ist die PADDING-Box des .container,
   dessen padding-inline liegt also innerhalb von left/right:0. */
.hp-toprow {
  position:        absolute;
  left:            0;
  right:           0;
  top:             var(--s-6);
  padding-inline:  var(--gutter);
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             var(--s-4);
}

/* Mobil untereinander statt nebeneinander: die Kategoriezeile bräuchte
   neben der Bildmarke drei Zeilen und liefe aus dem Bild. Der Platz
   darunter ist im Eröffnungsbild ohnehin leer. */
@media (max-width: 767px) {
  .hp-toprow {
    flex-direction: column;
    align-items:    flex-start;
    gap:            var(--s-2);
  }
}

/* Eigene Klasse statt .logo-img--white: die ist global position:absolute
   und opacity:0 (Crossfade-Partner in der Pill) — hier unsichtbar. */
.hp-logo {
  height:      1.8rem;
  width:       auto;
  display:     block;
  flex-shrink: 0;
}

/* Beschriftung, kein Akzent: gedämpftes Creme statt Akzent. */
.hero-eyebrow {
  margin:     0;
  text-align: right;
  color:      rgba(243, 240, 234, .6);
}

@media (max-width: 767px) {
  .hero-eyebrow {
    text-align: left;
    max-width:  26ch;
  }
}

/* H1 und SYSTEMS hängen an der von JS gemessenen Wortbox, statt im
   Textfluss zu stehen — das Riesenwort selbst ist eine Hintergrundebene
   ohne eigene Flusshöhe. */
.hp-wordmark {
  position:       absolute;
  left:           0;
  right:          0;
  /* Eng an der Wortunterkante: SYSTEMS gehört zur Wortmarke, nicht zur Copy. Der
     kleinste der drei Abstände im Bild — daran liest das Auge die Gruppierung. */
  top:            calc(var(--hp-word-bottom) + 11px + var(--hp-word-h) * 0.045);
  margin:         0;
  padding-inline: var(--gutter);
  text-align:     center;
  font-family:    var(--f-body);
  /* Deutlich größer als alle übrigen Textelemente im Bild (H1 max. 17px,
     Buttons 16px): SYSTEMS soll auf den ersten Blick als zweites Markenwort
     erkennbar sein, nicht als Fußnote unter dem großen VOELKEL untergehen. */
  font-size:      var(--t-2xl);
  font-weight:    600;
  line-height:    1.15;
  /* Deutlich breiter gesperrt (0.55× der Schriftgröße statt einer festen,
     kleinen Sperrung) — macht aus SYSTEMS ein bewusst gebautes Wortmarken-
     Lockup statt einer kleinen Bildunterschrift. Kein Versuch, exakt die
     Breite von VOELKEL zu treffen: siehe Kommentar bei syncWordmarkLockup()
     in script.js — bei diesem Größenunterschied nicht erreichbar, ohne
     dass die Buchstaben auseinanderfallen.
     --hp-sys-tracking kommt aus syncWordmarkLockup() (px, pro Schriftgröße
     neu berechnet); der em-Wert dahinter ist nur der Rückfall ohne JS.
     text-indent gleicht die Lücke hinter dem letzten Buchstaben aus, exakt
     dieselbe Technik wie bei .hp-static weiter unten. */
  letter-spacing: var(--hp-sys-tracking, 0.2em);
  text-indent:    var(--hp-sys-tracking, 0);
  color:          rgba(243, 240, 234, .58);
}

/* Unten verankerter Block: unabhängig von der Wortgröße, blendet
   zusammen mit dem Eröffnungsbild aus. */
/* An die gemessene Wortbox gehängt statt bodenverankert: bei einem
   breiten Wort wie VOELKEL ist die Bühne meist breiten- statt
   höhenbegrenzt (siehe wordAnchorY-Kommentar in initGlyphPortal) — ein
   fester Bodenabstand würde dann mit dem Wort überlappen, je nach
   Seitenverhältnis des Viewports. */
.hp-caption {
  position:       absolute;
  left:           0;
  right:          0;
  /* Größter Abstand im Bild: die Handlungsebene steht für sich, nicht am Wort.
     Die frühere Mobil-Ausnahme (+56px) ist entfallen — der Sockel von 49px leistet
     dasselbe und läuft ohne Sprung in den Desktop-Wert weiter. */
  top:            calc(var(--hp-word-bottom) + 49px + var(--hp-word-h) * 0.325);
  padding-inline: var(--gutter);
}

/* Textblock unter dem Wort — zentriert wie die ganze Komposition. */
.hero-text {
  max-width:     56ch;
  margin-inline: auto;
  text-align:    center;
}

/* Sicherheitsnetz für flache Fenster (Laptop-Vollbild, kein Ultrawide) */
@media (max-height: 720px) {
  .hero-actions { margin-bottom: var(--s-4); }
}

@media (max-width: 767px) {
  .hero-text { max-width: 100%; }
}

/* Die leise Zeile ÜBER dem Wort, wie im Referenzbild: kein Display-Grad,
   sondern Fließtextschrift in Beschriftungsgröße. Hängt an der Oberkante
   der gemessenen Wortbox, damit der Abstand bei jeder Wortgröße stimmt. */
.hero-headline {
  position:       absolute;
  left:           0;
  right:          0;
  bottom:         calc(var(--hp-height) - var(--hp-word-top)
                       + 18px + var(--hp-word-h) * 0.145);
  margin:         0;
  padding-inline: var(--gutter);
  font-family: var(--f-body);
  /* Über Buttongröße (16px), unter keiner Bedingung darunter: das ist der einzige
     Satz im Eröffnungsbild und trägt Botschaft wie Suchbegriff. Auf --t-sm (14px)
     stand er kleiner als die Buttonbeschriftung. */
  font-size:   clamp(0.9375rem, 0.75rem + 0.5vw, 1.0625rem);   /* 15 → 17 */
  font-weight: 500;
  line-height: 1.5;
  text-align:  center;
  /* Eine Strichstärke, eine Deckkraft über die ganze Zeile — keine hervorgehobene
     Stelle mehr. Etwas heller als zuvor (.72), weil die Zeile jetzt allein trägt. */
  color:       rgba(243, 240, 234, .78);
}

.hp-front .btn-light {
  border-radius:  9999px;
  padding-inline: var(--s-10);
}

.hero-actions {
  display:         flex;
  align-items:     center;
  justify-content: center;
  gap:             var(--s-4);
  flex-wrap:       wrap;
  margin-bottom:   var(--s-5);
}

@media (max-width: 480px) {
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { width: 100%; }
}

/* Scroll-Hinweis, verschwindet mit der übrigen Vorderebene */
.hp-scroll {
  position:       absolute;
  z-index:        2;
  inset:          auto 0 4%;
  text-align:     center;
  opacity:        calc(var(--hp-caption) * 0.6);
  color:          var(--c-light);
  font-size:      var(--t-xs);
  letter-spacing: 0.08em;
}

/* Kein-JS- und Stall-Rückfall: das Wort steht als normaler, unvermessener
   Text still im Bild, statt dass die Fläche eine leere Navy-Fläche bliebe.
   .hp-front (H1, Actions) bleibt in jedem Fall sichtbar — nur die
   Zoom-Mechanik fehlt dann, nicht der Inhalt.
   Sitzt bewusst im selben Wortband (--hp-word-top/-bottom, hier noch die
   CSS-Vorgabewerte), an dem auch H1, SYSTEMS und die Copy hängen: mittig
   über die ganze Bühne gelegt würde es genau in diesen Stapel laufen.
   letter-spacing spiegelt CFG.tracking (6 von 100px = 0.06em); das
   text-indent gleicht die Lücke hinter dem letzten Buchstaben wieder aus,
   sonst säße das Wort um ein halbes Sperrmaß links. */
.hp-static {
  display:        none;
  position:       absolute;
  inset:          var(--hp-word-top) 0 auto;
  height:         calc(var(--hp-word-bottom) - var(--hp-word-top));
  z-index:        1;
  margin:         0;
  place-items:    center;
  font-family:    var(--f-portal); /* muss mit .hp-defs text uebereinstimmen */
  font-weight:    700;
  font-size:      min(13vw, 12vh);
  letter-spacing: 0.06em;
  text-indent:    0.06em;
  color:          var(--c-light);
}
.glyph-portal.is-stalled .hp-static,
html:not(.js) .hp-static {
  display: grid;
}

/* Immer dann, wenn die Pill NICHT ausgeblendet wird (kein JS, Stall,
   Reduced Motion), trägt sie die Bildmarke — die eigene Kopfzeile der
   Bühne wäre eine zweite, direkt dahinterliegende. */
.glyph-portal.is-stalled .hp-toprow,
.glyph-portal.is-static  .hp-toprow,
html:not(.js) .hp-toprow {
  display: none;
}

/* Nur visuell versteckt, für Screenreader erreichbar (Eintritts-Buchstabe-
   Label des Touch-Pickers). */
.sr-only {
  position: absolute;
  width:    1px;
  height:   1px;
  padding:  0;
  margin:   -1px;
  overflow: hidden;
  clip:     rect(0, 0, 0, 0);
  white-space: nowrap;
  border:   0;
}

/* =============================================================
   SHARED SECTION BASE
   Radial-gradient glows adapted from background-components pattern.
   Light sections: soft Akzent glow (opacity .07, multiply blend).
   Navy sections: warm center glow for perceived depth.
   ============================================================= */
.section-light {
  position:   relative;
  padding-block: var(--sec-pad);
  background:
    radial-gradient(circle at 50% 40%, rgba(46, 74, 133, 0.07) 0%, transparent 68%),
    var(--c-bg);
}


.section-navy {
  position:      relative;
  isolation:     isolate;
  padding-block: var(--sec-pad);
  background:
    radial-gradient(circle at 50% 38%, rgba(46, 74, 133, 0.09) 0%, transparent 60%),
    var(--c-navy);
}

/* Floating navy tile — dark card that hovers on the cream page */
.navy-tile {
  position:      relative;
  isolation:     isolate;
  border-radius: 28px;
  padding:       var(--sec-pad) var(--s-12);
  overflow:      hidden;
  background:
    radial-gradient(circle at 50% 38%, rgba(46, 74, 133, 0.09) 0%, transparent 60%),
    var(--c-navy);
  box-shadow:
    0 2px 4px   rgba(20,33,61,.06),
    0 8px 24px  rgba(20,33,61,.14),
    0 28px 64px rgba(20,33,61,.18),
    0 56px 96px rgba(20,33,61,.10);
}

@media (max-width: 767px) {
  .navy-tile {
    border-radius: 18px;
    /* Block-Achse bewusst NICHT --sec-pad: die Kachel steckt in einer
       .section-light, die selbst schon padding-block:var(--sec-pad) trägt
       — sonst öffnet sich der Abstand doppelt. */
    padding: var(--s-12) var(--s-6);
  }
}



/* =============================================================
   VERSPRECHEN – leise Aussage zwischen Portal und Problem-Spiegel
   ============================================================= */
/* Bewusst kleiner als --sec-pad: eine Mini-Sektion, keine volle.
   Bewusst OHNE eigenes Radial und in einer festen Farbe statt --c-bg:
   .section-light zentriert sein Akzent-Radial auf die eigene, hohe Box
   (circle at 50% 40%) — in einer so kurzen Box wie dieser läuft dieselbe
   Formel geometrisch anders aus und erzeugt an der Grenze zu #problem einen
   messbaren Sprung (bis zu 10 RGB-Stufen).
   rgb(239,241,246) ist keine neue Farbe, sondern exakt die Farbe, mit der
   sowohl das Hero-Portal endet als auch die Deckschicht von #problem
   ansetzt (siehe dortiger Kommentar zur Kante) — eine flache Fläche in
   genau diesem Ton schließt oben nahtlos ans Portal UND unten nahtlos an
   #problems eigene Deckschicht an, ohne dass #problem selbst etwas von
   dieser neuen Sektion wissen muss. */
.section-statement {
  padding-block: var(--s-16);
  background:    rgb(239, 241, 246);
}

.statement-text {
  max-width:     46ch;
  margin-inline: auto;
  text-align:    center;
  font-size:     var(--t-xl);
  line-height:   1.6;
  color:         var(--c-muted);
}
.statement-text strong {
  color:       var(--c-text);
  font-weight: 700;
}

/* =============================================================
   PROBLEM-SPIEGEL – Leitkachel + Suchergebnis-Mockup
   ============================================================= */
.section-problem .headline-display { margin-bottom: var(--s-12); }

/* Einleitungstext direkt unter der Headline, ohne Kachel-Hülle: wie beim
   Umdeutung-Textblock (.umdeutung-text) links ausgerichtet und auf
   Lesebreite begrenzt. */
.problem-intro {
  max-width:     64ch;
  margin-bottom: var(--s-10);
}

/* Story-Wrapper: Grafik + Punkte-Band. Gestapelt (Grafik oben, Punkte
   darunter) bis 1024px, darüber Split-Screen — siehe Media Query unten. */
.problem-story {
  display: grid;
  gap:     var(--s-10);
  margin-top: var(--s-12);
}

/* Illustration der Suchergebnisseite (KI-generiert, gekennzeichnet).
   Zentriert, solange gestapelt. */
.problem-serp {
  max-width:     440px;
  margin-inline: auto;
}
.problem-serp .si-media {
  box-shadow:
    0 0 0 1px   rgba(20, 33, 61, .08),
    0 10px 30px rgba(20, 33, 61, .10),
    0 2px 6px   rgba(20, 33, 61, .06);
}
.problem-serp .si-media img { aspect-ratio: 960 / 717; }
.problem-shot-caption {
  margin-top: var(--s-3);
  text-align: center;
  font-size:  var(--t-xs);
  color:      var(--c-muted);
}


/* ─── PROBLEM-PUNKTE ─────────────────────────────────────────
   Textband unter Grafik + Leitkachel: drei gleichrangige Punkte,
   durch Haarlinien statt Kacheln getrennt. Mobil gestapelt mit
   Linie oben, ab 768px als Reihe mit senkrechten Trennern
   (border-left, beim ersten Punkt unterdrückt). */
.problem-points {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-6);
}

.problem-point {
  padding-top: var(--s-6);
  border-top:  1px solid rgba(20, 33, 61, 0.10);
}

/* Ab hier trägt die Grafik den Beweis links, die Punkte stehen als Folgen
   rechts daneben — Pfeil vor jedem Punkt zeigt gedanklich zurück zur
   Grafik. Darunter bleibt alles gestapelt (Grafik oben, Punkte darunter). */
@media (min-width: 1024px) {
  .problem-story {
    grid-template-columns: minmax(320px, 440px) 1fr;
    align-items:           center;
    gap:                   var(--s-14);
  }
  .problem-serp {
    margin-inline: 0;
    position:      sticky;
    top:           var(--s-10);
  }
  /* Lücke zwischen den Punkten wandert von gap (außerhalb der Box) zu
     padding-bottom (innerhalb) — dieselbe Gesamthöhe, aber jetzt reicht
     .problem-point exakt von dieser Trennlinie bis zur nächsten. Erst so
     zentriert top:50% den Pfeil wirklich zwischen den beiden Linien statt
     nur über dem Fließtext. */
  .problem-points {
    gap: 0;
  }
  .problem-point {
    position:       relative;
    padding-left:   var(--s-8);
    padding-bottom: var(--s-6);
  }
  .problem-point::before {
    content:     "→";
    position:    absolute;
    left:        0;
    top:         50%;
    transform:   translateY(-50%);
    color:       var(--c-accent);
    font-family: var(--f-display);
    font-size:   var(--t-lg);
  }
}

.problem-point-lead {
  display:        flex;
  align-items:    flex-start;
  gap:            var(--s-2);
  font-family:    var(--f-display);
  font-size:      var(--t-lg);
  font-weight:    600;
  letter-spacing: -0.015em;
  line-height:    1.3;
  color:          var(--c-text);
  margin-bottom:  var(--s-3);
}

/* Kreuz auf Versalhöhe der ersten Zeile ausrichten, unabhängig davon, ob die
   Überschrift ein- oder zweizeilig umbricht. */
.problem-point-icon {
  flex-shrink: 0;
  width:       1.125rem;
  height:      1.125rem;
  margin-top:  0.2em;
  color:       var(--c-negative);
}

.problem-point-text {
  font-size:   var(--t-base);
  line-height: 1.65;
  color:       var(--c-muted);
  /* Verhindert, dass ein neuer Satz nur mit ein, zwei Wörtern am
     Zeilenende beginnt und dann erst in der nächsten Zeile weitergeht —
     gleicht die Zeilenlängen aus, sodass der Satzanfang mit auf die
     zweite Zeile rutscht. Getestet: löst es bei allen drei Punkten. */
  text-wrap:   balance;
}


/* =============================================================
   SELBSTTEST – dunkle schwebende Karte (.navy-tile)
   ============================================================= */
.selbsttest-tile { max-width: var(--max-w); margin-inline: auto; }

.selbsttest-tile .eyebrow          { color: rgba(46, 74, 133, 0.85); }
.selbsttest-tile .headline-display { margin-bottom: var(--s-5); max-width: 30ch; }
.selbsttest-tile .body-text--light { max-width: 60ch; }
.selbsttest-tile .body-text--light + .body-text--light { margin-top: var(--s-5); }
.selbsttest-transition             { font-weight: 500; }

/* Zwei Zonen statt einer Rand-Karte: oben Kontext über volle Breite, unten
   durch eine Haarlinie abgesetzt das Angebot in zwei gleichgewichtigen
   Spalten — links was man bekommt, rechts wie man es bekommt. Gestapelt
   (< 1024px) liest sich die DOM-Reihenfolge von allein richtig. */
.selbsttest-offer {
  margin-top:  var(--s-12);
  padding-top: var(--s-12);
  border-top:  1px solid rgba(255, 255, 255, 0.12);
  display:     grid;
  gap:         var(--s-10);
}

@media (min-width: 1024px) {
  .selbsttest-offer {
    grid-template-columns: 1fr 1fr;
    align-items:           start;
    column-gap:            var(--s-14);
  }
}

.selbsttest-offer-title {
  font-family:    var(--f-display);
  font-size:      var(--t-lg);
  font-weight:    600;
  letter-spacing: -0.015em;
  line-height:    1.3;
  color:          var(--c-light);
  margin-bottom:  var(--s-5);
}

.selbsttest-list {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-4);
}

.selbsttest-list li {
  display:     flex;
  align-items: flex-start;
  gap:         var(--s-3);
  font-size:   var(--t-base);
  line-height: 1.6;
  color:       rgba(243, 240, 234, 0.82);
}

/* Häkchen im selben Stil wie das Kreuz in der Problem-Sektion
   (.problem-point-icon) — dort ✕, hier ✓: gleiches Icon-System, Kehrseite. */
.selbsttest-list-icon {
  flex-shrink: 0;
  width:       1.125rem;
  height:      1.125rem;
  margin-top:  0.2em;
  color:       var(--c-accent);
}

.selbsttest-actions {
  display:   flex;
  flex-wrap: wrap;
  gap:       var(--s-4);
  margin-bottom: var(--s-6);
}

@media (max-width: 480px) {
  .selbsttest-actions { flex-direction: column; align-items: stretch; }
  .selbsttest-actions .btn { width: 100%; }
}

.selbsttest-note {
  font-size: var(--t-sm);
  color:     rgba(243, 240, 234, 0.55);
  margin-top: var(--s-2);
}

.selbsttest-note-link {
  color:           rgba(243, 240, 234, 0.75);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition:      color var(--tr-fast);
}
.selbsttest-note-link:hover  { color: var(--c-accent); }
.selbsttest-note-link:active { color: var(--c-accent-hover); }
.selbsttest-note-link:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius:  2px;
}


/* =============================================================
   LÖSUNG – Service Grid
   ============================================================= */
.section-loesung {
  padding-block: var(--sec-pad);
}

.section-loesung .headline-display { margin-bottom: var(--s-4); }
.section-loesung .eyebrow          { margin-bottom: var(--s-3); }
.section-loesung > .container > .body-text { margin-bottom: var(--s-4); }

/* ── SERVICE LIST: card grid ───────────────────────────────── */
.service-list {
  margin-top:     var(--s-12);
  display:        flex;
  flex-direction: column;
  gap:            var(--s-3);
}

/* Drei-Karten-Variante (Mechanismus): Icon oben, Titel, Text */
.service-list--cols {
  display:               grid;
  grid-template-columns: repeat(3, 1fr);
  gap:                    var(--s-5);
}

@media (max-width: 767px) {
  .service-list--cols { grid-template-columns: 1fr; }
}

.service-item {
  display:               grid;
  grid-template-columns: 3.5rem 1fr 52px;
  gap:                   var(--s-6);
  align-items:           center;
  padding:               var(--s-6) var(--s-8);
  background:            var(--c-card);
  border-radius:         var(--r-md);
  box-shadow:            var(--shadow-card);
  transition:
    background 300ms cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 300ms cubic-bezier(0.16, 1, 0.3, 1),
    transform  300ms cubic-bezier(0.16, 1, 0.3, 1);
  cursor: default;
}

.service-list--cols .service-item {
  grid-template-columns: 1fr;
  align-items:           start;
  gap:                   var(--s-4);
}

@media (hover: hover) and (pointer: fine) {
  .service-item:hover {
    background: rgba(255,255,255,0.95);
    box-shadow: var(--shadow-card-hover);
    transform:  translateY(-2px);
  }
}

.si-body {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-1);
}

.si-title {
  font-family:    var(--f-display);
  font-size:      var(--t-xl);
  font-weight:    600;
  letter-spacing: -0.02em;
  color:          var(--c-text);
  line-height:    1.25;
  transition:     color 300ms cubic-bezier(0.16, 1, 0.3, 1);
}

@media (hover: hover) and (pointer: fine) {
  .service-item:hover .si-title { color: var(--c-navy); }
}

.si-text {
  font-size:   var(--t-base);
  line-height: 1.65;
  color:       var(--c-muted);
  margin-top:  var(--s-1);
}

@media (max-width: 639px) {
  .service-item {
    grid-template-columns: 2.5rem 1fr;
    padding: var(--s-5) var(--s-6);
  }
  .si-title { font-size: var(--t-lg); }
}

/* ── PAKET-KLAMMER ────────────────────────────────────────────
   Akzent-Linie über den drei Karten, unterbrochen vom Label. Zeigt
   sichtbar, was der Fließtext sagt: "Einzeln bringt Ihnen keiner
   davon viel. Zusammen…" — nur ab Tablet, im 1-Spalten-Stapel
   trägt sie nichts. */
.paket-bracket {
  display:       none;
  align-items:   center;
  gap:           var(--s-3);
  margin-top:    var(--s-8);
  margin-bottom: var(--s-5);
}

@media (min-width: 768px) {
  .paket-bracket { display: flex; }
}

.paket-bracket-line {
  position:   relative;
  flex:       1;
  height:     1px;
  background: rgba(46, 74, 133, 0.4);
}

.paket-bracket-line:first-child::before,
.paket-bracket-line:last-child::after {
  content:    '';
  position:   absolute;
  top:        0;
  width:      1px;
  height:     8px;
  background: rgba(46, 74, 133, 0.4);
}
.paket-bracket-line:first-child::before { left:  0; }
.paket-bracket-line:last-child::after   { right: 0; }

.paket-bracket-label {
  flex-shrink:    0;
  font-size:      var(--t-xs);
  font-weight:    700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color:          var(--c-accent);
}

/* ── ILLUSTRATIONEN je Karte (KI-generiert, gekennzeichnet) ──── */
.si-media {
  position:      relative;
  width:         100%;
  margin:        0 0 var(--s-2);
  border-radius: var(--r-sm);
  overflow:      hidden;
  background:    #F7F8F1;
  box-shadow:    0 0 0 1px rgba(20, 33, 61, .07);
}
.si-media img {
  display:      block;
  width:        100%;
  height:       auto;
  aspect-ratio: 8 / 5;
}
.si-media-tag {
  position:       absolute;
  left:           var(--s-2);
  bottom:         var(--s-2);
  padding:        3px 8px;
  border-radius:  999px;
  font-size:      .6875rem;
  font-weight:    600;
  letter-spacing: .02em;
  line-height:    1.4;
  color:          var(--c-muted);
  background:     rgba(255, 255, 255, .86);
  box-shadow:     0 1px 3px rgba(20, 33, 61, .12);
}

.mechanismus-note {
  margin-top:     var(--s-12);
  padding-top:    var(--s-8);
  border-top:     1px solid var(--c-border);
  font-size:      var(--t-lg);
  line-height:    1.78;
  color:          var(--c-muted);
  max-width:      70ch;
}


/* =============================================================
   ABLAUF – 3 Schritte
   ============================================================= */
.section-ablauf .headline-display { margin-bottom: var(--s-12); }
/* Akzent circle badge */
.step-badge {
  width:           40px;
  height:          40px;
  border-radius:   50%;
  border:          1.5px solid rgba(20, 33, 61, 0.35);
  background:      rgba(20, 33, 61, 0.05);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-family:     var(--f-display);
  font-size:       var(--t-base);
  font-weight:     600;
  color:           var(--c-navy);
  flex-shrink:     0;
  position:        relative;
  z-index:         1;
  user-select:     none;
}

.step-body { }

.step-title {
  font-family:    var(--f-display);
  font-size:      var(--t-2xl);
  font-weight:    600;
  letter-spacing: -0.025em;
  color:          var(--c-text);
  margin-bottom:  var(--s-2);
}

.step-text {
  font-size:   var(--t-lg);
  line-height: 1.72;
  color:       var(--c-muted);
  max-width:   46ch;
}


/* =============================================================
   REFERENZ – 3-tile portfolio grid
   ============================================================= */
.section-referenz {
  padding-block: var(--sec-pad);
}

.section-referenz .eyebrow         { margin-bottom: var(--s-3); }
.section-referenz .headline-display { margin-bottom: var(--s-12); }

/* 2 Spalten: Projekte nebeneinander, CTA als volle Bar darunter */
.referenz-grid {
  display:               grid;
  grid-template-columns: repeat(2, 1fr);
  gap:                   var(--s-5);
  align-items:           stretch;
}

.referenz-cta {
  grid-column:     1 / -1;
  display:         flex;
  justify-content: center;
  margin-top:      var(--s-4);
}
@media (max-width: 640px) { .referenz-cta .btn { width: 100%; } }

/* Kundenstimmen: je eine Spalte unter der passenden Projekt-Karte */
.referenz-testi {
  padding: var(--s-8) var(--s-10);
}
@media (max-width: 767px) {
  .referenz-testi { padding: var(--s-6); }
}

@media (max-width: 700px) {
  .referenz-grid {
    grid-template-columns: 1fr;
  }
}

.referenz-card {
  background:     var(--c-card);
  border-radius:  var(--r-lg);
  overflow:       hidden;
  box-shadow:     var(--shadow-card);
  display:        flex;
  flex-direction: column;
  transition:     box-shadow 300ms ease, transform 300ms ease;
}

.referenz-card:hover {
  box-shadow: var(--shadow-card-hover);
  transform:  translateY(-2px);
}
.referenz-card:active {
  box-shadow: var(--shadow-card);
  transform:  translateY(0) scale(0.99);
}

.referenz-card-mock {
  flex:        1;
  display:     flex;
  align-items: center;
  padding:     var(--s-4) var(--s-5);
}

.referenz-card-mock .browser-mock {
  width: 100%;
}

.referenz-card-info {
  padding: var(--s-5) var(--s-5) var(--s-6);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}

.referenz-card-name {
  font-family:    var(--f-display);
  font-size:      var(--t-base);
  font-weight:    600;
  color:          var(--c-text);
  letter-spacing: -0.01em;
  margin-top:     var(--s-2);
}

.referenz-card-desc {
  font-size: var(--t-sm);
  color:     var(--c-muted);
}

.referenz-card-note {
  font-size:   var(--t-sm);
  line-height: 1.6;
  color:       var(--c-muted);
  margin-top:  var(--s-2);
  padding-top: var(--s-2);
  border-top:  1px solid var(--c-border);
}

/* Deaktivierte Link-Zeile für Projekte, die noch nicht gehostet sind */
.referenz-link--soon {
  display:        inline-flex;
  align-items:    center;
  gap:            var(--s-2);
  margin-top:     var(--s-2);
  font-size:      var(--t-sm);
  color:          var(--c-muted);
  cursor:         default;
  pointer-events: none;
}

.referenz-link-tag {
  padding:       2px var(--s-3);
  border-radius: 999px;
  background:    rgba(46, 74, 133,0.14);
  color:         var(--c-accent);
  font-size:     var(--t-xs);
  font-weight:   500;
}

/* Badge (overrides old styles for grid context) */
.referenz-card .referenz-badge {
  display:     inline-flex;
  align-items: center;
  gap:         var(--s-2);
  color:       var(--c-navy);
}

/* Browser mockup */
.referenz-preview {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-4);
}

.browser-mock {
  border-radius: 8px;
  overflow:      hidden;
  box-shadow:
    0 0 0 1px rgba(255,255,255,.08),
    0 12px 40px rgba(0,0,0,.5),
    0 4px 12px rgba(0,0,0,.3);
}

/* Override shadow when mock sits on a light card */
.referenz-card-mock .browser-mock {
  box-shadow:
    0 0 0 1px rgba(20,33,61,.10),
    0 8px 24px rgba(20,33,61,.14),
    0 2px 6px rgba(20,33,61,.06);
}

.browser-bar {
  display:          flex;
  align-items:      center;
  gap:              var(--s-3);
  background:       rgba(255,255,255,.06);
  padding:          var(--s-3) var(--s-4);
  border-bottom:    1px solid rgba(255,255,255,.06);
}

.browser-dots {
  display: flex;
  gap:     5px;
  flex-shrink: 0;
}

.dot {
  width:         10px;
  height:        10px;
  border-radius: 50%;
}
.dot-red    { background: #FF5F57; }
.dot-yellow { background: #FFBD2E; }
.dot-green  { background: #28C840; }

.browser-url {
  flex:             1;
  font-family:      var(--f-body);
  font-size:        0.7rem;
  color:            rgba(255,255,255,.35);
  background:       rgba(255,255,255,.06);
  border-radius:    3px;
  padding:          3px var(--s-3);
  white-space:      nowrap;
  overflow:         hidden;
  text-overflow:    ellipsis;
}

/* Gemeinsames Grundformat für beide Referenz-Frames (UniProjekt-Wireframe
   und ScheibMedia-Screenshot) — exaktes Seitenverhältnis des Screenshots,
   damit beide Karten immer dieselbe Rahmengröße haben. Wireframe-Inhalt
   wird zentriert, falls er die Fläche nicht exakt ausfüllt. */
.browser-content {
  position:        relative;
  background:      #1C2840;
  padding:         var(--s-5);
  display:         flex;
  flex-direction:  column;
  justify-content: center;
  gap:             var(--s-4);
  aspect-ratio:    1400 / 666;
  overflow:        hidden;
}

/* Echter Screenshot statt Wireframe-Mock (ScheibMedia-Karte) — kein
   Crop, keine Letterbox-Balken, füllt die Fläche exakt aus. */
.browser-content--photo {
  padding: 0;
}

.browser-content--photo img {
  display:    block;
  width:      100%;
  height:     100%;
  object-fit: cover;
}

/* Kurzer Lade-Moment beim ersten Erscheinen der Referenz-Frames:
   Spinner deckt den Content-Bereich ab und blendet aus, sobald die
   Karte zum ersten Mal ins Bild scrollt (an .is-visible gekoppelt,
   dadurch automatisch einmalig — kein eigener Scroll-/Timer-Code). */
.referenz-preview-loader {
  position:       absolute;
  inset:          0;
  display:        flex;
  align-items:    center;
  justify-content: center;
  background:     #1C2840;
  opacity:        1;
  transition:     opacity 300ms ease;
  z-index:        2;
}

.loader-spinner {
  width:         28px;
  height:        28px;
  border-radius: 50%;
  border:        2.5px solid rgba(255,255,255,.15);
  border-top-color: var(--c-accent);
  animation:     fx-spin 0.7s linear infinite;
}

@keyframes fx-spin {
  to { transform: rotate(360deg); }
}

html.js .referenz-card--real.is-visible .referenz-preview-loader {
  transition-delay: 500ms;
  opacity:          0;
  pointer-events:   none;
}

@media (prefers-reduced-motion: reduce) {
  .referenz-preview-loader { transition: none; opacity: 0; }
  .loader-spinner { animation: none; }
}

.referenz-badge {
  display:     flex;
  align-items: center;
  gap:         var(--s-2);
  font-size:   var(--t-sm);
  color:       rgba(243,240,234,.5);
}

.badge-dot {
  width:         7px;
  height:        7px;
  border-radius: 50%;
  background:    var(--c-accent);
  opacity:       .7;
  flex-shrink:   0;
}
.badge-label { color: var(--c-accent); font-weight: 500; }
.badge-sep   { opacity: .4; }
.badge-name  { opacity: .7; }


/* =============================================================
   VERGLEICH — zwei Karten: „Andere Anbieter" (zurückgenommen) und
   Voelkel Systems (Navy, überlappt die andere Karte, mit Aktion)
   ============================================================= */
.section-vergleich .headline-display { margin-bottom: var(--s-10); max-width: 26ch; }

.vs {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-5);
}
.vs-card {
  position:      relative;
  border-radius: var(--r-lg);
  padding:       var(--s-8) var(--s-6);
}
.vs-card--other {
  background: rgba(255, 255, 255, .6);
  border:     1px solid var(--c-border);
}
.vs-card--own {
  background:  var(--c-navy);
  color:       rgba(243, 240, 234, .92);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .08),
    0 2px 6px   rgba(20, 33, 61, .10),
    0 14px 34px rgba(20, 33, 61, .18),
    0 36px 80px rgba(46, 74, 133, .22);
}
.vs-title {
  margin-bottom:  var(--s-6);
  text-align:     center;
  font-family:    var(--f-display);
  font-size:      var(--t-2xl);
  font-weight:    600;
  letter-spacing: -0.03em;
  line-height:    1.15;
}
.vs-card--own .vs-title { color: #fff; }

.vs-list { list-style: none; display: grid; gap: var(--s-3); }
.vs-item {
  display:       flex;
  align-items:   center;
  gap:           var(--s-3);
  font-size:     var(--t-base);
  line-height:   1.5;
}
.vs-item strong { font-weight: 700; }
.vs-icon {
  flex-shrink:   0;
  width:         22px;
  height:        22px;
  padding:       4px;
  border-radius: 50%;
}
.vs-card--other .vs-item { color: var(--c-muted); padding-block: var(--s-1); }
.vs-card--other .vs-item strong { color: var(--c-text); }
.vs-card--other .vs-icon { background: rgba(26, 26, 26, .72); color: #fff; }

.vs-card--own .vs-item {
  padding:       var(--s-3) var(--s-4);
  border-radius: var(--r-sm);
  background:    rgba(255, 255, 255, .06);
  box-shadow:    inset 0 0 0 1px rgba(255, 255, 255, .06);
}
.vs-card--own .vs-item strong { color: #fff; }
.vs-card--own .vs-icon { background: var(--c-accent-bright); color: var(--c-navy); }
.vs-cta { width: 100%; margin-top: var(--s-6); justify-content: center; color: var(--c-navy); }

@media (min-width: 900px) {
  .vs {
    display:               grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    align-items:           center;
    gap:                   0;
  }
  .vs-card--other { padding: var(--s-10) calc(var(--s-16) + var(--s-6)) var(--s-10) var(--s-10); }
  .vs-card--own   { margin-left: calc(var(--s-16) * -1); padding: var(--s-10) var(--s-10) var(--s-10); z-index: 1; }
  .vs-title       { font-size: clamp(1.75rem, 2.6vw, 2.25rem); }
}



/* =============================================================
   TESTIMONIAL – volle Breite innerhalb von .referenz-grid
   ============================================================= */
.testi-featured {
  background:    var(--c-card);
  border:        1px solid rgba(46, 74, 133, 0.22);
  border-radius: var(--r-xl);
  box-shadow:    var(--shadow-card);
  padding:       var(--s-10) var(--s-12);
  display:       flex;
  flex-direction: column;
  gap:           var(--s-6);
}

@media (max-width: 767px) {
  .testi-featured { padding: var(--s-6); }
}

.testi-quote-mark {
  font-family:  var(--f-display);
  font-size:    clamp(3rem, 12vw, 5rem);
  line-height:  0.7;
  color:        var(--c-accent);
  opacity:      0.60;
  user-select:  none;
}

.testi-blockquote {
  font-family:  var(--f-display);
  font-size:    clamp(1.125rem, 2vw, 1.375rem);
  font-weight:  400;
  line-height:  1.65;
  color:        var(--c-text);
  flex:         1;
}

.testi-cite {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-1);
  font-style:     normal;
  border-top:     1px solid rgba(46, 74, 133, 0.18);
  padding-top:    var(--s-6);
}

.testi-name {
  font-family:    var(--f-display);
  font-weight:    600;
  font-size:      var(--t-base);
  color:          var(--c-accent);
  letter-spacing: -0.01em;
}

.testi-role {
  font-size: var(--t-sm);
  color:     var(--c-muted);
}

/* =============================================================
   FAQ – Accordion
   ============================================================= */
.section-faq {
  padding-block: var(--sec-pad);
}

.faq-layout {
  display:     grid;
  grid-template-columns: 1fr 1.6fr;
  gap:         var(--s-16);
  align-items: start;
}

.faq-intro {
  position: sticky;
  top: calc(80px + var(--s-10));
}

.faq-intro .headline-display { margin-bottom: 0; }

@media (max-width: 900px) {
  .faq-layout {
    grid-template-columns: 1fr;
    gap: var(--s-10);
  }
  .faq-intro {
    position: static;
  }
}

.faq-list {
  display: flex;
  flex-direction: column;
}

.faq-item {
  border-bottom: 1px solid var(--c-border);
}
.faq-item:first-child { border-top: 1px solid var(--c-border); }

.faq-trigger {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             var(--s-6);
  width:           100%;
  padding-block:   var(--s-6);
  background:      none;
  border:          none;
  cursor:          pointer;
  touch-action:    manipulation;
  text-align:      left;
  font-family:     var(--f-display);
  font-size:       var(--t-lg);
  font-weight:     600;
  letter-spacing:  -0.015em;
  color:           var(--c-text);
  -webkit-tap-highlight-color: transparent;
  transition:      color var(--tr-fast);
}

.faq-trigger:active      { color: var(--c-accent); }
.faq-trigger:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius:  2px;
}

.faq-icon {
  flex-shrink: 0;
  color:       var(--c-navy);
  transition:  transform var(--tr-base);
}

.faq-trigger[aria-expanded="true"] .faq-icon {
  transform: rotate(180deg);
}

/* Sanftes Auf-/Zuklappen: grid-rows 0fr→1fr (animierbar, ohne feste Höhe) */
.faq-answer {
  display:            grid;
  grid-template-rows: 0fr;
  transition:         grid-template-rows 320ms cubic-bezier(0.16, 1, 0.3, 1);
}

.faq-item.is-open .faq-answer { grid-template-rows: 1fr; }

.faq-answer p {
  overflow:       hidden;
  min-height:     0;
  padding-bottom: 0;
  transition:     padding-bottom 320ms cubic-bezier(0.16, 1, 0.3, 1);
  font-size:      var(--t-base);
  line-height:    1.78;
  color:          var(--c-muted);
  max-width:      65ch;
}

.faq-item.is-open .faq-answer p { padding-bottom: var(--s-6); }

@media (prefers-reduced-motion: reduce) {
  .faq-answer, .faq-answer p { transition: none; }
}


/* =============================================================
   ÜBER MICH
   ============================================================= */
.section-ueber-mich {
  padding-block: var(--sec-pad);
}

.ueber-mich-split {
  display:               grid;
  grid-template-columns: 1fr;
  gap:                   var(--s-12);
  align-items:           center;
}

@media (min-width: 768px) {
  .ueber-mich-split {
    grid-template-columns: 55fr 45fr;
    gap:                   var(--s-16);
  }

  .portrait-wrap {
    /* Die 45fr-Spalte selbst wird bei den aktuellen --max-w/--gutter-Werten
       bis zu 508px breit — sichtbar zu groß für ein Portrait. Deckel drauf,
       justify-self:end hält es weiter bündig am rechten Spaltenrand statt
       den nun kleineren Rest der Spalte links auszufüllen. */
    max-width:    420px;
    justify-self: end;
  }
}

.ueber-mich-text .body-text {
  max-width: none;
}

.ueber-mich-text .body-text + .body-text {
  margin-top: var(--s-5);
}

.portrait-wrap {
  border-radius: 28px;
  overflow:      hidden;
  background:    var(--c-navy);
  box-shadow:
    0 2px 4px   rgba(20,33,61,.06),
    0 8px 24px  rgba(20,33,61,.14),
    0 28px 64px rgba(20,33,61,.18),
    0 56px 96px rgba(20,33,61,.10);
}

.portrait-wrap img {
  width:   100%;
  /* height:auto zwingend: das height-Attribut (CLS-Fix) würde sonst
     als Fixhöhe wirken und das Bild verzerren */
  height:  auto;
  display: block;
}

@media (max-width: 767px) {
  /* Mobil: Porträt über der Überschrift */
  .ueber-mich-split { gap: var(--s-8); }
  .portrait-wrap {
    order:         -1;
    border-radius: 18px;
    max-height:    360px;
  }

  .portrait-wrap img {
    height:          360px;
    object-fit:      cover;
    /* "top" zeigte fast nur den leeren dunklen Hintergrund über dem Kopf
       (im Quellbild ~27% Freiraum über dem Haaransatz) — Gesicht war fast
       komplett abgeschnitten. Zentriert auf den Kopf-/Schulter-Bereich. */
    object-position: center 20%;
  }
}

/* Namenssignatur zum Abschluss — der einzige Navy-Akzent dieser Sektion. */
.ueber-mich-signature {
  position:       relative;
  margin-top:     var(--s-8);
  padding-top:    var(--s-5);
  display:        flex;
  flex-direction: column;
  gap:            2px;
}
.ueber-mich-signature::before {
  content:    "";
  position:   absolute;
  top:        0;
  left:       0;
  width:      48px;
  height:     2px;
  background: var(--c-accent);
}
.ueber-mich-signature-name {
  font-family:    var(--f-display);
  font-size:      var(--t-lg);
  font-weight:    600;
  letter-spacing: -0.01em;
  color:          var(--c-text);
}
.ueber-mich-signature-role {
  font-size: var(--t-sm);
  color:     var(--c-muted);
}


/* =============================================================
   KONTAKT / CTA
   ============================================================= */

/* Personal intro card */
.kontakt-hero {
  display:        flex;
  align-items:    center;
  gap:            var(--s-8);
  background:     var(--c-navy);
  border-radius:  var(--r-xl);
  padding:        var(--s-10) var(--s-12);
  margin-bottom:  var(--s-16);
  flex-wrap:      wrap;
}

.kontakt-hero-photo {
  width:         96px;
  height:        96px;
  border-radius: 50%;
  overflow:      hidden;
  flex-shrink:   0;
  border:        3px solid rgba(46, 74, 133,0.35);
  box-shadow:    0 0 0 6px rgba(46, 74, 133,0.10);
}

.kontakt-hero-photo img {
  width:          100%;
  height:         100%;
  object-fit:     cover;
  /* Gesicht mittig im Kreis: das Foto hat oben viel Headroom */
  object-position: center 28%;
}

.kontakt-hero-text {
  flex: 1;
  min-width: 240px;
}

.kontakt-hero-text .headline-display {
  color:         var(--c-light);
  font-size:     var(--t-2xl);
  margin-bottom: var(--s-3);
}

.kontakt-hero-text .body-text {
  color:      rgba(243,240,234,0.72);
  font-size:  var(--t-base);
  font-style: italic;
  max-width:  none;
}

.kontakt-hero-btn {
  flex-shrink: 0;
}

@media (max-width: 640px) {
  .kontakt-hero {
    flex-direction: column;
    align-items:    flex-start;
    padding:        var(--s-8);
  }
  .kontakt-hero-btn { width: 100%; }
}

/* ── KONTAKT-WEGE: drei gleichwertige Karten statt eines einzelnen
   Kalenders ─────────────────────────────────────────────────────
   Gleiche Bauweise wie .referenz-card: Karte auf --c-card, Hover hebt sie
   an, Active drückt sie leicht ein. Alle drei sind echte <a href> (auch die
   Termin-Karte) — progressive enhancement, siehe index.html. */
.kontakt-wege {
  display:               grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap:                   var(--s-5);
  margin-bottom:         var(--s-5);
}

.kontakt-weg {
  display:        flex;
  flex-direction: column;
  align-items:    flex-start;
  gap:            var(--s-2);
  padding:        var(--s-6);
  background:     var(--c-card);
  border-radius:  var(--r-lg);
  box-shadow:     var(--shadow-card);
  transition:     box-shadow 300ms ease, transform 300ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .kontakt-weg:hover {
    box-shadow: var(--shadow-card-hover);
    transform:  translateY(-2px);
  }
}
.kontakt-weg:active {
  box-shadow: var(--shadow-card);
  transform:  translateY(0) scale(0.99);
}
.kontakt-weg:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 3px;
  border-radius:  var(--r-lg);
}

/* Aktive Termin-Karte: zeigt, dass der Kalender darunter offen ist —
   derselbe Akzentrand wie bei anderen "eingeschalteten" Zuständen der Seite. */
.kontakt-weg.is-active {
  box-shadow: inset 0 0 0 2px var(--c-accent), var(--shadow-card);
}

.kontakt-weg-icon {
  width:  28px;
  height: 28px;
  color:  var(--c-accent);
  margin-bottom: var(--s-1);
}

.kontakt-weg-title {
  font-family:    var(--f-display);
  font-size:      var(--t-lg);
  font-weight:    600;
  letter-spacing: -0.015em;
  color:          var(--c-text);
}

.kontakt-weg-desc {
  font-size:   var(--t-sm);
  color:       var(--c-muted);
  line-height: 1.5;
}

.kontakt-weg-meta {
  font-size:      var(--t-xs);
  color:          var(--c-accent);
  font-weight:    600;
  letter-spacing: 0.02em;
  margin-top:     auto;
  padding-top:    var(--s-2);
}

.kontakt-wege-note {
  max-width:     52ch;
  margin-inline: auto;
  margin-bottom: var(--s-10);
  text-align:    center;
  font-size:     var(--t-xs);
  color:         var(--c-muted);
  line-height:   1.6;
}
.kontakt-wege-note a {
  color:           var(--c-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.kontakt-wege-note a:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius:  2px;
}
@media (hover: hover) and (pointer: fine) {
  .kontakt-wege-note a:hover { color: var(--c-accent); }
}
.kontakt-wege-note a:active { color: var(--c-accent); }

/* Cal.com-Embed steht jetzt allein, zentriert statt in einer Zweispalte
   neben Begleittext — der stand ohnehin schon im Embed selbst. Breit genug
   lassen, damit Cal.com intern auf die dreispaltige Ansicht umschaltet
   (Termin-Infos | Kalender | Uhrzeiten nebeneinander) statt gestapelt
   untereinander — der Umschaltpunkt liegt bei Cal.com um ~900px Breite. */
.kontakt-booking {
  max-width:     980px;
  margin-inline: auto;
  scroll-margin-top: var(--s-8);
}
/* tabindex="-1": nur programmatisch fokussierbar (nach dem Aufklappen),
   nicht Teil der Tab-Reihenfolge. Der sichtbare Fokusring auf einem ganzen
   Block wäre unruhig — das Scrollen dorthin ist bereits das Signal. */
.kontakt-booking:focus { outline: none; }

/* Kein eigener Scrollbereich: eine Karte, in der man nochmal scrollen muss,
   um an die Uhrzeiten zu kommen, ist eine Scrollfalle. Der Cal.com-Embed
   meldet seine Höhe selbst per postMessage — die Karte wächst einfach mit
   der Seite mit, wie jede andere Sektion auch. In der dreispaltigen
   Ansicht (breiter Container, siehe .kontakt-booking) bleibt die Höhe
   ohnehin moderat, das alte 720px-Limit stammte noch von der schmalen,
   gestapelten Darstellung. */
.cal-embed-wrap {
  width:         100%;
  border-radius: var(--r-md);
  box-shadow:    var(--shadow-card);
}

#cal-inline-embed {
  width:      100%;
  min-height: 640px;
}

.kontakt-closing {
  margin-top: var(--s-16);
  text-align: center;
  font-size:  var(--t-sm);
  color:      var(--c-muted);
}


/* =============================================================
   FOOTER
   ============================================================= */
.site-footer {
  background:
    radial-gradient(circle at 50% 30%, rgba(46, 74, 133, 0.06) 0%, transparent 60%),
    var(--c-navy-deep);
  padding-block: var(--sec-pad);
}

.footer-brand        { margin-bottom: var(--s-8); }
/* display: flex (nicht block) — sonst rutscht die Bildmarke über den
   Schriftzug statt daneben. */
.footer-logo-img      { height: 2.15rem; width: auto; display: block; margin-bottom: var(--s-2); }

.footer-tagline {
  font-size: var(--t-sm);
  color:     rgba(243,240,234,.4);
}

.footer-divider {
  height:           1px;
  background-color: rgba(243,240,234,.08);
  margin-block:     var(--s-8);
}

.footer-columns {
  display:               grid;
  grid-template-columns: 1fr;
  gap:                   var(--s-10);
}

@media (min-width: 768px) {
  .footer-columns { grid-template-columns: 1fr 1fr; }
}

.footer-col-title {
  font-family:    var(--f-body);
  font-size:      var(--t-sm);
  font-weight:    600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color:          rgba(243,240,234,.75);
  margin-bottom:  var(--s-4);
}

.footer-address,
.footer-note {
  font-size:   var(--t-sm);
  line-height: 1.85;
  color:       rgba(243,240,234,.45);
}

.footer-address { margin-bottom: var(--s-4); }

.footer-address a,
.footer-note a {
  display:      inline-flex;
  align-items:  center;
  min-height:   44px;
  color:        rgba(243,240,234,.45);
  transition:   color var(--tr-fast);
  touch-action: manipulation;
}
.footer-address a:hover,
.footer-note a:hover  { color: var(--c-accent); }
.footer-address a:active,
.footer-note a:active { color: var(--c-accent-hover); }

.footer-copy {
  margin-top: var(--s-10);
  font-size:  var(--t-xs);
  color:      rgba(243,240,234,.28);
}

/* Footer-Link-Liste (Impressum · Datenschutz · Cookie-Einstellungen) */
.footer-legal-list {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-2);
}
.footer-legal-list a,
.footer-legal-btn {
  display:      inline-flex;
  align-items:  center;
  min-height:   44px;
  font-size:    var(--t-sm);
  line-height:  1.85;
  color:        rgba(243,240,234,.45);
  transition:   color var(--tr-fast);
  touch-action: manipulation;
}
.footer-legal-list a:hover,
.footer-legal-btn:hover { color: var(--c-accent); }
.footer-legal-list a:active,
.footer-legal-btn:active { color: var(--c-accent-hover); }
.footer-legal-btn {
  background: none;
  border:     none;
  padding:    0;
  font-family: var(--f-body);
  text-align:  left;
  cursor:      pointer;
}
.footer-legal-btn:focus-visible,
.footer-legal-list a:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 3px;
  border-radius:  2px;
}


/* =============================================================
   IMPRESSUM / DATENSCHUTZ — schlanke Unterseiten
   ============================================================= */
.section-legal { padding-top: calc(var(--sec-pad) + var(--s-16)); }

.section-legal .headline-display { margin-bottom: var(--s-10); max-width: none; }

.legal-content .headline-mid {
  margin-top:    var(--s-10);
  margin-bottom: var(--s-4);
}
.legal-content .headline-mid:first-child { margin-top: 0; }

.legal-content .body-text { max-width: 68ch; }
.legal-content .body-text + .body-text { margin-top: var(--s-4); }
.legal-content .body-text + .headline-mid,
.legal-content .legal-list + .headline-mid { margin-top: var(--s-10); }

.legal-list {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-2);
  max-width:      68ch;
  margin-block:   var(--s-4);
}
.legal-list li {
  position:     relative;
  padding-left: var(--s-6);
  font-size:    var(--t-lg);
  line-height:  1.6;
  color:        var(--c-text);
}
.legal-list li::before {
  content:       '';
  position:      absolute;
  left:          0;
  top:           0.65em;
  width:         6px;
  height:        6px;
  border-radius: 50%;
  background:    var(--c-accent);
}

.legal-back {
  margin-top: var(--s-16);
}
.legal-back a {
  font-weight:     600;
  color:           var(--c-navy);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition:      color var(--tr-fast);
}
.legal-back a:active { color: var(--c-accent); }
@media (hover: hover) and (pointer: fine) {
  .legal-back a:hover { color: var(--c-accent); }
}
.legal-back a:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 3px;
  border-radius:  2px;
}


/* =============================================================
   COOKIE-BANNER (consent.js)
   ============================================================= */
.cookie-banner {
  position:      fixed;
  left:          var(--s-4);
  right:         var(--s-4);
  bottom:        calc(var(--s-4) + env(safe-area-inset-bottom));
  z-index:       200;
  /* 860 statt 720: die beiden Buttons belegen rund 450 px und schrumpfen nicht
     (flex-shrink:0). Bei 720 blieben dem Text nur ~200 px, er brach in eine
     schmale Spalte um. */
  max-width:     860px;
  margin-inline: auto;
  border-radius: var(--r-lg);
  background:
    radial-gradient(circle at 50% 30%, rgba(46, 74, 133, 0.09) 0%, transparent 60%),
    var(--c-navy);
  box-shadow:
    0 2px 4px   rgba(20,33,61,.06),
    0 8px 24px  rgba(20,33,61,.14),
    0 28px 64px rgba(20,33,61,.18);
  padding:    var(--s-6) var(--s-8);
  opacity:    0;
  visibility: hidden;
  pointer-events: none;
  transform:  translateY(16px);
  transition: opacity 280ms ease, transform 280ms ease, visibility 0s linear 280ms;
}
.cookie-banner.is-open {
  opacity:        1;
  visibility:     visible;
  pointer-events: auto;
  transform:      none;
  transition:     opacity 280ms ease, transform 280ms ease;
}

.cookie-banner-inner {
  display:        flex;
  flex-direction: column;
  gap:            var(--s-5);
}
@media (min-width: 640px) {
  .cookie-banner-inner {
    flex-direction:  row;
    align-items:     center;
    justify-content: space-between;
    gap:             var(--s-8);
  }
  /* Ohne flex-grow bleibt der Textblock auf seiner Inhaltsbreite stehen und
     bricht in eine schmale Spalte um, während rechts Platz frei bleibt.
     min-width:0 hebt die flex-Grundregel auf, die Schrumpfen unter die
     längste Zeile verhindert. */
  .cookie-banner-text { flex: 1 1 auto; min-width: 0; }
}

.cookie-banner-title {
  font-family:   var(--f-display);
  font-size:     var(--t-lg);
  font-weight:   600;
  color:         var(--c-light);
  margin-bottom: var(--s-2);
}

.cookie-banner-desc {
  font-size:   var(--t-sm);
  line-height: 1.6;
  color:       rgba(243, 240, 234, 0.72);
  max-width:   46ch;
}
.cookie-banner-desc a {
  display:               inline-block;
  padding-block:         6px;
  color:                 rgba(243, 240, 234, 0.9);
  text-decoration:       underline;
  text-underline-offset: 2px;
}
.cookie-banner-desc a:active { color: var(--c-accent); }
.cookie-banner-desc a:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius:  2px;
}
@media (hover: hover) and (pointer: fine) {
  .cookie-banner-desc a:hover { color: var(--c-accent); }
}

.cookie-banner-actions {
  display:     flex;
  gap:         var(--s-3);
  flex-wrap:   wrap;
  flex-shrink: 0;
}
.cookie-banner-actions .btn { flex: 1 1 auto; white-space: nowrap; }
@media (min-width: 640px) {
  .cookie-banner-actions .btn { flex: none; }
}

@media (max-width: 480px) {
  .cookie-banner { padding: var(--s-5) var(--s-6); }
}



/* =============================================================
   404-SEITE
   ============================================================= */
.section-error {
  min-height:      100svh;
  display:         flex;
  align-items:     center;
  padding-top:     calc(var(--sec-pad) + var(--s-16));
}

/* Mobil nicht vertikal zentrieren: sonst landet der CTA-Button auf halber
   Viewport-Höhe genau dort, wo der Cookie-Banner beim ersten Besuch liegt. */
@media (max-width: 767px) {
  .section-error {
    min-height:  auto;
    align-items: flex-start;
    padding-bottom: var(--s-16);
  }
}

.error-404 {
  max-width:     60ch;
  margin-inline: auto;
  text-align:    center;
}
.error-404 .headline-display { margin-block: var(--s-4) var(--s-5); }
.error-404 .body-text { margin-inline: auto; }

.error-404-actions {
  display:        flex;
  flex-direction: column;
  align-items:    center;
  gap:            var(--s-4);
  margin-top:     var(--s-8);
}

.error-404-phone {
  display:      inline-flex;
  align-items:  center;
  min-height:   44px;
  font-size:    var(--t-sm);
  color:        var(--c-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  transition:   color var(--tr-fast);
  touch-action: manipulation;
}
.error-404-phone:active { color: var(--c-accent); }
@media (hover: hover) and (pointer: fine) {
  .error-404-phone:hover { color: var(--c-accent); }
}
.error-404-phone:focus-visible {
  outline:        2px solid var(--c-accent);
  outline-offset: 3px;
  border-radius:  2px;
}


/* =============================================================
   GRAIN / FILM-TEXTURE OVERLAY
   Der einzige Grain-Layer auf Desktop (ein fixed-Pseudo-Element).
   Niedrige Opacity: Körnung als Struktur spürbar, nie sichtbar.
   Mobil-Pendant: body::before weiter unten, eigene Körnung im
   selben Layer wie der statische Mesh-Fallback.
   ============================================================= */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  opacity: 0.055;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 300px 300px;
  background-repeat: repeat;
}
@media (prefers-reduced-motion: reduce) {
  body::after { display: none; }
}

/* Aus auf dem Handy: eine fixe Vollbild-Rauschebene über allem, inklusive
   dem laufenden Video-Scrub — zusätzliche Compositing-Last auf schwächeren
   Mobil-GPUs, bei 5,5% Opazität ohnehin kaum wahrnehmbar. */
@media (max-width: 767px) {
  body::after { display: none; }
}

/* =============================================================
   GRAINIENT — STATISCHER MOBIL-FALLBACK
   Unter 767px läuft kein WebGL (initGrainient() bricht früh ab,
   s. script.js). Dieser Layer bildet dieselbe Blob-Komposition als
   fixiertes CSS-Mesh nach, im selben z-index:-1-Slot, den auf
   Desktop der Canvas belegt (body erzeugt keinen Stacking-Context,
   body::before ist frei — nur body::after ist für den Grain belegt).

   Positionen sind die t=0-Positionen der Shader-Blobs (BLOB_POS in
   script.js), umgerechnet von UV-Einheiten auf CSS-Prozent:
   x% = (x+0.5)*100, y% = (0.5-y)*100 (uv.y ist bottom-up). Radien
   in vh statt vw: der Shader normiert auf Höhe (d.x wird mit dem
   Seitenverhältnis skaliert, s. dortiger Kommentar) — 1:1 auf vw
   übernommen würden die Radien auf 9:19,5 zu schmalen senkrechten
   Streifen statt runden Wolken.
   Vier Alpha-Stops statt zwei: nähert den smoothstep-Abfall des
   Shaders an (Werte bei f=0/.3/.58/.8 von 1-smoothstep(0,1,f)) —
   eine lineare Rampe knickt an beiden Enden sichtbar.
   Peak-Alpha je Blob = navyStrength(0.20) × BLOB_AMP, Farben nach
   BLOB_TINT zwischen --c-navy und #4A6BB0 gemischt (Blob 2 landet
   nahe --c-accent). navyStrength per Muster-Seite entschieden (0.05/
   0.07 waren zu zurückhaltend, 0.40 am 17.09.2026 auf 0.20 halbiert)
   — hier 1:1 mitgezogen, sonst wäre Mobil deutlich schwächer als
   Desktop.
   Körnung liegt in derselben Ebene als oberste background-image,
   Opazität im SVG selbst (rect opacity='0.05') statt per CSS
   opacity auf das ganze Element — sonst würden auch die Verläufe
   mitgedimmt. So bleibt es bei einem fixed-Layer statt zweien. */
@media (max-width: 767px) {
  body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-color: #FCFCFD;
    background-image:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E"),
      radial-gradient(circle 62vh at 8% 16%,
        rgba(20, 33, 61, .124) 0%, rgba(20, 33, 61, .096) 30%,
        rgba(20, 33, 61, .048) 58%, rgba(20, 33, 61, 0) 80%),
      radial-gradient(circle 55vh at 96% 32%,
        rgba(74, 107, 176, .112) 0%, rgba(74, 107, 176, .088) 30%,
        rgba(74, 107, 176, .044) 58%, rgba(74, 107, 176, 0) 80%),
      radial-gradient(circle 58vh at 36% 94%,
        rgba(46, 74, 133, .100) 0%, rgba(46, 74, 133, .080) 30%,
        rgba(46, 74, 133, .040) 58%, rgba(46, 74, 133, 0) 80%),
      radial-gradient(circle 48vh at 88% 86%,
        rgba(28, 44, 78, .092) 0%, rgba(28, 44, 78, .072) 30%,
        rgba(28, 44, 78, .036) 58%, rgba(28, 44, 78, 0) 80%),
      radial-gradient(circle 34vh at 52% 4%,
        rgba(63, 92, 153, .068) 0%, rgba(63, 92, 153, .052) 30%,
        rgba(63, 92, 153, .028) 58%, rgba(63, 92, 153, 0) 80%);
    background-size: 300px 300px, auto, auto, auto, auto, auto;
    background-repeat: repeat, no-repeat, no-repeat, no-repeat, no-repeat, no-repeat;
  }

  /* Freigabe: dieselbe Rolle wie .grainient-active .section-light auf
     Desktop, nur dauerhaft statt an eine JS-Klasse gebunden. */
  .section-light { background: none; }

  /* Naht zum Hero-Portal bleibt erhalten (s. Kommentare bei .hp-field
     und .section-light.section-problem) — der Layer ist hier zwar
     statisch, die Farbkante zwischen Portal-Ende und Fallback-Grund
     würde ohne die Freigabe trotzdem als Sprung auffallen. */
  .section-light.section-problem {
    background: linear-gradient(to bottom, rgb(239, 241, 246) 0px, rgba(239, 241, 246, 0) 220px);
  }
  .section-light.section-statement {
    background: rgb(239, 241, 246);
  }
}


/* =============================================================
   BORDER GLOW
   ============================================================= */
.border-glow-card {
  --edge-proximity: 0;
  --cursor-angle: 45deg;
  --edge-sensitivity: 30;
  --color-sensitivity: calc(var(--edge-sensitivity) + 20);
  --border-radius: 24px;
  --glow-padding: 40px;
  --cone-spread: 25;
  --fill-opacity: 0.5;

  position: relative;
  border-radius: var(--border-radius);
  isolation: isolate;
  transform: translate3d(0, 0, 0.01px);
  overflow: visible;
  border: 1px solid rgb(255 255 255 / 12%);
}

.border-glow-card::before,
.border-glow-card::after,
.border-glow-card > .edge-light {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  transition: opacity 0.25s ease-out;
  z-index: -1;
}

.border-glow-card:not(:hover)::before,
.border-glow-card:not(:hover)::after,
.border-glow-card:not(:hover) > .edge-light {
  opacity: 0;
  transition: opacity 0.75s ease-in-out;
}

/* colored mesh-gradient border */
.border-glow-card::before {
  border: 1px solid transparent;
  background:
    linear-gradient(var(--card-bg, #14213D) 0 100%) padding-box,
    linear-gradient(rgb(255 255 255 / 0%) 0% 100%) border-box,
    var(--gradient-one,   radial-gradient(at 80% 55%, #2E4A85 0px, transparent 50%)) border-box,
    var(--gradient-two,   radial-gradient(at 69% 34%, #14213D 0px, transparent 50%)) border-box,
    var(--gradient-three, radial-gradient(at  8%  6%, #FAFAF8 0px, transparent 50%)) border-box,
    var(--gradient-four,  radial-gradient(at 41% 38%, #2E4A85 0px, transparent 50%)) border-box,
    var(--gradient-five,  radial-gradient(at 86% 85%, #14213D 0px, transparent 50%)) border-box,
    var(--gradient-six,   radial-gradient(at 82% 18%, #FAFAF8 0px, transparent 50%)) border-box,
    var(--gradient-seven, radial-gradient(at 51%  4%, #14213D 0px, transparent 50%)) border-box,
    var(--gradient-base,  linear-gradient(#2E4A85 0 100%)) border-box;
  opacity: calc((var(--edge-proximity) - var(--color-sensitivity)) / (100 - var(--color-sensitivity)));
  mask-image: radial-gradient(
    ellipse 80% 80% at calc(var(--cursor-x, 50%) * 1%) calc(var(--cursor-y, 50%) * 1%),
    black 0%, transparent 100%
  );
}

/* colored mesh-gradient background fill near edges */
.border-glow-card::after {
  border: 1px solid transparent;
  background:
    var(--gradient-one,   radial-gradient(at 80% 55%, #2E4A85 0px, transparent 50%)) padding-box,
    var(--gradient-two,   radial-gradient(at 69% 34%, #14213D 0px, transparent 50%)) padding-box,
    var(--gradient-three, radial-gradient(at  8%  6%, #FAFAF8 0px, transparent 50%)) padding-box,
    var(--gradient-four,  radial-gradient(at 41% 38%, #2E4A85 0px, transparent 50%)) padding-box,
    var(--gradient-five,  radial-gradient(at 86% 85%, #14213D 0px, transparent 50%)) padding-box,
    var(--gradient-six,   radial-gradient(at 82% 18%, #FAFAF8 0px, transparent 50%)) padding-box,
    var(--gradient-seven, radial-gradient(at 51%  4%, #14213D 0px, transparent 50%)) padding-box,
    var(--gradient-base,  linear-gradient(#2E4A85 0 100%)) padding-box;
  mask-image: radial-gradient(
    ellipse 100% 100% at calc(var(--cursor-x, 50%) * 1%) calc(var(--cursor-y, 50%) * 1%),
    black 0%, transparent 70%
  );
  opacity: calc(var(--fill-opacity, 0.5) * (var(--edge-proximity) - var(--color-sensitivity)) / (100 - var(--color-sensitivity)));
  mix-blend-mode: soft-light;
}

/* outer glow layer */
.border-glow-card > .edge-light {
  inset: calc(var(--glow-padding) * -1);
  pointer-events: none;
  z-index: 1;
  mask-image: radial-gradient(
    ellipse 70% 70% at calc(var(--cursor-x, 50%) * 1%) calc(var(--cursor-y, 50%) * 1%),
    black 0%, transparent 100%
  );
  opacity: calc((var(--edge-proximity) - var(--edge-sensitivity)) / (100 - var(--edge-sensitivity)));
  mix-blend-mode: plus-lighter;
}

.border-glow-card > .edge-light::before {
  content: "";
  position: absolute;
  inset: var(--glow-padding);
  border-radius: inherit;
  box-shadow:
    inset 0 0 0 1px   var(--glow-color,    hsl(38deg 54% 54% / 100%)),
    inset 0 0 1px 0   var(--glow-color-60, hsl(38deg 54% 54% /  60%)),
    inset 0 0 3px 0   var(--glow-color-50, hsl(38deg 54% 54% /  50%)),
    inset 0 0 6px 0   var(--glow-color-40, hsl(38deg 54% 54% /  40%)),
    inset 0 0 15px 0  var(--glow-color-30, hsl(38deg 54% 54% /  30%)),
    inset 0 0 25px 2px var(--glow-color-20, hsl(38deg 54% 54% / 20%)),
    inset 0 0 50px 2px var(--glow-color-10, hsl(38deg 54% 54% / 10%)),
          0 0 1px 0   var(--glow-color-60, hsl(38deg 54% 54% /  60%)),
          0 0 3px 0   var(--glow-color-50, hsl(38deg 54% 54% /  50%)),
          0 0 6px 0   var(--glow-color-40, hsl(38deg 54% 54% /  40%)),
          0 0 15px 0  var(--glow-color-30, hsl(38deg 54% 54% /  30%)),
          0 0 25px 2px var(--glow-color-20, hsl(38deg 54% 54% / 20%)),
          0 0 50px 2px var(--glow-color-10, hsl(38deg 54% 54% / 10%));
}

.border-glow-inner {
  display:   flex;
  flex-direction: column;
  position:  relative;
  overflow:  visible;
  z-index:   1;
}

.portrait-wrap.border-glow-card {
  --border-radius: 28px;
}
.portrait-wrap.border-glow-card > .border-glow-inner {
  overflow: hidden;
  border-radius: var(--border-radius);
}

/* Referenz section on light bg — badge text */
.section-referenz .referenz-badge {
  color: var(--c-navy);
}

/* ── GRAINIENT: reveal WebGL canvas through light-bg elements ──
   Kein eigenes Radial mehr: der Mesh-Shader liefert die Navy-Wolken
   jetzt selbst (uNavyStrength) — ein zusätzliches 7%-Radial hier war
   staerker als der gesamte geplante Mesh-Anteil und hätte ihn beim
   Tuning komplett überdeckt. */
.grainient-active .section-light {
  background: none;
}

/* Ausnahme für den Abschnitt direkt unter dem Hero-Portal: dort träfe der
   ANIMIERTE Canvas auf die statische Endfarbe des Portals — eine Kante, die
   sich per Farbwert nicht treffen lässt, weil der Canvas sich bewegt.
   Deshalb setzt #problem oben deckend mit genau der Portal-Endfarbe an und
   gibt den Canvas erst 220px tiefer frei, wo keine Kante mehr sichtbar ist.
   Muss nach der Regel oben stehen: gleiche Spezifität, hier gewinnt die
   spätere. */
.grainient-active .section-light.section-problem {
  background: linear-gradient(to bottom, rgb(239, 241, 246) 0px, rgba(239, 241, 246, 0) 220px);
}

/* Dieselbe Kanten-Problematik gilt für die Mini-Sektion zwischen Portal und
   #problem — nur bleibt sie hier dauerhaft flach statt nach 220px auf den
   Canvas freizugeben: die Sektion selbst ist kaum größer als die Freigabe-
   Strecke, ein Reveal würde fast ihre ganze Höhe einnehmen und unruhig
   wirken. Der Canvas wird stattdessen weiterhin erst in #problem sichtbar,
   das dort unverändert seine eigene 220px-Freigabe trägt. */
.grainient-active .section-light.section-statement {
  background: rgb(239, 241, 246);
}

/* =============================================================
   EFFEKTE — Scroll-, Load- und Hover-Inszenierung
   Alle Initialzustände sind an html.js gebunden: ohne JS bleibt
   die Seite vollständig sichtbar. prefers-reduced-motion wird
   global über den Block am Dateianfang neutralisiert.
   ============================================================= */

/* Intro-Delays skalieren mobil kürzer */
:root { --fx-scale: 1; }
@media (max-width: 767px) { :root { --fx-scale: 0.6; } }

/* ── SMOOTH SCROLL ────────────────────────────────────────────
   JS-Lerp übernimmt das Wheel; natives smooth würde jedes
   scrollTo() zusätzlich glätten → aus. */
html.has-smooth-scroll { scroll-behavior: auto; }

/* ── ZEILEN-REVEAL (Headlines) ───────────────────────────────
   JS zerlegt Headlines in .line-mask > .line-inner. Padding-
   Trick verhindert, dass Unterlängen (g, y) geclippt werden. */
.has-lines .line-mask {
  display:        block;
  overflow:       hidden;
  padding-bottom: 0.12em;
  margin-bottom:  -0.12em;
}
.has-lines .line-inner {
  display:    block;
  transform:  translateY(115%);
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
}
.has-lines.is-visible .line-inner {
  transform:        none;
  transition-delay: calc(var(--reveal-delay, 0ms) + var(--line-index, 0) * 90ms);
}
/* Standard-Fade der Headline neutralisieren — die Masken übernehmen */
.headline-display.has-lines {
  opacity:    1;
  transform:  none;
  transition: none;
}

/* ── HERO-LOAD-CHOREOGRAFIE ──────────────────────────────────
   html.js versteckt, html.is-loaded startet die Sequenz. is-loaded kommt
   aus dem <head>-Snippet (Schrift-Gate 400ms). Die Subline ist raus (eigene
   Sektion, normales Scroll-Reveal über .fade-in) — die verbliebene Kette ist
   dadurch kürzer, die Abstände entsprechend enger gezogen.
   Keyframes mit backwards-Fill statt transition-delay, damit
   spätere Zustandswechsel (is-scrolled, is-suppressed) keine
   verschleppten Delays erben. */
html.js:not(.is-loaded) .site-header,
html.js:not(.is-loaded) .hp-toprow,
html.js:not(.is-loaded) .hp-wordmark,
html.js:not(.is-loaded) .hero-actions,
html.js:not(.is-loaded) .hp-scroll { opacity: 0; }

html.js.is-loaded .site-header {
  animation: fx-drop-in 520ms cubic-bezier(0.16, 1, 0.3, 1)
             calc(120ms * var(--fx-scale)) backwards;
}
html.js.is-loaded .hp-toprow {
  animation: fx-rise-in 520ms cubic-bezier(0.16, 1, 0.3, 1)
             calc(190ms * var(--fx-scale)) backwards;
}
html.js.is-loaded .hp-wordmark {
  animation: fx-rise-in 520ms cubic-bezier(0.16, 1, 0.3, 1)
             calc(260ms * var(--fx-scale)) backwards;
}
html.js.is-loaded .hero-actions {
  animation: fx-rise-in 520ms cubic-bezier(0.16, 1, 0.3, 1)
             calc(330ms * var(--fx-scale)) backwards;
}
html.js.is-loaded .hp-scroll {
  animation: fx-rise-in 520ms cubic-bezier(0.16, 1, 0.3, 1)
             calc(400ms * var(--fx-scale)) backwards;
}

/* Headline-Zeilen: getriggert durch is-loaded statt is-visible */
.hero-headline.has-lines .line-inner { transition-duration: 600ms; }
html.is-loaded .hero-headline.has-lines .line-inner {
  transform:        none;
  transition-delay: calc((240ms + var(--line-index, 0) * 90ms) * var(--fx-scale));
}

@keyframes fx-drop-in  { from { opacity: 0; transform: translateY(-24px); } }
@keyframes fx-rise-in  { from { opacity: 0; transform: translateY(18px); } }

/* Riesenwort tritt der Choreografie bewusst NICHT bei: es blendet über
   .is-ready ein (initGlyphPortal), erst nach Font-Gate und Vermessung —
   die auch nach is-loaded landen können. Diese Trennung verhindert ein
   Aufpoppen, würde das Wort hier mitanimiert. */
.hp-field { opacity: 0; transition: opacity 420ms cubic-bezier(0.16, 1, 0.3, 1); }
.glyph-portal.is-ready .hp-field { opacity: 1; }

/* ── AKZENT-SHIMMER ──────────────────────────────────────────
   Einmaliger Glanz-Durchlauf über das Kontakt-Akzentwort (Navy-Karte,
   daher die helle Verlaufsfamilie). Die Hero-Zeile darüber bekommt
   bewusst KEINEN Shimmer: sie ist eine leise 14px-Beschriftung, ein
   wandernder Glanzstreifen darin wäre Unruhe ohne Aussage. */
html.js .kontakt-hero.is-visible .headline-display .text-accent--dark {
  background-image: linear-gradient(105deg,
    var(--c-accent-bright) 42%, var(--c-accent-light-ondark) 50%, var(--c-accent-bright) 58%);
  background-size: 280% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}
html.js .kontakt-hero.is-visible .headline-display .text-accent--dark {
  animation: fx-accent-shimmer 1300ms ease-in-out 900ms both;
}
@keyframes fx-accent-shimmer {
  from { background-position: 130% 0; }
  to   { background-position: -30% 0; }
}

/* ── LEISTUNGS-GRID SPOTLIGHT ────────────────────────────────
   JS setzt --mx/--my pro Karte; Lichtschein + Akzent-Kante folgen
   dem Cursor über das ganze Grid. */
@media (hover: hover) and (pointer: fine) {
  .spotlight-item { position: relative; }

  .spotlight-item::after {
    content:        '';
    position:       absolute;
    inset:          0;
    border-radius:  inherit;
    pointer-events: none;
    opacity:        0;
    transition:     opacity 350ms ease;
    background: radial-gradient(300px circle at var(--mx, 50%) var(--my, 50%),
                rgba(46, 74, 133, 0.10), transparent 65%);
  }

  /* Akzent-Kante: Ring-Maske lässt nur den Rand durch */
  .spotlight-item::before {
    content:        '';
    position:       absolute;
    inset:          0;
    border-radius:  inherit;
    pointer-events: none;
    border:         1px solid transparent;
    background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%),
                rgba(46, 74, 133, 0.55), transparent 70%) border-box;
    -webkit-mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) padding-box, linear-gradient(#000 0 0);
            mask-composite: exclude;
    opacity:    0;
    transition: opacity 350ms ease;
  }

  .spotlight-grid.is-lit .spotlight-item::after,
  .spotlight-grid.is-lit .spotlight-item::before { opacity: 1; }
}

/* ── FOTO-REVEALS + HOVER-ZOOM ───────────────────────────────
   Bilder zoomen beim Erscheinen aus 1.10 in die Maske; ein
   gemeinsamer transform-Übergang deckt Reveal und Hover ab. */
html.js .portrait-wrap img,
html.js .kontakt-hero-photo img {
  transform:  scale(1.10);
  transition: transform 1100ms cubic-bezier(0.16, 1, 0.3, 1);
}
html.js .portrait-wrap.is-visible img,
html.js .kontakt-hero.is-visible .kontakt-hero-photo img {
  transform: none;
}
@media (hover: hover) and (pointer: fine) {
  html.js .portrait-wrap.is-visible:hover img {
    transform:           scale(1.035);
    transition-duration: 700ms;
  }
}

/* ── REFERENZ BAUT SICH SELBST ───────────────────────────────
   Die Browser-Dots poppen beim Scroll-Reveal nacheinander ein,
   bevor der Screenshot darunter sichtbar wird (siehe .referenz-preview-loader). */
html.js .referenz-card--real .browser-dots .dot {
  transform:  scale(0);
  transition: transform 500ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
html.js .referenz-card--real.is-visible .browser-dots .dot {
  transform: none;
}
html.js .referenz-card--real.is-visible .dot-red    { transition-delay: 150ms; }
html.js .referenz-card--real.is-visible .dot-yellow { transition-delay: 210ms; }
html.js .referenz-card--real.is-visible .dot-green  { transition-delay: 270ms; }

/* ── KONTAKT-FINALE ──────────────────────────────────────────
   Die Navy-Karte fährt als Abschluss-Moment auf. */
html.js .kontakt-hero.fade-in {
  transform:           translateY(36px) scale(0.965);
  transition-duration: 1000ms;
}
html.js .kontakt-hero.fade-in.is-visible {
  opacity:   1;
  transform: none;
}


/* ── FAQ-FEINSCHLIFF ─────────────────────────────────────────
   Frage rückt beim Hover leicht nach rechts, Farbe geht
   Richtung Text-Akzent. */
@media (hover: hover) {
  .faq-trigger > span {
    transition: transform 250ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .faq-trigger:hover > span,
  .faq-trigger:focus-visible > span { transform: translateX(6px); }
  .faq-trigger:hover { color: var(--c-accent); }
}

/* ── NAV-GLEITER ─────────────────────────────────────────────
   Eine Akzent-Linie gleitet zum aktiven/gehoverten Link; die
   statischen Per-Link-Unterstriche übernimmt sie komplett. */
.header-nav { position: relative; }

.nav-indicator {
  position:         absolute;
  top:              0;
  left:             0;
  width:            100px; /* Referenzbreite — JS skaliert per scaleX */
  height:           2px;
  border-radius:    1px;
  background:       var(--c-accent);
  transform-origin: left center;
  opacity:          0;
  pointer-events:   none;
  transition:
    transform 380ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity   250ms ease;
}
.header-nav.has-indicator .nav-link::after { content: none; }


/* =============================================================
   ERLEBNIS-EBENE — scroll-gekoppelte Szenen + Werkzeuge (Okt. 2026)
   Grundregel: Die Grundstile beschreiben den ENDZUSTAND jeder Szene
   (= Standbild ohne JS / bei Reduced Motion). Bewegung kommt erst über
   Klassen aus script.js (.is-fx, .is-paket, .is-swipe …) und über --p
   (Szenenfortschritt 0…1) bzw. --e (geglättet).
   ============================================================= */

:root {
  --fx-amp:     1;                                   /* Bewegungsstärke, Muster-Regler */
  --ease-out:   cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.22, 1.35, 0.36, 1);
  --ease-io:    cubic-bezier(0.65, 0, 0.35, 1);
  --mock-bg:    #1C2840;                             
  --shadow-float:
    0 2px 4px   rgba(20,33,61,.06),
    0 8px 24px  rgba(20,33,61,.14),
    0 28px 64px rgba(20,33,61,.18);
}

/* =============================================================
   VERSPRECHEN — Wort für Wort
   ============================================================= */
.statement-text.is-fx .fx-w {
  opacity: clamp(.16, calc(var(--p, 1) * (var(--n) + 4) - var(--i)), 1);
}





/* =============================================================
   WISCH-REIHEN (nur Handy) — Problem-Punkte, Leistungen, Referenzen
   ============================================================= */
.swipe-dots { display: none; }

@media (max-width: 767px) {
  /* Attribut + Klasse: schlägt die Grid-/Flex-Regeln der jeweiligen
     Komponente (.referenz-projects, .service-list--cols …) unabhängig
     von der Reihenfolge in der Datei. */
  [data-fx-swipe].is-swipe {
    position:               relative;
    display:                flex;
    flex-direction:         row;
    flex-wrap:              nowrap;
    gap:                    var(--s-4);
    overflow-x:             auto;
    overscroll-behavior-x:  contain;
    scroll-snap-type:       x mandatory;
    scrollbar-width:        none;
    margin-inline:          calc(var(--gutter) * -1);
    padding:                var(--s-3) var(--gutter) var(--s-6);
    scroll-padding-inline:  var(--gutter);
    -webkit-overflow-scrolling: touch;
  }
  .is-swipe::-webkit-scrollbar { display: none; }
  .is-swipe:focus-visible {
    outline:        2px solid var(--c-accent);
    outline-offset: -2px;
    border-radius:  var(--r-md);
  }

  /* Einzeleigenschaften (scale/opacity) statt transform: kollidieren
     nicht mit Hover-/Fade-in-Transforms der Karten selbst. */
  .is-swipe > .swipe-item {
    flex:              0 0 84%;
    scroll-snap-align: start;
    scale:             calc(1 - .05 * var(--d, 0) * var(--fx-amp));
    opacity:           calc(1 - .35 * var(--d, 0));
    transform-origin:  left center;
  }

  .swipe-dots {
    display:         flex;
    justify-content: center;
    gap:             2px;
    margin-top:      calc(var(--s-3) * -1);
  }
  .swipe-dot {
    display:         grid;
    place-items:     center;
    width:           28px;
    height:          28px;
    padding:         0;
    border:          0;
    background:      transparent;
    cursor:          pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .swipe-dot::before {
    content:       "";
    width:         7px;
    height:        7px;
    border-radius: 9999px;
    background:    rgba(20, 33, 61, .2);
    transition:    transform 320ms var(--ease-spring), background-color 200ms ease;
  }
  .swipe-dot[aria-current="true"]::before { background: var(--c-navy); transform: scaleX(2.4); }
  .swipe-dot:hover::before  { background: rgba(20, 33, 61, .45); }
  .swipe-dot[aria-current="true"]:hover::before { background: var(--c-navy); }
  .swipe-dot:active::before { transform: scale(.8); }
  .swipe-dot:focus-visible  { outline: 2px solid var(--c-accent); outline-offset: -2px; border-radius: 9999px; }

  /* Problem-Punkte werden in der Reihe zu Karten */
  .problem-points.is-swipe .problem-point {
    padding:       var(--s-6);
    border-top:    0;
    border-radius: var(--r-md);
    background:    var(--c-card);
    box-shadow:    var(--shadow-card);
  }
  .problem-points.is-swipe .problem-point-text { text-wrap: pretty; }

  /* Referenz-Projekte: Karten gleich hoch halten */
  .referenz-projects.is-swipe > .swipe-item { flex-basis: 88%; }
}


/* =============================================================
   SELBSTTEST — Kachel öffnet sich + echter Google-Test
   ============================================================= */
/* Die Kachel wird randlos (Sektionsbreite) und per clip-path zunächst
   exakt auf ihre alte Kartenbreite beschnitten; beim Hineinscrollen
   öffnet sich der Beschnitt bis an die Bildschirmränder. */
.navy-tile.is-open-fx {
  --ot-pad:      var(--s-12);
  max-width:     none;
  width:         var(--ot-w, 100%);
  margin-left:   calc(var(--ot-l, 0px) * -1);
  margin-right:  0;
  padding-inline: calc(var(--ot-l, 0px) + var(--ot-pad));
  border-radius: 0;
  box-shadow:    none;
  clip-path: inset(
    calc((1 - var(--e, 1)) * 28px)
    calc((1 - var(--e, 1)) * var(--ot-l, 0px))
    round calc((1 - var(--e, 1)) * 28px)
  );
}
@media (max-width: 767px) {
  .navy-tile.is-open-fx { --ot-pad: var(--s-6); }
}

.gtest {
  margin-block:  var(--s-8) var(--s-6);
  padding:       var(--s-6);
  max-width:     820px;
  border-radius: var(--r-md);
  background:    rgba(255, 255, 255, .04);
  border:        1px solid rgba(255, 255, 255, .10);
}
.gtest-fields {
  display:               grid;
  grid-template-columns: 1fr 1fr auto;
  gap:                   var(--s-3);
  align-items:           end;
}
.gtest-label {
  display:        block;
  margin-bottom:  var(--s-2);
  font-size:      var(--t-xs);
  font-weight:    700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color:          rgba(243, 240, 234, .6);
}
.gtest-input {
  width:         100%;
  height:        52px;
  padding:       0 var(--s-4);
  border-radius: var(--r-sm);
  border:        1px solid rgba(255, 255, 255, .18);
  background:    rgba(255, 255, 255, .06);
  color:         var(--c-light);
  font-family:   var(--f-body);
  font-size:     16px; /* < 16px zoomt iOS beim Fokus */
  font-weight:   500;
  transition:    border-color 150ms ease, background-color 150ms ease;
}
.gtest-input::placeholder { color: rgba(243, 240, 234, .6); } /* ≈5:1 auf der Kachel */
.gtest-input:hover  { border-color: rgba(255, 255, 255, .34); }
.gtest-input:focus-visible {
  outline:        2px solid var(--c-accent-bright);
  outline-offset: 2px;
  background:     rgba(255, 255, 255, .09);
}
.gtest-submit {
  height:      52px;
  white-space: nowrap;
  display:     inline-flex;
  align-items: center;
  gap:         var(--s-2);
}
.gtest-submit-icon { width: 18px; height: 18px; transition: transform 250ms var(--ease-out); }
.gtest-submit:hover .gtest-submit-icon { transform: translate(2px, -2px); }

.gtest-hint {
  margin-top: var(--s-3);
  font-size:  var(--t-sm);
  color:      rgba(243, 240, 234, .66);
}
.gtest-error {
  margin-top:  var(--s-2);
  font-size:   var(--t-sm);
  font-weight: 600;
  color:       var(--c-accent-light-ondark);
}

.gtest-result {
  margin-top:  var(--s-6);
  padding-top: var(--s-6);
  border-top:  1px solid rgba(255, 255, 255, .12);
}
.gtest-result.is-shown { animation: fx-rise-in 520ms var(--ease-out) both; }
.gtest-question {
  margin-bottom:  var(--s-4);
  font-family:    var(--f-display);
  font-size:      var(--t-xl);
  font-weight:    600;
  letter-spacing: -0.02em;
  color:          var(--c-light);
}
.gtest-answers { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.gtest-answer {
  min-height:    44px;
  padding:       0 var(--s-5);
  border-radius: 9999px;
  border:        1px solid rgba(255, 255, 255, .24);
  background:    transparent;
  color:         rgba(243, 240, 234, .9);
  font-family:   var(--f-body);
  font-size:     var(--t-sm);
  font-weight:   600;
  cursor:        pointer;
  transition:
    background-color 150ms ease, border-color 150ms ease, color 150ms ease,
    transform 200ms var(--ease-out);
}
.gtest-answer:hover  { background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .42); }
.gtest-answer:active { transform: scale(.97); }
.gtest-answer:focus-visible { outline: 2px solid var(--c-accent-bright); outline-offset: 2px; }
.gtest-answer[aria-pressed="true"] {
  background:   var(--c-light);
  border-color: var(--c-light);
  color:        var(--c-navy);
}
.gtest-reply {
  margin-top:     var(--s-5);
  max-width:      46ch;
  font-family:    var(--f-display);
  font-size:      var(--t-xl);
  line-height:    1.45;
  letter-spacing: -0.015em;
  color:          var(--c-light);
  animation:      fx-rise-in 460ms var(--ease-out) both;
}


/* Bestehender Fehler der Live-Seite: .btn-navy auf der Navy-Kachel war
   praktisch unsichtbar (Navy auf Navy). Hier hell wie .btn-light. */
.selbsttest-tile .btn-navy,
.kontakt-hero .btn-navy {
  background:   var(--c-light);
  border-color: var(--c-light);
  color:        var(--c-navy);
}
.selbsttest-tile .btn-navy:hover,
.kontakt-hero .btn-navy:hover {
  background:   #FFFFFF;
  border-color: #FFFFFF;
  box-shadow:   0 4px 16px rgba(0, 0, 0, .28);
}

@media (max-width: 767px) {
  .gtest { padding: var(--s-5); margin-inline: calc(var(--s-2) * -1); }
  .gtest-fields { grid-template-columns: 1fr; }
  .gtest-submit { width: 100%; justify-content: center; }
  .gtest-answers { flex-direction: column; align-items: stretch; }
}


/* =============================================================
   LEISTUNGEN — Auftakt „Gebaut heißt nicht gefunden" + Zeitregler
   ============================================================= */
.section-loesung .umdeutung-lead { max-width: 60ch; }
.paket-headline { margin-top: var(--sec-pad); }

.zeit { margin-top: var(--s-10); }
.zeit-tabs { display: none; }

.zeit-cards {
  display:               grid;
  grid-template-columns: 1fr 1fr;
  gap:                   var(--s-5);
}
.zeit-card {
  padding:       var(--s-6);
  border-radius: var(--r-lg);
  background:    var(--c-card);
  box-shadow:    var(--shadow-card);
}
.zeit-intro {
  max-width:     60ch;
  margin-bottom: var(--s-6);
  font-size:     var(--t-lg);
  line-height:   1.6;
  color:         var(--c-muted);
}
.zeit-card-label {
  margin-bottom:  var(--s-1);
  font-size:      var(--t-xs);
  font-weight:    700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color:          var(--c-muted);
}
.zeit-card--running .zeit-card-label { color: var(--c-accent); }
.zeit-card-sub {
  margin-bottom: var(--s-4);
  font-size:     var(--t-sm);
  color:         var(--c-muted);
}

/* Ereignisliste unter dem Profil: links passiert nichts, rechts kommen
   die Pflege-Einträge dazu (Monate sind ein Beispielverlauf). */
.zp-log { margin-top: var(--s-4); }
.zp-log-title {
  margin-bottom:  var(--s-2);
  font-size:      var(--t-xs);
  font-weight:    700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color:          var(--c-muted);
}
.zp-log-list { list-style: none; min-height: calc(3 * 2.4rem); }
.zp-log-item {
  display:         flex;
  justify-content: space-between;
  align-items:     baseline;
  gap:             var(--s-4);
  padding-block:   var(--s-2);
  border-bottom:   1px solid var(--c-border);
  font-size:       var(--t-sm);
  line-height:     1.4;
}
.zp-log-what { display: inline-flex; align-items: baseline; gap: var(--s-2); }
.zp-log-what::before {
  content:       "";
  flex-shrink:   0;
  width:         8px;
  height:        8px;
  border-radius: 50%;
  translate:     0 -1px;
}
.zp-log-when { flex-shrink: 0; font-size: var(--t-xs); color: var(--c-muted); }
.zp-log--static .zp-log-what { color: var(--c-muted); }
.zp-log--static .zp-log-what::before { background: rgba(26, 26, 26, .22); }
.zp-log--running .zp-log-what { font-weight: 600; color: var(--c-navy); }
.zp-log--running .zp-log-what::before { background: var(--c-accent); }
.zp-log-item.is-new { animation: fx-log-in 420ms var(--ease-out) both; }
@keyframes fx-log-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* Schematisches Google-Profil in der Mockup-Fläche der Mini-Vorschauen */
.zp {
  padding:       var(--s-5);
  border-radius: var(--r-md);
  background:    var(--mock-bg);
  color:         rgba(243, 240, 234, .85);
}
.zeit-card--static .zp { filter: saturate(calc(1 - .85 * var(--age, 0))); }

.zp-head { display: flex; align-items: center; gap: var(--s-3); }
.zp-avatar {
  flex-shrink:   0;
  width:         40px;
  height:        40px;
  border-radius: 50%;
  background:    linear-gradient(135deg, var(--c-accent-light), var(--c-accent));
}
.zp-name {
  font-family:    var(--f-display);
  font-size:      var(--t-base);
  font-weight:    600;
  letter-spacing: -0.01em;
  color:          rgba(243, 240, 234, .95);
}
.zp-sub { font-size: var(--t-xs); color: rgba(243, 240, 234, .5); }

.zp-photos {
  display:               grid;
  grid-template-columns: repeat(5, 1fr);
  gap:                   6px;
  margin-top:            var(--s-4);
}
.zp-photo {
  aspect-ratio:  1;
  border-radius: 6px;
  background:    linear-gradient(135deg, rgba(74, 107, 176, .6), rgba(46, 74, 133, .22));
}
.zeit-card--static .zp-photo { opacity: calc(1 - .6 * var(--age, 0)); }
.zp-photo--new { opacity: 0; scale: .6; }
.zeit-card .zp-photo--new:not(.is-on) { opacity: 0; } /* schlägt das Verblassen der statischen Karte */
.zeit-card--running .zp-photo--new {
  transition: opacity 300ms ease, scale 420ms var(--ease-spring);
}
.zeit-card--running .zp-photo--new.is-on { opacity: 1; scale: 1; }

.zp-facts { display: grid; gap: var(--s-2); margin-top: var(--s-4); }
.zp-fact {
  display:         flex;
  justify-content: space-between;
  align-items:     center;
  gap:             var(--s-3);
  padding-bottom:  var(--s-2);
  border-bottom:   1px solid rgba(255, 255, 255, .07);
  font-size:       var(--t-sm);
}
.zp-fact dt { color: rgba(243, 240, 234, .55); }
.zp-fact dd { font-weight: 600; text-align: right; color: rgba(243, 240, 234, .92); }
.zp-badge {
  display:       inline-block;
  padding:       2px 9px;
  border-radius: 9999px;
  background:    rgba(46, 74, 133, .55);
  color:         var(--c-accent-light-ondark);
  font-size:     var(--t-xs);
}
/* „Veraltet" ohne Signalfarbe: entsättigt + gestrichelt, nicht rot */
.zp-badge.is-stale {
  background: transparent;
  border:     1px dashed rgba(243, 240, 234, .35);
  color:      rgba(243, 240, 234, .6);
}
.zp-dots {
  display:         inline-flex;
  flex-wrap:       wrap;
  justify-content: flex-end;
  gap:             3px;
  max-width:       150px;
}
.zp-dot {
  width:         7px;
  height:        7px;
  border-radius: 50%;
  background:    var(--c-accent-bright);
  animation:     fx-pop 380ms var(--ease-spring) both;
}
@keyframes fx-pop { from { opacity: 0; transform: scale(0); } }

.zp-rank { margin-top: var(--s-4); }
.zp-rank-label { display: block; font-size: var(--t-xs); color: rgba(243, 240, 234, .55); }
.zp-rank-track {
  display:       block;
  height:        6px;
  margin-top:    6px;
  border-radius: 3px;
  overflow:      hidden;
  /* bewusst ohne gefüllte Spur: nur der Balken selbst (kein Dashboard-Look) */
}
.zp-rank-fill {
  display:          block;
  height:           100%;
  border-radius:    3px;
  background:       linear-gradient(90deg, var(--c-accent-light), var(--c-accent-bright));
  transform-origin: left center;
  transform:        scaleX(var(--rank, .84));
  transition:       transform 280ms var(--ease-out);
}

/* Regler */
.zeit-control { max-width: 640px; margin: var(--s-8) auto 0; }
.zeit-control-head {
  display:         flex;
  justify-content: space-between;
  align-items:     baseline;
  gap:             var(--s-4);
  margin-bottom:   var(--s-1);
}
.zeit-label { font-size: var(--t-sm); font-weight: 600; color: var(--c-muted); }
.zeit-output {
  font-family:          var(--f-display);
  font-size:            var(--t-xl);
  font-weight:          600;
  letter-spacing:       -0.02em;
  font-variant-numeric: tabular-nums;
  color:                var(--c-navy);
}
.zeit-range {
  --fill:             0%;
  -webkit-appearance: none;
  appearance:         none;
  display:            block;
  width:              100%;
  height:             44px;
  margin:             0;
  background:         transparent;
  cursor:             pointer;
  touch-action:       pan-y;
}
.zeit-range::-webkit-slider-runnable-track {
  height:        6px;
  border-radius: 3px;
  background:    linear-gradient(90deg, var(--c-navy) 0 var(--fill), rgba(20, 33, 61, .12) var(--fill) 100%);
}
.zeit-range::-moz-range-track    { height: 6px; border-radius: 3px; background: rgba(20, 33, 61, .12); }
.zeit-range::-moz-range-progress { height: 6px; border-radius: 3px; background: var(--c-navy); }
.zeit-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width:         28px;
  height:        28px;
  margin-top:    -11px;
  border-radius: 50%;
  border:        2px solid var(--c-navy);
  background:    var(--c-card);
  box-shadow:    0 2px 8px rgba(20, 33, 61, .25), 0 1px 2px rgba(20, 33, 61, .15);
  transition:    transform 200ms var(--ease-out);
}
.zeit-range::-moz-range-thumb {
  width:         24px;
  height:        24px;
  border-radius: 50%;
  border:        2px solid var(--c-navy);
  background:    var(--c-card);
  box-shadow:    0 2px 8px rgba(20, 33, 61, .25);
  transition:    transform 200ms var(--ease-out);
}
.zeit-range:hover::-webkit-slider-thumb  { transform: scale(1.1); }
.zeit-range:active::-webkit-slider-thumb { transform: scale(.94); }
.zeit-range:hover::-moz-range-thumb      { transform: scale(1.1); }
.zeit-range:active::-moz-range-thumb     { transform: scale(.94); }
.zeit-range:focus-visible { outline: none; }
.zeit-range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--c-bg), 0 0 0 6px var(--c-accent); }
.zeit-range:focus-visible::-moz-range-thumb     { box-shadow: 0 0 0 4px var(--c-bg), 0 0 0 6px var(--c-accent); }
.zeit-scale {
  display:         flex;
  justify-content: space-between;
  font-size:       var(--t-xs);
  color:           var(--c-muted);
}
.zeit-note {
  margin-top: var(--s-4);
  text-align: center;
  font-size:  var(--t-xs);
  color:      var(--c-muted);
}

@media (max-width: 767px) {
  .zeit.is-fx .zeit-tabs {
    display:       flex;
    gap:           4px;
    padding:       4px;
    margin-bottom: var(--s-4);
    border-radius: 9999px;
    background:    rgba(20, 33, 61, .06);
  }
  .zeit-tab {
    flex:          1;
    min-height:    44px;
    border:        0;
    border-radius: 9999px;
    background:    transparent;
    color:         var(--c-muted);
    font-family:   var(--f-body);
    font-size:     var(--t-sm);
    font-weight:   600;
    cursor:        pointer;
    transition:    background-color 200ms ease, color 200ms ease, transform 200ms var(--ease-out);
  }
  .zeit-tab:hover  { color: var(--c-text); }
  .zeit-tab:active { transform: scale(.97); }
  .zeit-tab:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }
  .zeit-tab[aria-pressed="true"] { background: var(--c-card); color: var(--c-navy); box-shadow: var(--shadow-card); }
  .zeit-tab.is-hint { animation: fx-hint 1.2s var(--ease-io) 2; }

  .zeit-cards { grid-template-columns: 1fr; }
  .zeit.is-fx[data-view="static"]  .zeit-card--running,
  .zeit.is-fx[data-view="running"] .zeit-card--static { display: none; }
  .zeit.is-fx .zeit-card-label { display: none; }
  .zeit-card { padding: var(--s-4); }
  .zeit-intro { margin-bottom: var(--s-4); font-size: var(--t-base); }
  .zeit-control { margin-top: var(--s-5); }
}
@keyframes fx-hint {
  0%, 100% { box-shadow: 0 0 0 0 rgba(46, 74, 133, 0); }
  50%      { box-shadow: 0 0 0 4px rgba(46, 74, 133, .28); }
}


/* =============================================================
   LEISTUNGEN — „Drei Teile, ein Paket": Karten fahren zusammen,
   Illustrationen je Karte
   ============================================================= */
@media (min-width: 768px) {
  .service-list.is-paket .service-item:nth-child(1) {
    translate: calc((1 - var(--e, 1)) * -64px * var(--fx-amp)) calc((1 - var(--e, 1)) * 18px);
    rotate:    calc((1 - var(--e, 1)) * -3deg * var(--fx-amp));
  }
  .service-list.is-paket .service-item:nth-child(2) {
    translate: 0 calc((1 - var(--e, 1)) * 44px * var(--fx-amp));
  }
  .service-list.is-paket .service-item:nth-child(3) {
    translate: calc((1 - var(--e, 1)) * 64px * var(--fx-amp)) calc((1 - var(--e, 1)) * 18px);
    rotate:    calc((1 - var(--e, 1)) * 3deg * var(--fx-amp));
  }
  .paket-bracket.is-paket .paket-bracket-line { transform: scaleX(var(--e, 1)); }
  .paket-bracket.is-paket .paket-bracket-line:first-child { transform-origin: left center; }
  .paket-bracket.is-paket .paket-bracket-line:last-child  { transform-origin: right center; }
  .paket-bracket.is-paket .paket-bracket-label { opacity: clamp(0, calc(var(--e, 1) * 4 - 3), 1); }
}


/* =============================================================
   ABLAUF — Uhr in drei Dritteln, ein Drittel je Schritt
   Standbild (ohne .is-fx): Uhr voll, alle Schritte, nur die letzte Szene.
   ============================================================= */
.ablauf-grid {
  display: grid;
  gap:     var(--s-10);
}
@media (min-width: 900px) {
  .ablauf-grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    grid-template-areas:   "clock stage" "steps stage";
    column-gap:            var(--s-16);
    row-gap:               var(--s-8);
    align-items:           center;
  }
  .ablauf-clock  { grid-area: clock; }
  .ablauf-steps  { grid-area: steps; }
  .ablauf-stage  { grid-area: stage; }
}

.ablauf-clock { display: flex; align-items: center; gap: var(--s-6); }
.clock-svg {
  flex-shrink: 0;
  width:       136px;
  height:      136px;
  overflow:    visible;
  filter:      drop-shadow(0 8px 20px rgba(20, 33, 61, .12));
}
.clock-face           { fill: var(--c-card); stroke: rgba(20, 33, 61, .10); stroke-width: 1; }
.clock-sector         { fill: rgba(46, 74, 133, .16); }
.clock-ticks line     { stroke: rgba(20, 33, 61, .22); stroke-width: 1.5; stroke-linecap: round; }
.clock-ticks .is-major { stroke: rgba(20, 33, 61, .55); stroke-width: 2.25; }
.clock-hand,
.clock-run {
  transform-box:    view-box;
  transform-origin: 60px 60px;
}
.clock-hand {
  stroke:           var(--c-navy);
  stroke-width:     3.5;
  stroke-linecap:   round;
}
.clock-pin { fill: var(--c-navy); }

.clock-value {
  font-family:    var(--f-display);
  font-size:      clamp(2rem, 3.4vw, 2.75rem);
  font-weight:    700;
  letter-spacing: -0.035em;
  line-height:    1.05;
  color:          var(--c-navy);
}
.clock-caption {
  margin-top:     var(--s-2);
  font-size:      var(--t-xs);
  font-weight:    700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color:          var(--c-accent);
}

.ablauf-steps { list-style: none; display: grid; gap: var(--s-6); }
.ablauf-step  { display: flex; align-items: flex-start; gap: var(--s-4); }
.ablauf-step .step-title { font-size: var(--t-xl); margin-bottom: var(--s-1); }
.ablauf-step .step-text  { font-size: var(--t-base); line-height: 1.65; }

.ablauf-stage { display: grid; align-items: center; }
.ablauf-stage > .mock { grid-area: 1 / 1; }
.ablauf-scene:not(.is-fx) .mock:not([data-step="2"]) { display: none; }

/* ── Szenen-Mockups ─────────────────────────────────────── */
.mock {
  display:        flex;
  flex-direction: column;
  aspect-ratio:   16 / 10;
  border-radius:  var(--r-lg);
  overflow:       hidden;
  background:     var(--mock-bg);
  box-shadow:     var(--shadow-float);
}
.mock-bar {
  display:       flex;
  align-items:   center;
  gap:           5px;
  padding:       10px 14px;
  background:    rgba(255, 255, 255, .06);
  border-bottom: 1px solid rgba(255, 255, 255, .06);
}
.mock-bar .dot { width: 8px; height: 8px; }
.mock-title { margin-left: 8px; font-size: 11px; color: rgba(243, 240, 234, .55); }
.mock-url {
  flex:          1;
  margin-left:   8px;
  padding:       2px 8px;
  border-radius: 3px;
  background:    rgba(255, 255, 255, .06);
  font-size:     11px;
  color:         rgba(243, 240, 234, .45);
}

/* 1 · Videocall */
.call-tiles {
  flex:                  1;
  display:               grid;
  grid-template-columns: 1fr 1fr;
  gap:                   10px;
  padding:               12px 12px 0;
  min-height:            0;
}
.call-tile {
  position:      relative;
  display:       grid;
  place-items:   center;
  border-radius: 12px;
  overflow:      hidden;
  background:    rgba(255, 255, 255, .05);
}
.call-avatar {
  width:         34%;
  aspect-ratio:  1;
  border-radius: 50%;
  background:    linear-gradient(135deg, var(--c-accent-light), var(--c-accent));
}
.call-avatar--alt { background: linear-gradient(135deg, var(--c-accent-bright), var(--c-accent-light)); }
.call-tile::after {
  content:       "";
  position:      absolute;
  inset:         0;
  border:        2px solid var(--c-accent-bright);
  border-radius: 12px;
  opacity:       0;
}
.mock--call.is-active .call-tile--fritz::after { animation: fx-speak 2.4s ease-in-out infinite; }
.mock--call.is-active .call-tile--you::after   { animation: fx-speak 2.4s ease-in-out 1.2s infinite; }
@keyframes fx-speak { 0%, 100% { opacity: 0; } 30%, 55% { opacity: 1; } }
.call-name {
  position:      absolute;
  left:          8px;
  bottom:        8px;
  padding:       2px 8px;
  border-radius: 9999px;
  background:    rgba(14, 24, 39, .7);
  font-size:     11px;
  font-weight:   600;
  color:         rgba(243, 240, 234, .92);
}
.call-controls {
  display:     flex;
  align-items: center;
  gap:         8px;
  padding:     10px 14px;
}
.call-btn { width: 24px; height: 24px; border-radius: 50%; background: rgba(255, 255, 255, .1); }
.call-btn--end { background: var(--c-negative); }
.call-timer {
  margin-left:          auto;
  font-size:            12px;
  font-weight:          600;
  font-variant-numeric: tabular-nums;
  color:                rgba(243, 240, 234, .75);
}

/* 2 · Entwurf mit Anmerkung und Freigabe */
.draft-page {
  position:       relative;
  flex:           1;
  display:        flex;
  flex-direction: column;
  gap:            8px;
  margin:         12px;
  padding:        16px;
  border-radius:  8px;
  background:     var(--c-bg);
  min-height:     0;
}
.draft-line { display: block; height: 6px; border-radius: 3px; background: rgba(20, 33, 61, .16); }
.draft-line--title { width: 58%; height: 11px; background: var(--c-navy); }
.draft-line--text  { width: 82%; }
.draft-line--short { width: 48%; }
.draft-img {
  flex:          1;
  min-height:    24px;
  border-radius: 6px;
  background:    linear-gradient(135deg, rgba(74, 107, 176, .38), rgba(46, 74, 133, .12));
}
.draft-btn {
  align-self:    flex-start;
  padding:       4px 12px;
  border-radius: 9999px;
  background:    var(--c-navy);
  color:         var(--c-light);
  font-size:     10px;
  font-weight:   600;
}
.draft-pin { position: absolute; top: 30%; right: 16%; }
.draft-pin-dot {
  display:       block;
  width:         14px;
  height:        14px;
  border-radius: 50%;
  background:    var(--c-accent);
  box-shadow:    0 0 0 4px rgba(46, 74, 133, .22);
}
.draft-pin-bubble {
  position:      absolute;
  top:           -6px;
  right:         22px;
  display:       grid;
  gap:           5px;
  width:         92px;
  padding:       8px 10px;
  border-radius: 8px;
  background:    var(--c-card);
  box-shadow:    0 6px 18px rgba(20, 33, 61, .2);
}
.draft-pin-bubble span { display: block; height: 5px; border-radius: 3px; background: rgba(20, 33, 61, .2); }
.draft-pin-bubble span + span { width: 64%; }
.draft-stamp {
  position:      absolute;
  right:         14px;
  bottom:        14px;
  display:       inline-flex;
  align-items:   center;
  gap:           6px;
  padding:       6px 12px;
  border-radius: 9999px;
  background:    var(--c-navy);
  color:         var(--c-light);
  font-size:     12px;
  font-weight:   700;
  box-shadow:    0 8px 20px rgba(20, 33, 61, .3);
  rotate:        -6deg;
}
.draft-stamp svg { width: 14px; height: 14px; }

/* 3 · Live auf dem Handy */
.mock--live {
  background:  transparent;
  box-shadow:  none;
  overflow:    visible;
  display:     grid;
  place-items: center;
}
.phone {
  position:      relative;
  height:        100%;
  aspect-ratio:  9 / 17;
  padding:       7px;
  border-radius: 26px;
  background:    var(--c-navy-deep);
  box-shadow:    var(--shadow-float);
}
.phone-notch {
  position:      absolute;
  top:           12px;
  left:          50%;
  width:         34%;
  height:        5px;
  margin-left:   -17%;
  border-radius: 3px;
  background:    rgba(255, 255, 255, .18);
  z-index:       1;
}
.phone-screen {
  position:       relative;
  height:         100%;
  display:        flex;
  flex-direction: column;
  gap:            6px;
  padding:        30px 12px 12px;
  border-radius:  20px;
  background:     var(--c-bg);
  overflow:       hidden;
}
.live-badge {
  align-self:     flex-start;
  display:        inline-flex;
  align-items:    center;
  gap:            5px;
  padding:        3px 9px;
  border-radius:  9999px;
  background:     var(--c-navy);
  color:          var(--c-light);
  font-size:      9px;
  font-weight:    700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--c-accent-bright); }
.mock--live.is-active .live-dot { animation: fx-blink 1.6s ease-in-out infinite; }
@keyframes fx-blink { 50% { opacity: .25; } }
.phone-name  { margin-top: 4px; font-family: var(--f-display); font-size: 14px; font-weight: 700; letter-spacing: -0.01em; color: var(--c-text); }
.phone-stars { font-size: 11px; letter-spacing: 1px; color: var(--c-accent); }
.phone-open  { font-size: 11px; font-weight: 600; color: var(--c-accent); }
.phone-img {
  display:       block;
  flex:          1;
  min-height:    0;
  margin-top:    4px;
  border-radius: 8px;
  background:    linear-gradient(135deg, rgba(74, 107, 176, .42), rgba(46, 74, 133, .14));
}
.phone-thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.phone-thumbs span {
  aspect-ratio:  1;
  border-radius: 5px;
  background:    linear-gradient(135deg, rgba(74, 107, 176, .3), rgba(46, 74, 133, .1));
}
.phone-line  { display: block; height: 5px; border-radius: 3px; background: rgba(20, 33, 61, .14); }
.phone-line--short { width: 60%; }
.phone-actions { display: flex; gap: 6px; margin-top: auto; }
.phone-pill {
  flex:          1;
  padding:       6px 0;
  border-radius: 9999px;
  background:    rgba(20, 33, 61, .08);
  text-align:    center;
  font-size:     10px;
  font-weight:   600;
  color:         var(--c-navy);
}
.phone-pill--call { background: var(--c-navy); color: var(--c-light); }

/* ── Szene aktiv (gepinnt) ──────────────────────────────── */
.ablauf-scene.is-fx { height: calc(var(--ablauf-len, 3) * 100svh); }
.ablauf-scene.is-fx .ablauf-sticky {
  position:        sticky;
  top:             0;
  height:          100svh;
  display:         flex;
  flex-direction:  column;
  justify-content: center;
  padding-top:     88px; /* Header-Pill */
}
.ablauf-scene.is-fx .headline-display { margin-bottom: var(--s-8); }
.ablauf-scene.is-fx .ablauf-grid { width: 100%; }

/* Der Inhalt muss in die Fensterhöhe passen, sonst wird Schritt 3 unten
   abgeschnitten. Abstände, Überschrift und Uhr richten sich nach der Höhe. */
@media (min-width: 900px) {
  .ablauf-scene.is-fx .ablauf-sticky { padding-top: 84px; padding-bottom: var(--s-6); }
  .ablauf-scene.is-fx .headline-display {
    font-size:     clamp(1.75rem, min(4.8vw, 6.6vh), 3.5rem);
    margin-bottom: clamp(var(--s-3), 3vh, var(--s-8));
  }
  .ablauf-scene.is-fx .ablauf-grid { row-gap: clamp(var(--s-4), 3vh, var(--s-8)); }
  .ablauf-scene.is-fx .clock-svg {
    width:  clamp(84px, 15vh, 136px);
    height: clamp(84px, 15vh, 136px);
  }
  .ablauf-scene.is-fx .ablauf-steps { gap: clamp(var(--s-3), 2.6vh, var(--s-6)); }
}
/* Niedrige Fenster: nur der aktive Schritt zeigt seinen Text */
@media (min-width: 900px) and (max-height: 960px) {
  .ablauf-scene.is-fx .ablauf-step:not(.is-active) .step-text { display: none; }
  .ablauf-scene.is-fx .ablauf-step.is-active .step-text { animation: fx-log-in 420ms var(--ease-out) both; }
}

.ablauf-scene.is-fx .ablauf-step { opacity: .34; transition: opacity 420ms ease; }
.ablauf-scene.is-fx .ablauf-step.is-active { opacity: 1; }
.ablauf-scene.is-fx .step-badge { transition: background-color 300ms ease, color 300ms ease, border-color 300ms ease; }
.ablauf-scene.is-fx .ablauf-step.is-active .step-badge,
.ablauf-scene.is-fx .ablauf-step.is-done .step-badge {
  background:   var(--c-navy);
  border-color: var(--c-navy);
  color:        var(--c-light);
}

.ablauf-scene.is-fx .mock {
  opacity:    0;
  transform:  translateY(calc(16px * var(--fx-amp))) scale(.96);
  transition: opacity 420ms ease, transform 620ms var(--ease-out);
}
.ablauf-scene.is-fx .mock.is-active { opacity: 1; transform: none; }

/* Elemente innerhalb der Szenen kommen nach, sobald die Szene aktiv ist */
.ablauf-scene.is-fx .draft-pin-bubble,
.ablauf-scene.is-fx .draft-stamp,
.ablauf-scene.is-fx .live-badge {
  opacity:    0;
  transform:  scale(.6);
  transition: opacity 260ms ease, transform 520ms var(--ease-spring);
}
.ablauf-scene.is-fx .mock.is-active .draft-pin-bubble { opacity: 1; transform: none; transition-delay: 350ms; }
.ablauf-scene.is-fx .mock.is-active .draft-stamp      { opacity: 1; transform: none; transition-delay: 1000ms; }
.ablauf-scene.is-fx .mock.is-active .live-badge       { opacity: 1; transform: none; transition-delay: 300ms; }

@media (max-width: 899px) {
  .ablauf-scene.is-fx { --ablauf-len: 2.4; }
  /* Zwischen Header-Pill (oben) und Anruf-Leiste (unten) gleich viel Luft.
     Das Szenenbild hat eine Wunschhöhe (300 px) und gibt nach, wenn das
     Fenster knapp ist; bei viel Platz steht alles mittig. */
  .ablauf-scene.is-fx .ablauf-sticky {
    padding-top:     102px; /* Pill endet bei 78 px, +24 */
    padding-bottom:  calc(24px + env(safe-area-inset-bottom));
    justify-content: center;
  }
  @media (max-width: 767px) {
    /* Anruf-Leiste (68 px) + 24 */
    .ablauf-scene.is-fx .ablauf-sticky { padding-bottom: calc(92px + env(safe-area-inset-bottom)); }
  }
  .ablauf-scene.is-fx .headline-display { margin-bottom: 0; font-size: clamp(1.6rem, 7vw, 2rem); }
  .ablauf-scene.is-fx .ablauf-grid {
    flex:           0 1 auto;
    min-height:     0;
    display:        flex;
    flex-direction: column;
    gap:            var(--s-5);
    padding-top:    var(--s-5);
  }
  .ablauf-scene.is-fx .ablauf-clock,
  .ablauf-scene.is-fx .ablauf-steps { flex-shrink: 0; }
  .ablauf-scene.is-fx .ablauf-stage { flex: 0 1 300px; min-height: 0; container-type: size; }
  .ablauf-scene.is-fx .ablauf-clock { gap: var(--s-4); }
  .ablauf-scene.is-fx .clock-svg { width: 76px; height: 76px; }
  .ablauf-scene.is-fx .clock-value { font-size: 1.85rem; }
  /* Mobil: Uhr, Szene, dann nur der aktive Schritt (alle in einer Zelle) */
  .ablauf-scene.is-fx .ablauf-stage { order: 1; }
  .ablauf-scene.is-fx .ablauf-steps { order: 2; display: grid; }
  .ablauf-scene.is-fx .ablauf-step {
    grid-area:  1 / 1;
    align-self: end; /* Abstand zur Leiste bei jedem Schritt gleich */
    opacity:    0;
    transform:  translateY(10px);
    transition: opacity 360ms ease, transform 480ms var(--ease-out);
  }
  .ablauf-scene.is-fx .ablauf-step.is-active { opacity: 1; transform: none; }
  /* Breite statt max-height begrenzen: Seitenverhältnis + Höhendeckel
     blähten die Grid-Spalte über den Bildschirm hinaus auf. */
  .ablauf-scene.is-fx .ablauf-grid { grid-template-columns: minmax(0, 1fr); }
  .ablauf-scene.is-fx .mock { width: min(100%, calc(min(100cqh, 300px) * 1.6)); margin-inline: auto; }
  .ablauf-scene.is-fx .mock--live { width: 100%; height: min(100cqh, 300px); aspect-ratio: auto; }
}



/* Niedrige Handy-Fenster (Browserleisten kosten Höhe): Überschrift, Uhr und
   Abstände kompakter, damit für das Szenenbild genug Höhe bleibt. Wird es
   trotzdem knapp, lässt das Handy-Bild Details weg statt überzulaufen. */
@media (max-width: 899px) and (max-height: 760px) {
  .ablauf-scene.is-fx .headline-display { font-size: clamp(1.4rem, 6.2vw, 1.75rem); }
  .ablauf-scene.is-fx .ablauf-grid { gap: var(--s-3); padding-top: var(--s-4); }
  .ablauf-scene.is-fx .clock-svg { width: 56px; height: 56px; }
  .ablauf-scene.is-fx .clock-value { font-size: 1.5rem; }
}
@media (max-width: 899px) {
  .ablauf-scene.is-fx .phone { min-height: 0; max-height: 100%; }
  @container (max-height: 230px) {
    .ablauf-scene.is-fx .phone-img,
    .ablauf-scene.is-fx .phone-line { display: none; }
  }
  @container (max-height: 170px) {
    .ablauf-scene.is-fx .phone-thumbs,
    .ablauf-scene.is-fx .phone-stars { display: none; }
  }
}

/* =============================================================
   ÜBER MICH — Unterschrift zeichnet sich, Porträt-Parallax
   ============================================================= */
.signatur {
  position:      relative;
  display:       block;
  width:         210px;
  height:        70px;
  margin-bottom: var(--s-3);
}
.signatur-img { display: block; width: 100%; height: 100%; object-fit: contain; object-position: left center; }
.signatur-missing { display: none; }
.signatur.is-missing .signatur-img { display: none; }
.signatur.is-missing { display: none; }
.signatur.is-missing .signatur-missing {
  display:        flex;
  align-items:    center;
  justify-content: center;
  height:         100%;
  border:         1.5px dashed rgba(20, 33, 61, .25);
  border-radius:  var(--r-sm);
  font-size:      var(--t-xs);
  font-weight:    600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color:          var(--c-muted);
}
/* Schreibrichtung: weiche Maskenkante wandert von links nach rechts */
.signatur.is-fx .signatur-img {
  -webkit-mask-image:    linear-gradient(90deg, #000 45%, transparent 55%);
          mask-image:    linear-gradient(90deg, #000 45%, transparent 55%);
  -webkit-mask-size:     280% 100%;
          mask-size:     280% 100%;
  -webkit-mask-repeat:   no-repeat;
          mask-repeat:   no-repeat;
  -webkit-mask-position: 100% 0;
          mask-position: 100% 0;
}
.signatur.is-fx.is-drawn .signatur-img { animation: fx-sign 1.8s var(--ease-io) forwards; }
@keyframes fx-sign {
  to { -webkit-mask-position: 0 0; mask-position: 0 0; }
}

/* Einzeleigenschaften statt transform: verrechnen sich mit dem Foto-Reveal
   (html.js .portrait-wrap.is-visible img { transform: none }), der sonst
   per Spezifität gewinnt. */
.portrait-wrap.is-parallax img {
  translate: 0 calc((var(--p, .5) - .5) * -48px * var(--fx-amp));
  scale:     1.1;
}


/* =============================================================
   REFERENZEN — Vorher/Nachher + Live-Vorschau
   ============================================================= */
.referenz-projects {
  grid-column:           1 / -1;
  display:               grid;
  grid-template-columns: repeat(2, 1fr);
  gap:                   var(--s-5);
}
@media (max-width: 700px) {
  .referenz-projects { grid-template-columns: 1fr; }
}
.ba .referenz-preview-loader,
.live .referenz-preview-loader { z-index: 6; }

.ba > img,
.ba-before-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ba-before { display: none; }

.ba.is-fx {
  touch-action: pan-y;
  cursor:       ew-resize;
  user-select:  none;
  -webkit-user-select: none;
}
.ba.is-fx .ba-before {
  display:    block;
  position:   absolute;
  inset:      0;
  z-index:    1;
  background: var(--mock-bg);
  clip-path:  inset(0 calc(100% - var(--ba, 50%)) 0 0);
}
.ba-missing {
  position:       absolute;
  inset:          10px;
  display:        none;
  place-items:    center;
  padding:        var(--s-4);
  text-align:     center;
  border:         1.5px dashed rgba(243, 240, 234, .28);
  border-radius:  6px;
  font-size:      var(--t-xs);
  font-weight:    600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color:          rgba(243, 240, 234, .6);
}
.ba.is-missing .ba-before-img { display: none; }
.ba.is-missing .ba-missing    { display: grid; right: calc(100% - var(--ba, 50%) + 10px); }

.ba-tag, .ba-handle, .ba-range { display: none; }
.ba.is-fx .ba-tag {
  display:        block;
  position:       absolute;
  top:            10px;
  z-index:        4;
  padding:        3px 9px;
  border-radius:  9999px;
  background:     rgba(14, 24, 39, .72);
  color:          rgba(243, 240, 234, .92);
  font-size:      10px;
  font-weight:    700;
  letter-spacing: .08em;
  text-transform: uppercase;
  pointer-events: none;
}
.ba.is-fx .ba-tag--before { left: 10px; }
.ba.is-fx .ba-tag--after  { right: 10px; }
.ba.is-fx .ba-handle {
  display:        block;
  position:       absolute;
  top:            0;
  bottom:         0;
  left:           var(--ba, 50%);
  z-index:        3;
  width:          2px;
  margin-left:    -1px;
  background:     rgba(255, 255, 255, .92);
  box-shadow:     0 0 12px rgba(0, 0, 0, .35);
  pointer-events: none;
}
.ba-knob {
  position:      absolute;
  top:           50%;
  left:          50%;
  display:       grid;
  place-items:   center;
  width:         40px;
  height:        40px;
  margin:        -20px 0 0 -20px;
  border-radius: 50%;
  background:    var(--c-card);
  color:         var(--c-navy);
  box-shadow:    0 4px 14px rgba(20, 33, 61, .35);
  transition:    transform 220ms var(--ease-out);
}
.ba-knob svg { width: 18px; height: 18px; }
.ba.is-fx:hover .ba-knob     { transform: scale(1.08); }
.ba.is-fx.is-dragging .ba-knob { transform: scale(.94); }
.ba.is-fx .ba-range {
  display:        block;
  position:       absolute;
  inset:          0;
  width:          100%;
  height:         100%;
  margin:         0;
  opacity:        0;
  pointer-events: none;
}
.ba-range:focus-visible ~ .ba-handle .ba-knob {
  box-shadow: 0 0 0 3px var(--c-card), 0 0 0 6px var(--c-accent);
}

/* Live-Vorschau: ganzseitiger Screenshot läuft im Rahmen durch */
.live .live-img { object-position: center top; }
.live.is-fx .live-img {
  position:   absolute;
  top:        0;
  left:       0;
  width:      100%;
  height:     auto;
  animation:  fx-live-scroll 20s var(--ease-io) infinite;
  animation-play-state: paused;
}
.live.is-fx.is-playing .live-img { animation-play-state: running; }
@media (hover: hover) and (pointer: fine) {
  .live.is-fx:hover .live-img { animation-play-state: paused; }
}
@keyframes fx-live-scroll {
  0%, 8%    { transform: translateY(0); }
  48%, 58%  { transform: translateY(calc(-100% + var(--frame-h, 240px))); }
  100%      { transform: translateY(0); }
}


/* =============================================================
   VERGLEICH — Einträge kommen nacheinander, Haken poppen auf
   ============================================================= */
.vs.is-fx .vs-item {
  opacity:    0;
  transform:  translateY(calc(10px * var(--fx-amp)));
  transition: opacity 420ms ease, transform 560ms var(--ease-out);
  transition-delay: calc(var(--i) * 70ms);
}
.vs.is-fx .vs-card--own .vs-item { transition-delay: calc(240ms + var(--i) * 70ms); }
.vs.is-fx .vs-icon {
  transform:  scale(0);
  transition: transform 460ms var(--ease-spring);
  transition-delay: calc(140ms + var(--i) * 70ms);
}
.vs.is-fx .vs-card--own .vs-icon { transition-delay: calc(380ms + var(--i) * 70ms); }
.vs.is-fx.is-in .vs-item { opacity: 1; transform: none; }
.vs.is-fx.is-in .vs-icon { transform: none; }
.vs.is-fx .vs-cta { opacity: 0; transition: opacity 420ms ease 900ms; }
.vs.is-fx.is-in .vs-cta { opacity: 1; }


/* =============================================================
   MOBILE ANRUF-LEISTE
   ============================================================= */
.cta-bar { display: none; }
@media (max-width: 767px) {
  .cta-bar:not([hidden]) {
    position:              fixed;
    left:                  0;
    right:                 0;
    bottom:                0;
    z-index:               90;
    display:               grid;
    grid-template-columns: 1fr 1fr;
    gap:                   8px;
    /* Bündig am unteren Rand und deckend: Safari (iOS) färbt seine Leiste
       dann passend ein, statt die Buttons mit einem hellen Schleier zu
       überdecken. Ausgeblendet ist sie ganz weg (opacity + visibility),
       nicht nur nach unten verschoben, sonst schimmert sie hinter der
       Browser-Leiste durch. */
    padding:               10px 12px calc(10px + env(safe-area-inset-bottom));
    border-radius:         18px 18px 0 0;
    background:            var(--c-navy);
    box-shadow:            0 -8px 24px rgba(20, 33, 61, .18), 0 -1px 4px rgba(20, 33, 61, .12);
    transform:             translate3d(0, 100%, 0);
    opacity:               0;
    visibility:            hidden;
    /* Feste eigene Grafikebene: Safari verschiebt die Leiste beim Scrollen
       dann direkt auf der GPU, statt sie neu zu zeichnen (sonst zieht sie
       bei schnellem Scrollen sichtbar nach). */
    will-change:           transform, opacity;
    backface-visibility:   hidden;
    transition:            transform 420ms var(--ease-out), opacity 260ms ease, visibility 0s linear 420ms;
  }
  .cta-bar.is-shown {
    transform:  translate3d(0, 0, 0);
    opacity:    1;
    visibility: visible;
    transition: transform 460ms var(--ease-out), opacity 200ms ease, visibility 0s;
  }
  .cta-bar-btn {
    display:         flex;
    align-items:     center;
    justify-content: center;
    gap:             8px;
    min-height:      48px;
    border-radius:   12px;
    background:      var(--c-light);
    color:           var(--c-navy);
    font-family:     var(--f-body);
    font-size:       var(--t-base);
    font-weight:     600;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition:      transform 160ms var(--ease-out), background-color 160ms ease;
  }
  .cta-bar-btn svg { width: 18px; height: 18px; }
  .cta-bar-btn:hover  { background: #FFFFFF; }
  .cta-bar-btn:active { transform: scale(.97); }
  .cta-bar-btn:focus-visible { outline: 2px solid var(--c-accent-bright); outline-offset: 2px; }
  .cta-bar-btn--wa { background: transparent; color: var(--c-light); box-shadow: inset 0 0 0 1px rgba(243, 240, 234, .3); }
  .cta-bar-btn--wa:hover { background: rgba(255, 255, 255, .08); }
}

/* Über mich: die Überschrift steht immer in zwei Zeilen („…für Handwerker“ /
   „Websites baue.“). Die Schriftgröße folgt der Spaltenbreite, sonst bricht
   die erste Zeile in der schmalen Zweispalten-Ansicht um. */
.ueber-mich-text { container-type: inline-size; }
.ueber-mich-text .headline-display { font-size: min(var(--t-3xl), 7.7cqw); }
