/* ═══ v5 · global.css — Tokens, Reset, Basis. Wächst nur, wenn ein Abschnitt
   etwas Gemeinsames braucht. Werte = Corporate Identity (ci.md). ═══ */

/* Schriften selbst gehostet (seit 18.10.2026, vorher fonts.googleapis.com — Datenschutz: keine IP an Google).
   Dateien = die woff2 von Google Fonts (Manrope v20, JetBrains Mono v24), nur latin + latin-ext, beide variabel.
   unicode-range wie bei Google: latin-ext lädt der Browser erst, wenn ein Zeichen daraus vorkommt.
   template.html lädt die beiden latin-Dateien per preload vor. */
@font-face {
  font-family: 'Manrope'; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url('/assets/fonts/manrope-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+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Manrope'; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url('/assets/fonts/manrope-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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-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+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-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-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --color-brand-main:     #6D28D9;
  --color-brand-darker:   #5B21B6;
  --color-brand-lighter:  #8B5CF6;
  --color-brand-subtle:   #F5F3FF;
  --color-bg-light:       #FFFFFF;
  --color-bg-card:        #FFFFFF;
  --color-bg-accent:      #FAFAFA;
  --color-bg-accent-2:    #F4F4F5;
  --color-heading:        #09090B;
  --color-body:           #27272A;
  --color-text-muted:     #71717A;
  --color-text-muted-2:   #A1A1AA;
  --color-border:         #E4E4E7;
  --color-border-strong:  #D4D4D8;
  --color-success:        #16A34A;
  --color-off-white:      #FAFAFA;

  --font-main: 'Manrope', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-size-body: 17px;
  --line-height-body: 1.55;

  --max-width: 1280px;
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;
  --radius-pill: 9999px;

  --shadow-sm: 0 1px 2px rgba(9, 9, 11, 0.04);
  --shadow:    0 4px 12px -2px rgba(9, 9, 11, 0.06), 0 2px 4px -1px rgba(9, 9, 11, 0.04);
  --shadow-lg: 0 12px 32px -8px rgba(9, 9, 11, 0.08), 0 4px 12px -2px rgba(9, 9, 11, 0.04);
  --shadow-brand:       0 12px 28px -8px rgba(37, 99, 235, 0.35), 0 6px 14px -4px rgba(109, 40, 217, 0.25);
  --shadow-brand-hover: 0 20px 36px -8px rgba(37, 99, 235, 0.45), 0 10px 20px -4px rgba(109, 40, 217, 0.32);
  --shadow-card-hover:  0 24px 48px -22px rgba(109, 40, 217, 0.28);
  --shadow-chip:        0 10px 22px -12px rgba(37, 99, 235, 0.40), 0 4px 10px -6px rgba(109, 40, 217, 0.28);   /* Chips unter dem Über-uns-Text (03-about, 24.09.2026) */

  --color-star:  #F59E0B;   /* Bewertungssterne (01-hero, 35-anspruch, 60-ref-liste) */
  --color-error: #DC2626;   /* Fehler-Hinweise in Formularen (12-contact, 34-anfrage) */
  --color-error-hell: #F87171;   /* Fehler-Text auf dunklem Grund (34-anfrage im dunklen Kontakt, KONTAKT-5): 6,3 : 1 auf #1B1922 */

  --grad-brand:       linear-gradient(135deg, #2563eb 0%, #6D28D9 100%);
  --grad-brand-hover: linear-gradient(135deg, #1d4ed8 0%, #5B21B6 100%);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --duration-fast: 280ms;
  --duration: 540ms;
  /* Aurora-Bänder des Heros (01-hero), gemeinsam genutzt von 30-seitenkopf und dem Kontakt der Startseite.
     Der Hero selbst trägt dieselben Werte lokal (abgenommen, nicht angefasst). */
  --aurora-verlauf: repeating-linear-gradient(100deg, #3b82f6 10%, #a5b4fc 15%, #93c5fd 20%, #c4b5fd 25%, #60a5fa 30%);
  --aurora-weiss:   repeating-linear-gradient(100deg, #ffffff 0%, #ffffff 7%, transparent 10%, transparent 12%, #ffffff 16%);
}
/* Drift der Aurora: das ::after gleitet genau eine Kachelperiode (wie sk-hero-aurora-shift in 01-hero) */
@keyframes sk-aurora-drift { from { transform: translateX(0); } to { transform: translateX(-66.6667%); } }

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { overflow-x: clip; }
html { -webkit-text-size-adjust: 100%; }
/* Anker-Abstand für die schwebende Nav (80 px wie NAV_ABSTAND in js/smooth.js).
   Greift, wo Lenis nicht selbst versetzt: ohne Lenis und bei „weniger Bewegung“ —
   dort springt der Browser nativ nach Lenis' Sofort-Sprung und landete sonst bei 0.
   Beim sanften Lenis-Scrollen aus: Lenis zieht scroll-padding UND offset ab → 160. */
html { scroll-padding-top: 80px; }
@media (prefers-reduced-motion: no-preference) {
  html.lenis { scroll-padding-top: 0; }
}
body {
  font-family: var(--font-main);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  color: var(--color-body);
  background: var(--color-bg-light);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
h1, h2, h3 { color: var(--color-heading); line-height: 1.05; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }

/* ─── Sprunglink „Zum Inhalt springen“ (template.html) — nur bei Tastatur-Fokus sichtbar ─── */
.sk-sprung {
  position: absolute; left: 16px; top: -80px; z-index: 1000;
  padding: 12px 18px; border-radius: var(--radius-pill);
  background: var(--color-bg-card); color: var(--color-heading);
  font-size: 16px; font-weight: 600; box-shadow: var(--shadow-lg);
}
.sk-sprung:focus { top: 16px; outline: 2px solid var(--color-brand-main); outline-offset: 3px; }
main:focus { outline: none; }

/* ─── Button ─── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: inherit; font-size: 16px; font-weight: 600; letter-spacing: 0.02em;
  padding: 12px 22px; min-height: 44px;
  border: 0; border-radius: var(--radius-pill);
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease);
}
.btn-primary { background: var(--grad-brand); color: #fff; box-shadow: var(--shadow-brand); }
@media (hover: hover) and (pointer: fine) { .btn-primary:hover { background: var(--grad-brand-hover); box-shadow: var(--shadow-brand-hover); transform: translateY(-1px); } }   /* GLOBAL-3: Hover nur mit Maus */
.btn:focus-visible { outline: 2px solid var(--color-brand-main); outline-offset: 3px; }
.btn svg { width: 16px; height: 16px; }

/* Pfeil, der beim Hover durchläuft (zwei gleiche SVGs, ab 08-pricing) */
.btn-arrow { position: relative; display: inline-block; width: 18px; height: 18px; overflow: hidden; flex-shrink: 0; }
.btn-arrow svg { position: absolute; inset: 0; width: 18px; height: 18px; transition: transform 380ms cubic-bezier(0.65, 0, 0.35, 1); }
.btn-arrow svg:nth-child(2) { transform: translateX(-130%); }
@media (hover: hover) and (pointer: fine) {   /* GLOBAL-3: Hover nur mit Maus */
  .btn:hover .btn-arrow svg:nth-child(1) { transform: translateX(130%); }
  .btn:hover .btn-arrow svg:nth-child(2) { transform: translateX(0); }
}
/* Der zweite Button: dieselbe Familie wie der erste, eine Stufe leiser (20.09.2026).
   Vorher zwei Zeilen — grauer Rand, Hover nur Grund- und Randfarbe. Tunahan: „langweilig".
   Der Verlauf kommt als RAND zurück, nicht als Fläche: Technik 1:1 aus .sk-b-preise-karte--hervor
   (zwei Hintergründe, padding-box + border-box), aber als Pseudo-Element, weil sich `background`
   nicht weich überblenden lässt, `opacity` dagegen schon — und das auf der GPU, also gratis im
   Wisch-Klon. `isolation: isolate` hält das z-index: -1 im Button; ohne das rutscht der Verlauf
   im Klon hinter den Grund der Karte.
   Alle Werte sind Token, deshalb stimmt der Button im dunklen Satz ohne eigene Regel. */
.btn-secondary {
  position: relative; isolation: isolate;
  background: var(--color-bg-card);
  color: var(--color-heading);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-sm);
  transition: background-color var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              box-shadow var(--duration-fast) var(--ease),
              transform var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}
.btn-secondary::before {
  content: ''; position: absolute; inset: -1px; z-index: -1;
  border: 1px solid transparent; border-radius: inherit;
  background: linear-gradient(var(--color-bg-card), var(--color-bg-card)) padding-box,
              var(--grad-brand) border-box;
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .btn-secondary:hover { border-color: transparent; color: var(--color-brand-darker); box-shadow: var(--shadow); transform: translateY(-1px); }
  .btn-secondary:hover::before { opacity: 1; }
}
/* Touch (GLOBAL-4, 20.10.2026): eigene Tipp-Rückmeldung statt Browser-Kasten, kein Doppeltipp-Zoom. Solange der Finger liegt,
   gibt der Knopf leicht nach und zeigt die Farben des Maus-Hovers. Desktop unverändert: keine Tipp-Markierung, (hover: none)
   greift dort nicht. Der Hero-Knopf behält sein eigenes :active (hero.css, steht später). Karten- und Fließtext-Links behalten
   den Browser-Kasten bewusst — sonst hätten sie gar keine Rückmeldung. */
a, button, summary, label { touch-action: manipulation; }
.btn, summary { -webkit-tap-highlight-color: transparent; }
@media (hover: none) {
  .btn:active { transform: scale(0.98); }
  .btn-primary:active { background: var(--grad-brand-hover); box-shadow: var(--shadow-brand-hover); }
  .btn-secondary:active { border-color: transparent; color: var(--color-brand-darker); }
  .btn-secondary:active::before { opacity: 1; }
}

/* ─── Badge + Signal-Punkt (ab 08-pricing) ─── */
.badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 5px 11px;
  font-size: 16px; font-weight: 500; line-height: 1.3;
  color: var(--color-brand-darker);
  background: var(--color-brand-subtle);
  border-radius: var(--radius-sm);
}
.badge-neutral { background: var(--color-bg-accent); color: var(--color-text-muted); }
.signal-dot { display: inline-block; width: 8px; height: 8px; flex-shrink: 0; background: var(--color-brand-main); }

/* ─── Dunkles Thema: html.theme-dark setzt wisch.js (08-pricing) ab den Preisen bis zum Seitenende (seit 24.09.2026).
   .sk-wisch-dunkel trägt DIESELBEN Werte für die Klone im Wisch-Overlay, während die Seite noch hell ist
   (eine Quelle — v4 hatte hier eine Handkopie mit „MUSS synchron bleiben"). Werte 1:1 aus v4. ─── */
html.theme-dark,
.sk-wisch-dunkel {
  --color-bg-light:      #0B0A0F;
  --color-bg-accent:     #131218;
  --color-bg-card:       #1B1922;
  --color-heading:       #FAFAF7;
  --color-body:          rgba(250, 250, 247, 0.78);
  --color-text-muted:    rgba(250, 250, 247, 0.55);
  --color-border:        rgba(255, 255, 255, 0.10);
  --color-border-strong: rgba(255, 255, 255, 0.18);
  --color-brand-subtle:  rgba(124, 58, 237, 0.18);
  --color-brand-darker:  #c4b5fd;
  --color-off-white:     #FAFAF7;
}
/* Themenwechsel als Ein-Frame-Sprung (pricing.js setzt die Klasse für zwei Frames):
   Sonst laufen Farbübergänge unterschiedlich schnell, und kurz stünde helle Schrift
   auf noch hellem Grund (in v4 gemessen und so gelöst). */
html.is-theme-snap *, html.is-theme-snap *::before, html.is-theme-snap *::after { transition: none !important; }

/* ─── Lenis 1.3.26: offizielles Begleit-CSS (dist/lenis.css, Klassen setzt Lenis selbst) ─── */
html.lenis, html.lenis body { height: auto; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis [data-lenis-prevent], .lenis [data-lenis-prevent-wheel], .lenis [data-lenis-prevent-touch],
.lenis [data-lenis-prevent-vertical], .lenis [data-lenis-prevent-horizontal] { overscroll-behavior: contain; }
.lenis.lenis-smooth iframe { pointer-events: none; }
.lenis.lenis-autoToggle { transition-property: overflow; transition-duration: 1ms; transition-behavior: allow-discrete; }

/* ─── Inhaltsbreite ─── */
.container { max-width: var(--max-width); margin: 0 auto; padding: 0 48px; }
@media (max-width: 1024px) { .container { padding: 0 32px; } }
@media (max-width: 767px)  { .container { padding: 0 20px; } }

/* ─── Abschnitts-Bausteine (ab 03-about, werden von den folgenden Abschnitten geteilt) ─── */
.eyebrow {
  display: inline-flex; align-items: center; gap: 14px;
  font-family: var(--font-mono); font-size: 16px; font-weight: 500;
  /* 0.04em statt 0.06em: Die weite Sperrung glich früher die 12 px aus. Seit der CI-Regel
     „nie kleiner als 16 px" (18.09.2026) liefe das Label damit unnötig breit. */
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--color-brand-main);
}
.eyebrow::before { content: ''; width: 32px; height: 1px; background: currentColor; }
/* Auf dunklem Grund ist --color-brand-main (#6D28D9) zu dunkel: gemessen 2,80:1 gegen #09090B,
   also unter der Lesbarkeitsstufe 3:1 (19.09.2026, dunkler Kontakt-Abschluss der Unterseiten).
   --color-brand-darker ist im dunklen Satz der helle Markenton — keine neue Farbe, nur ein anderer
   Token. Gilt auch für die Klone im Wisch-Overlay und die dunkle Startseite. */
html.theme-dark .eyebrow,
.sk-wisch-dunkel .eyebrow { color: var(--color-brand-darker); }
.mono-label {
  font-family: var(--font-mono); font-size: 16px; font-weight: 500;
  letter-spacing: 0.04em; text-transform: uppercase;   /* siehe .eyebrow */
  color: var(--color-text-muted);
}
/* Markenname „webtastic.io“ bleibt immer klein, auch in Labels mit Großbuchstaben (ci.md v1.3, Abschnitt Name) */
.marke { text-transform: none; }
.brand-highlight {
  background: var(--grad-brand);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  font-weight: 800;
}
/* Größe = CI-h2 (ci.md: clamp(32, 3.8vw, 56) px) für JEDEN Abschnittstitel, seit 18.10.2026 ohne Sonderwerte je
   Abschnitt (vorher 72 px hier, 64/68/56 px in FAQ, Über uns, Gründer, Team, Anspruch, Kontakt, Textblock).
   Mit 72 px liefen die Startseiten-Titel in der halben Spalte des 50 : 50-Kopfs auf drei, vier Zeilen.
   balance verteilt umbrechende Titel auf gleich lange Zeilen statt ein Wort allein unten. */
.sk-section-title {
  font-size: clamp(32px, 3.8vw, 56px); line-height: 0.98; text-wrap: balance;
  letter-spacing: -0.035em; font-weight: 700;
  color: var(--color-heading);
}
/* Wörter stehen als <span class="word"><span>…</span></span> fertig im HTML.
   Padding schafft Platz für Unterlängen, margin nimmt ihn wieder weg. */
.sk-section-title .word {
  display: inline-block; overflow: hidden;
  padding: 0.14em 0.04em 0.22em; margin: -0.14em -0.04em -0.22em;
  vertical-align: baseline;
}
.sk-section-title .word > span { display: inline-block; }

/* Abschnitts-Kopf: Meta-Zeile + Titel links, Untertitel rechts unten.
   Seit 18.10.2026 eine Regel für die ganze Seite (Tunahan: „mal kein Untertitel und der Titel nicht full width,
   mal Titel + Untertitel und die Spalten nicht 50/50“ — vorher 1,6 : 1):
     · mit Untertitel  → 50 : 50, der Untertitel beginnt auf der Mittelachse (+ halbe Fuge)
     · ohne Untertitel → Titel über die volle Breite
   Dieselbe Mittelachse tragen die zweispaltigen Inhalts-Köpfe (FAQ, Textblock, Über uns, Kontakt). */
.sk-section-head {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: auto auto;
  gap: 24px 64px;
  align-items: end;
  margin-bottom: 80px;
}
.sk-section-meta  { grid-column: 1; grid-row: 1; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 18px; }
.sk-section-head .sk-section-title { grid-column: 1; grid-row: 2; }
.sk-section-head:not(:has(.sk-section-sub)) .sk-section-title { grid-column: 1 / -1; }
.sk-section-sub   { grid-column: 2; grid-row: 2; align-self: end; font-size: 17px; line-height: 1.55; color: var(--color-text-muted); }
.section-num {
  font-family: var(--font-mono); font-size: 16px; font-weight: 500;
  letter-spacing: 0.04em; font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}
@media (max-width: 900px) {
  /* eigene Zeilen definieren — sonst behalten Titel und Sub grid-row:2 und überlagern sich.
     Zwei feste Zeilen (GLOBAL-5, 19.10.2026): Der Untertitel legt sich über grid-row: 3 eine implizite dritte Zeile mit derselben
     16-px-Fuge an. Mit drei festen Zeilen blieb in Köpfen ohne Untertitel eine leere Zeile samt Fuge stehen (16 px zu viel Luft). */
  .sk-section-head { grid-template-columns: 1fr; grid-template-rows: auto auto; gap: 16px; margin-bottom: 48px; align-items: start; }
  .sk-section-sub  { grid-column: 1; grid-row: 3; }
  /* GLOBAL-6 (19.10.2026): dieselbe Lesebreite wie .sk-b (unten) für alle einspaltigen Köpfe — vorher 86–92 Zeichen je Zeile */
  .sk-section-sub  { max-width: 32em; }
}
/* GLOBAL-7 (19.10.2026): Auf Handys ≤ 400 px brach die Meta-Zeile „01 / 07 —— SECHS EIGENSCHAFTEN“ zweizeilig (330 px Bedarf bei
   320 px Platz). Kürzerer Strich, engere Abstände — einheitlich für alle Überzeilen auf kleinen Handys. Die Preise-Meta bleibt dort
   zweizeilig (ohne Textänderung nicht lösbar, Frage an Manuel). */
@media (max-width: 400px) {
  .sk-section-meta { gap: 12px; }
  .eyebrow { gap: 10px; }
  .eyebrow::before { width: 20px; }
}

/* ─── Bausteine der Unterseiten (sections/30–42): gemeinsamer Abschnitts-Rhythmus ───
   .sk-b = Abschnitt mit Standard-Abstand · .sk-b--flaeche = leicht graue Fläche zum Absetzen */
.sk-b { padding: 128px 0; }
.sk-b--flaeche { background: var(--color-bg-accent); }
@media (max-width: 767px) { .sk-b { padding: 80px 0; } }
/* Tablet quer (GLOBAL-12, Variante B, Tablet-Plan Aufgabe 14, 19.10.2026): Auf iPads quer (768–1279 px breit, 521–900 px hoch)
   standen zwischen zwei Abschnitten 240–256 px Leere, rund 40 % der sichtbaren Höhe. Abschnittsabstand 96 statt 120/128 px,
   Startseite und Unterseiten. main > :is(…) (0,1,1) schlägt die 120-px-Regeln der Abschnittsdateien; das Netz padding-bottom: 0
   (unten, ≥ 0,2,0) sowie Seitenkopf, Preise-Bühne und Hero behalten ihre eigenen Polster. (min-height: 521px): Handys quer behalten
   die Werte des Handy-Plans (sonst überstimmte main > .sk-features die 64 px aus FEAT-2). Tablets hoch, iPad Pro quer und der
   Desktop ab 1280 px bleiben unverändert.
   Die Wisch-Klone (div.sk-wisch-lage / div.sk-wischu-lage, 20.10.2026) brauchen denselben Abstand mit derselben Spezifität 0,1,1:
   Sie stehen nicht direkt in main, und mit 120 px lag ihr Inhalt (Ablauf, Kundenstimmen, FAQ) 24 px tiefer als im Original —
   die Kante brach auf iPad quer mitten durch die Zeilen (Sonde tablet/wisch-unterseiten.mjs, WISCH-14 lageVersatz). */
@media (min-width: 768px) and (max-width: 1279px) and (min-height: 521px) and (max-height: 900px) {
  .sk-b { padding: 96px 0; }
  main > :is(.sk-about, .sk-features, .sk-fit, .sk-refs, .sk-process, .sk-testimonials, .sk-faq),
  div:where(.sk-wisch-lage, .sk-wischu-lage) > :is(.sk-about, .sk-features, .sk-fit, .sk-refs, .sk-process, .sk-testimonials, .sk-faq) { padding-block: 96px; }
}

/* Gleiche Fläche direkt hintereinander (weiß → weiß, grau → grau, grau ↔ FAQ): Nur ein Abstand bleibt
   stehen. Sonst stünden 2 × 128 px Leere ohne Flächenwechsel, und zusammengehörige Abschnitte
   (z. B. die Preisgruppen auf /preise/) zerfielen. Gilt für jede Reihenfolge — die Bausteine brauchen keine eigene Regel.
   Der Seitenkopf zählt nicht als Vorgänger (eigener Innenabstand, Aurora).
   Spezifität ≥ 0,2,0: schlägt .sk-b / .sk-faq samt Mobil-Abstand.
   Seit 06.10.2026 sollen sich die Flächen überall abwechseln (Wächter tools/flaechen/pruefen.mjs) — die Regeln bleiben als Netz. */
/* Runde 2b-Nachprüfung: Der VORGÄNGER verliert den unteren Abstand, nicht das Ziel den oberen — sonst landeten
   Sprungmarken (#ki, #vergleich, #preise) mit der Überzeile direkt unter der Nav, andere Ziele 128 px tiefer.
   Ausnahme .sk-b-preise → .sk-b-anfrage: dort regelt 34-anfrage die gewollte Nähe (Preise behalten ihren Abstand).
   Ausnahme → .sk-b-person (19.09.2026): Der Kontakt-Abschluss ist keine Fortsetzung, sondern das Seitenende.
   Auf /referenzen/ (weiß → weiß) klebten die Karten sonst mit nur einem Abstand am Kontakt (Tunahan). */
.sk-b:where(:not(.sk-b--flaeche, .sk-b-kopf)):has(+ .sk-b:not(.sk-b--flaeche, .sk-b-anfrage, .sk-b-person)),
.sk-b--flaeche:has(+ .sk-b--flaeche),
.sk-b--flaeche:has(+ .sk-faq:not(.sk-faq--weiss)),
.sk-faq:not(.sk-faq--weiss):has(+ .sk-b--flaeche) { padding-bottom: 0; }

/* Untertitel im Abschnitts-Kopf: kein einzelnes Wort allein in der letzten Zeile */
.sk-section-sub { text-wrap: pretty; }

/* Zeilenlänge ≤ 70 Zeichen (Vertrag): in em statt ch — ch misst die breite Ziffer 0, in Manrope ergeben 60ch rund
   80 Zeichen. Gemessen: 1 em ≈ 2 Zeichen Fließtext, 32em ≈ 62–68 Zeichen. Wirkt nur, wo der Untertitel unter
   900 px einspaltig über die volle Breite läuft (darüber steht er in der schmaleren rechten Kopf-Spalte).
   Seit 19.10.2026 (GLOBAL-6) gilt dieselbe Grenze für ALLE einspaltigen Köpfe bis 900 px (Regel im ≤ 900-Block oben), nicht nur
   für die Bausteine — sonst hätten zwei Köpfe hintereinander völlig verschiedene Zeilenlängen. */
.sk-b .sk-section-sub { max-width: 32em; }

/* Einmal-Rendern (js/smooth.js, Handy-Plan Aufgabe 3, FEAT-1, 19.10.2026): Unter 1280 px oder mit Touch setzt smooth.js
   nach dem Laden (und vor dem ersten Anker-Tipp, nach dem Drehen) zwei Bilder lang html.sk-cv-voll — alle Abschnitte
   mit content-visibility: auto zeichnen einmal, contain-intrinsic-size: auto merkt sich ihre echten Höhen.
   Neue Abschnitte mit content-visibility: auto hier ergänzen. Am Desktop ab 1280 px mit Maus wird die Klasse nie gesetzt. */
html.sk-cv-voll :is(.sk-trust, .sk-about, .sk-features, .sk-fit, .sk-refs, .sk-process, .sk-testimonials, .sk-faq, .sk-footer) { content-visibility: visible; }

/* ─── EBENE rise: Einblenden beim Reinscrollen (js/rise.js) ───
   Versteckt wird NUR, wenn rise.js die Seite scharf gemacht hat
   (html.is-rise-armed) — ohne JS / bei weniger Bewegung bleibt alles sichtbar.
   Bewegung über die Einzel-Eigenschaft `translate`, NICHT `transform`: Eine
   Animation mit forwards hält ihren Endwert fest und würde sonst jeden
   Hover-transform der Karte (translateY(-2px)) dauerhaft überstimmen. */
html.is-rise-armed[data-layers~="rise"] [data-rise] { opacity: 0; translate: 0 18px; }
html.is-rise-armed[data-layers~="rise"] [data-rise].is-in {
  animation: sk-rise 600ms var(--ease) forwards;
  animation-delay: calc(60ms + var(--rise-i, 0) * 90ms);
}
html.is-rise-armed[data-layers~="rise"] [data-rise] .sk-section-title .word > span { transform: translateY(110%); }
html.is-rise-armed[data-layers~="rise"] [data-rise].is-in .sk-section-title .word > span {
  animation: sk-word-rise 1000ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
  animation-delay: calc(60ms + var(--w, 0) * 70ms);
}
/* Beim schnellen Wischen (js/rise.js, Handy-Übergang 26.10.2026): sofort da, kurze Blende, keine Staffel — sonst steht die Fläche
   beim Schwung leer, im Dunkeln schwarz. rise.js setzt .is-sofort nur auf Touch bzw. unter 1280 px. */
html.is-rise-armed[data-layers~="rise"] [data-rise].is-in.is-sofort { animation-duration: 180ms; animation-delay: 0ms; }
html.is-rise-armed[data-layers~="rise"] [data-rise].is-in.is-sofort .sk-section-title .word > span { animation-duration: 220ms; animation-delay: 0ms; }
@keyframes sk-rise      { from { opacity: 0; translate: 0 18px; } to { opacity: 1; translate: 0 0; } }
@keyframes sk-word-rise { from { transform: translateY(110%); } to { transform: none; } }

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