/* ks-v0-skin v3.0 — duenne Design-Ebene ueber ks-child/theme.json
 *
 * REGEL: Farben, Fonts, Radien, Schatten, Spacing kommen aus theme.json (ks-child).
 * Hier stehen NUR Dinge, die theme.json nicht ausdruecken kann: Marken-Baender (Hero,
 * Funnel), Cinema-Kategorie-Kacheln, Kurs-Card-Politur, Icons. Kein neues !important
 * ausser gegen Fremd-Plugin-CSS (kursflow-booking) — dort ist es unvermeidbar markiert.
 *
 * Die Aliase unten sind nur Kurzschreibweisen auf die theme.json-Presets, KEINE
 * zweite Werte-Quelle. Wert aendern = theme.json aendern.
 */
/* Lokale Space Grotesk Variable Font (DSGVO-konform, 0 externe Google-Requests) */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('assets/fonts/space-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+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url('assets/fonts/space-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;
}

:root {
  --wp--custom--scrim--brand: linear-gradient(to bottom, rgba(10, 10, 102, 0) 0%, rgba(10, 10, 102, 0.4) 50%, rgba(10, 10, 102, 0.92) 100%);
  --wp--custom--scrim--brand-soft: linear-gradient(to bottom, rgba(10, 10, 102, 0) 0%, rgba(10, 10, 102, 0.65) 100%);
  --ks-blue: var(--wp--preset--color--ks-blue, #1510f0);
  --ks-blue-light: var(--wp--preset--color--ks-blue-light, #3a2ee6);
  --ks-blue-dark: var(--wp--preset--color--ks-blue-dark, #0a0a66);
  --ks-orange: var(--wp--preset--color--ks-orange, #F5891F);
  --ks-orange-dark: var(--wp--preset--color--ks-orange-dark, #c05621);
  --ks-yellow: var(--wp--preset--color--ks-yellow, #FFB800);
  --ks-red: var(--wp--preset--color--ks-red, #dc2626);
  --ks-red-text: var(--wp--preset--color--ks-red-text, #991b1b);
  --ks-orange-text: var(--wp--preset--color--ks-orange-text, #c05621);
  --ks-amber-text: var(--wp--preset--color--ks-amber-text, #d97706);
  --ks-bg: var(--wp--preset--color--ks-bg, #ffffff);
  --ks-surface: var(--wp--preset--color--ks-surface, #f8fafc);
  --ks-border: var(--wp--preset--color--ks-border, #e2e8f0);
  --ks-t1: var(--wp--preset--color--ks-text, #0f172a);
  --ks-t2: var(--wp--preset--color--ks-text-2, #475569);
  --ks-t3: var(--wp--preset--color--ks-text-3, #94a3b8);
  --ks-dark: var(--wp--preset--color--ks-dark, #060817);
  --ks-font: var(--wp--preset--font-family--ks-body, 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif);
  --ks-fd: var(--wp--preset--font-family--ks-display, 'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif);
  --r-card: var(--wp--custom--radius--card, 12px);
  --r-hero: var(--wp--custom--radius--hero, 0px);
  --r-btn: var(--wp--custom--radius--btn, 8px);
  --r-pill: var(--wp--custom--radius--pill, 9999px);
  --sh-blue: var(--wp--custom--shadow--blue, 0 4px 14px rgba(21, 16, 240, 0.25));
  --sh-hov: var(--wp--custom--shadow--blue-hover, 0 8px 24px rgba(21, 16, 240, 0.35));
  --hero-blue: var(--wp--preset--gradient--ks-hero-blue, linear-gradient(135deg, #1510f0 0%, #0a0a66 100%));
  --hero-orange: var(--wp--preset--gradient--ks-hero-orange, linear-gradient(135deg, #F5891F 0%, #c05621 100%));
}

/* Startseite und Seiten mit Hero: Standard-Seitentitel raus, der Hero uebernimmt. */
.home .wp-block-post-title,
.home .nv-page-title-wrap,
body:has(.ks-hero) .nv-page-title-wrap,
body:has(.ks-hero) .nv-page-header {
  display: none !important;
}

/* Volle Breite (Hero-/Funnel-Baender).
 *
 * Primaer laeuft das ueber align:full im Block-Template bzw. im Seiteninhalt — WP nimmt
 * .alignfull aus seiner Constrained-Layout-Regel aus. Diese Klasse ist nur die Absicherung
 * fuer Shortcodes, die AUSSERHALB eines alignfull-Wrappers stehen.
 *
 * Der frueher hier stehende 100vw-Trick (left:50% + margin-left:-50vw) war defekt: WPs
 * Constrained-Layout setzt max-width auf die Content-Breite, die der Trick nie aufhob.
 * Ergebnis war ein auf Content-Breite geklemmtes Band, das bei 50% begann und rechts
 * herauslief. Die Variante unten hebt max-width auf und neutralisiert sich selbst, wenn
 * das Elternelement schon volle Breite hat (dann ist 50% == 50vw, Margin also 0). */
.ks-full { width: auto; max-width: none; margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); }

/* ==== HEADER — schwebende Pille (Referenz-Sprache), schlank und integriert ====
 *
 * WICHTIG: sticky gehoert auf das <header>-Element, NICHT auf die innere Gruppe.
 * Ein Sticky-Element bewegt sich nur innerhalb der Box seines Elternelements — die
 * innere Gruppe steckt im 66px hohen <header class="wp-block-template-part">, hatte
 * also null Weg und konnte nie schweben. Der Grosselternteil .wp-site-blocks ist
 * seitenhoch, deshalb funktioniert es dort.
 *
 * Zwei Zustaende wie in der Referenz:
 *   ueber dem Hero-Foto  -> transparent, helle Schrift, keine Kante
 *   nach dem Scrollen    -> weisse Pille mit Blur und weichem Schatten
 * Zustandswechsel per .ks-header-stuck / .ks-header-over-hero aus ks-v0-skin.js.
 * Ohne Hero (Inhaltsseiten) startet die Leiste direkt als Pille, sonst waere helle
 * Schrift auf weissem Grund unsichtbar.
 */
/* Zwei Themes, ein Skin: .wp-block-template-part = Block-Theme (ks-child auf TT5),
   header.header = klassisch (ks-neve-child auf Neve). Beide stehen hier, damit der
   Wechsel und ein eventueller Rueckweg ohne Design-Loch ablaufen. */
header.wp-block-template-part,
header.header {
  /* Ridecake-Kopie: die Bar klebt an der Fensterkante, kein Schweben mit
     Luftstreifen — die Pille war der Kern der Kritik (User 08-20). */
  position: sticky; top: 0; z-index: 100;
  padding-block: .55rem;
  transition: background .28s ease, box-shadow .28s ease, padding .28s ease;
  /* Chrome-exklusives Flackern (User-Befund 08-21): sticky + backdrop-filter
     (blur auf .ks-header darunter) lässt Blink beim Scrollen über wechselndem
     Bildinhalt neu rastern — ein bekannter Chromium-Compositor-Schwachpunkt,
     WebKit (Safari/DuckDuckGo) betraf es nie. Fix: den Header auf eine eigene
     GPU-Kompositions-Ebene heben, damit der Blur nicht bei jedem Scroll-Frame
     neu berechnet wird. Rein technische Stabilisierung, keine optische Änderung. */
  transform: translateZ(0);
  will-change: transform;
}
/* Auf Seiten mit Hero legt sich die Leiste INS Bild (Referenz-Verhalten). Ohne das
   stand sie im Fluss auf hellem Grund und ihre helle Schrift war unsichtbar —
   "Pille erst beim Runterscrollen sichtbar".
 *
 * Der erste Versuch zog die Leiste per negativem margin-bottom nach unten. Das griff,
 * reichte aber nicht: zwischen Leiste und Hero lagen zusaetzlich rund 216px Block-
 * Abstaende aus dem Theme (wp-site-blocks-Gap, main-Gruppe, ausgeblendeter Seitentitel).
 * Diese Summe zu erraten ist zwecklos, weil sie sich mit Theme-Updates aendert.
 *
 * Deshalb umgekehrt und deterministisch: das JS MISST, wo der Hero ohne Eingriff
 * beginnt (--ks-hero-pull), und der Hero wird exakt um diesen Wert nach oben gezogen.
 * Egal woher der Abstand kommt, das Ergebnis ist immer "Hero beginnt bei 0".
 * padding-top haelt den Text dann unter der Leiste frei. */
body.ks-hero-page .ks-hero {
  margin-top: calc(-1 * var(--ks-hero-pull, 0px));
  padding-top: calc(var(--ks-header-h, 76px) + clamp(2.5rem, 6vw, 5rem));
}
body.ks-hero-page .ks-hero--slim { padding-top: calc(var(--ks-header-h, 76px) + clamp(1.6rem, 3.5vw, 2.6rem)); }
.ks-header {
  /* Ridecake-Kopie (User-Entscheid 08-20): KEINE Pille mehr — die Leiste ist eine
     vollbreite Bar, Inhalt in der 1200px-Mitte. Das gab auch dem CTA wieder Raum:
     in der 880px-Pille quoll „Kurs finden" mit acht Nav-Eintraegen ueber den Rand. */
  width: 100%;
  border-radius: 0;
  padding-inline: max(1.2rem, calc(50vw - 620px));
  background: rgba(255, 255, 255, .86);
  -webkit-backdrop-filter: saturate(150%) blur(16px); backdrop-filter: saturate(150%) blur(16px);
  box-shadow: 0 1px 0 rgba(16, 20, 24, .08);
  transition: background .28s ease, box-shadow .28s ease;
  /* Eigene Compositing-Ebene fürs geblurrte Element selbst — dasselbe Motiv wie
     oben am sticky-Elternelement, hier direkt am backdrop-filter-Träger. */
  transform: translateZ(0);
  will-change: backdrop-filter, background;
}
/* Verlauf hinter der Leiste — damit die Schrift auf JEDEM Foto lesbar bleibt.
 *
 * Der Textschatten allein reicht nicht: er hilft auf dunklen Bildstellen und
 * versagt auf hellen. Auf /360-trainings-was-bedeutet-das/ liegt der Kopf ueber
 * einer hellgruenen Unschaerfe, dort war das Menue praktisch unlesbar. Ein
 * Schatten kann das nicht loesen, weil er die Helligkeit des Untergrunds nicht
 * kennt.
 *
 * Der Verlauf schon: er verdunkelt genau den oberen Streifen, in dem die Leiste
 * liegt, und laeuft nach unten aus. Die Anmutung „Marke schwebt frei im Bild"
 * bleibt, weil das Bild darunter sichtbar ist — es ist kein Balken, sondern ein
 * Schleier. Bewusst CSS-only und ohne Bewegung (Direktive).
 *
 * Hoehe = Kopfhoehe + Abstand + Auslauf. Der Wert kommt aus derselben Variablen,
 * die das Skript fuer die Kopfhoehe setzt; aendert sich der Kopf, wandert der
 * Verlauf mit.
 */
.ks-hero::before {
  content: ''; position: absolute; inset: 0 0 auto 0; z-index: 1;
  /* > .ks-hero__foto (z-index: 0) und < Hero-Inhalt (z-index: 1/2). Gleiche z-index wie
     das Bild hiesse: DOM-Reihenfolge entscheidet, und das spaetere <img> deckt den
     Verlauf zu — genau das passierte nach dem <img>-Umbau (Review-Fund 2026-08-20). */
  height: calc(var(--ks-header-h, 76px) + 5rem);
  background: linear-gradient(to bottom,
    rgba(8, 10, 24, .55) 0%,
    rgba(8, 10, 24, .34) 45%,
    rgba(8, 10, 24, 0) 100%);
  pointer-events: none;
}

/* Zustand 1: ueber dem Hero-Foto — die Marke schwebt frei im Bild. */
.ks-header-over-hero:not(.ks-header-stuck) .ks-header {
  background: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__brand,
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__brand a { color: #fff; text-shadow: 0 1px 12px rgba(0, 0, 0, .5); }
/* Volles Weiss statt 90 %: die Navigation ist Bedienung, kein Beiwerk. Bei .9
   auf hellem Foto blieb sie unter der Lesbarkeitsschwelle, obwohl der Verlauf
   half. */
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__nav a { color: #fff; text-shadow: 0 1px 10px rgba(0, 0, 0, .5); }
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__nav a:hover { color: #fff; }
/* Der CTA steht ueber dem Hero blau auf blau und war praktisch unsichtbar —
   auf /kurse/ verschwand "Kurs finden" im Verlauf. Ueber dem Bild deshalb
   umgekehrt: weisse Flaeche, blaue Schrift. Nach dem Scrollen greift wieder die
   Regel darunter und der Knopf ist blau wie ueberall sonst. */
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__cta .wp-block-button__link {
  background: #fff !important; color: var(--ks-blue) !important;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .18);
}
/* Zustand 2: gescrollt — Pille tritt hervor. */
.ks-header-stuck { padding-block: .45rem; }
.ks-header-stuck .ks-header { background: rgba(255, 255, 255, .93); box-shadow: 0 12px 40px rgba(16, 20, 24, .17); }

.ks-header__brand a, .ks-header__brand { font-family: var(--ks-fd); font-weight: 700; font-size: 1.02rem; letter-spacing: -.02em; color: var(--ks-t1); text-decoration: none; white-space: nowrap; transition: color .28s ease; }
/* Brand-Block: Logo + Wortmarke + Tagline. Das Logo behaelt IMMER seine
   Markenfarben (User-Entscheid 08-21, loest die 08-20-Loesung "weiss ueber
   Foto" ab) — Kontrast ueber dem Hero-Foto liefert bereits der dunkle
   Verlaufs-Scrim .ks-hero::before, der genau die Header-Zone abdunkelt. */
.ks-header__brand-link { display: inline-flex; align-items: center; gap: .55rem; }
.ks-header__logo { width: 2.1rem; height: 2.1rem; object-fit: contain; }
.ks-header__brand-wort { display: flex; flex-direction: column; line-height: 1.15; }
.ks-header__brand-tagline { font-size: .6rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--ks-t2); }
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__brand-tagline { color: rgba(255, 255, 255, .88); }
/* Ueber dem dunklen Hero traegt auch die Navigation weisse Schrift —
   dunkelgraue Links auf dem Foto waren kaum lesbar, und der Kontrastwechsel
   beim Stucken las wie Flackern (User-Bug 08-20). */
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__nav a { color: rgba(255, 255, 255, .92); }
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__nav a:hover { color: var(--ks-yellow); }
.ks-header-over-hero:not(.ks-header-stuck) .ks-nav__gutschein > a { color: var(--ks-yellow) !important; }
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__toggle span,
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__toggle span::before,
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__toggle span::after { background: #fff; }
.ks-header__nav a { color: var(--ks-t2); text-decoration: none; font-weight: 600; font-size: .9rem; transition: color .2s ease; }
.ks-header__nav a:hover, .ks-header__nav .current-menu-item > a { color: var(--ks-blue); }
/* min-width nie breiter als der Viewport erlaubt, und die rechten Untermenues nach
   links oeffnen — sonst schiebt sich das rechteste Dropdown ueber den Rand
   (vom Gate gefangen: 31px Ueberlauf, doc 799 bei vw 768). */
.ks-header__nav .wp-block-navigation__submenu-container,
.ks-header__nav .ks-megapanel { border-radius: 14px; border: 1px solid var(--ks-border); box-shadow: 0 16px 44px rgba(16, 20, 24, .16); padding: .35rem; min-width: min(15rem, calc(100vw - 2.5rem)); max-width: calc(100vw - 2.5rem); background: #fff; }
.ks-header__nav .wp-block-navigation__container > .wp-block-navigation-item:nth-last-child(-n+2) > .wp-block-navigation__submenu-container,
.ks-header__nav > ul > li:nth-last-child(-n+2) > .ks-megapanel { left: auto; right: 0; }
.ks-header__nav .wp-block-navigation__submenu-container a,
.ks-header__nav .ks-megapanel a { border-radius: 9px; padding: .5rem .7rem; color: var(--ks-t2) !important; }
.ks-header__nav .wp-block-navigation__submenu-container a:hover,
.ks-header__nav .ks-megapanel a:hover { background: rgba(21, 16, 240, .07); }
/* ==========================================================================
   MEGA-MENUE (Nutzer-Entscheid 2026-08-19: „Ridecakes Mega-Menue OK machen")
   ==========================================================================
   ridecake.com fuehrt 14 Eintraege der obersten Ebene und 42 Links in einem breiten
   Panel — gemessen, nicht geschaetzt. Unsere Direktive verlangte „max. 6 Eintraege",
   und das bleibt fuer die oberste Ebene auch so. Was sich aendert: die zweite Ebene
   erscheint nicht mehr als schmale 15rem-Liste, sondern als Panel ueber die ganze
   Breite der Kopf-Pille, mehrspaltig. Bei acht Kategorien plus Regionen plus Orten
   war die schmale Liste der Grund, warum das Menue trotz weniger Eintraege eng wirkte.

   Anker ist bewusst `.ks-header` (die Pille, position: relative) und NICHT
   `position: fixed`: die Pille schaltet je nach Scrollzustand `backdrop-filter` ein
   und aus, und ein Element mit backdrop-filter wird zum Bezugsrahmen fuer fixed-
   Nachkommen. Ein fixed-Panel waere also ueber dem Hero viewport-breit und nach dem
   Scrollen pillenbreit — dieselbe Regel, zwei Ergebnisse. Genau solche
   Zustandsabhaengigkeiten haben hier schon dreimal Zeit gekostet.

   Die Regeln oben (schmales Dropdown) bleiben fuer Tablet und Mobil gueltig; das hier
   ist eine bewusste Ueberschreibung fuer breite Schirme, keine Dublette.

   Zusaetzlich an echte Maus-Hover-Faehigkeit gebunden (Tablet-Flacker-Fix, s.
   ks-neve-child/style.css): ohne (hover:hover)/(pointer:fine) wuerde ein breites
   Touch-Tablet (Landscape, oft >900px) dieses vollbreite Panel per Hover
   bekommen — genau das Panel, das auf Touch nach der ersten Beruehrung haengen
   bleibt statt zu schliessen. Touch faellt jetzt bei jeder Breite auf den
   Klick-Akkordeon zurueck (ks-neve-child/style.css + ks-neve-header.js). */
/* Der Anker des Panels ist die Pille — dafuer braucht .ks-header position: relative.
   Fehlte es (Review-Fund 2026-08-20), ist der naechste positionierte Vorfahre der
   sticky-<header>: Panel und Hover-Steg liefen dann ueber die volle Viewportbreite.
   Sticky selbst sitzt auf dem aeusseren <header> (s. o., Z. 75), nicht hier — der
   Eingriff bricht das Schweben also nicht. */
.ks-header { position: relative; }
@media (min-width: 900px) and (hover: hover) and (pointer: fine) {
  /* Bezug wechselt vom <li> auf die Pille -> das Panel kann ueber die ganze Breite. */
  .ks-header__nav > ul > li.menu-item-has-children { position: static; }
  .ks-header__nav > ul > li > .ks-megapanel {
    left: 0; right: 0; top: 100%;
    /* Die Luecke zur Pille ist ein transparenter Border-Streifen statt eines top-Offsets:
       der Border gehoert zur Hover-Flaeche der Box, der Zeiger verliert den Hover beim
       Durchqueren also nicht — und es braucht keinen separaten Hover-Steg, der vorher
       unsichtbar ueber der ganzen Pillenbreite lag und Klicks darunter schluckte
       (Review-Fund 2026-08-20). */
    border-top: .7rem solid transparent;
    background-clip: padding-box;   /* Weiss darf den transparenten Streifen nicht fuellen */
    /* Vollbreites Panel (ridecake-Mega-Menue, User-Entscheid 08-20): weisser Streifen
       ueber die ganze Viewportbreite, Inhalt in der 1200px-Mitte. Radius 0, weil eine
       volle Breite keine Ecken hat. */
    margin-inline: calc(50% - 50vw);
    border-radius: 0;
    min-width: 0; max-width: none; width: auto;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    gap: .15rem .8rem;
    padding: 1.4rem max(1.2rem, calc(50vw - 600px));
    box-shadow: 0 28px 64px rgba(16, 20, 24, .22);
  }
  /* Die Rechts-Ausrichtung der letzten beiden Eintraege ist jetzt gegenstandslos —
     das Panel nutzt ohnehin die volle Breite. Ohne diese Ruecknahme bliebe
     `left: auto` stehen und das Panel schrumpfte auf die Inhaltsbreite. */
  .ks-header__nav > ul > li:nth-last-child(-n+2) > .ks-megapanel { left: 0; right: 0; }
  /* Im breiten Panel tragen die Links die Flaeche — in der schmalen Liste war ein
     zurueckhaltendes Grau richtig, hier wirkt es unentschlossen. `!important` nur,
     weil die Basisregel oben es selbst so setzt (Neve-Erbe). */
  .ks-header__nav > ul > li > .ks-megapanel > li > a {
    display: block; padding: .6rem .8rem; font-size: .95rem; line-height: 1.3;
    color: var(--ks-t1) !important; font-weight: 600;
  }
  .ks-header__nav > ul > li > .ks-megapanel > li > a:hover { color: var(--ks-blue) !important; }
}

/* CTA sitzt bundig am rechten Pillenrand und bildet mit ihr eine Form (Referenz). */
.ks-header__cta { margin-right: -.35rem; }
.ks-header__cta .wp-block-button__link {
  padding: .72em 1.3em !important; font-size: .875rem; white-space: nowrap;
  border-radius: var(--wp--custom--radius--chip) !important; box-shadow: none;
}
@media (max-width: 860px), (hover: none), (pointer: coarse) {
  .ks-header .ks-header__cta, .ks-header .ks-header__cta.is-layout-flex { display: none; }
} /* mobil/touch traegt der Hero-CTA */

/* Mobiles Mega-Menue kompakter (User-Befund 08-21): das Theme zeigt alle vier
   Gruppen mit allen 28 Unterpunkten samt Kurzbeschreibung permanent ausgeklappt
   uebereinander — ein Bildschirm voller Text, kein Ueberblick. Jetzt ein
   Akkordeon: Gruppen starten eingeklappt, ein Tap auf den Gruppentitel oeffnet
   genau eine (Skin-JS unten in ks-neve-header.js), Beschreibungstexte bleiben
   auch geoeffnet weg — auf dem schmalen Screen ist der Linktitel genug.
   Zusaetzlich schliesst das den Luecke zwischen Pille und Panel (Theme setzte
   `top: calc(100% + 0.5rem)`; der 0.5rem-Spalt liess das Hero-Foto samt der
   gelben Eyebrow-Zeile durchscheinen, wirkte wie eine Ueberlappung mit dem
   Panel-Rand). Bedingung erweitert (Tablet-Flacker-Fix): gilt fuer jedes
   Touch-Geraet, unabhaengig von der Breite — nicht nur unter 860px, s.
   ks-neve-child/style.css fuer die Begruendung. */
@media (max-width: 860px), (hover: none), (pointer: coarse) {
  .ks-header__nav { top: 100%; }
  .ks-header__nav .ks-megapanel { display: none; }
  .ks-header__nav li.is-expanded > .ks-megapanel { display: block; }
  @media (min-width: 600px) {
    .ks-header__nav li.is-expanded > .ks-megapanel {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
      gap: 0.2rem 1rem;
    }
  }
  .ks-megapanel__text { display: none; }
  .ks-header__nav li.menu-item-has-children > a {
    position: relative; padding-right: 1.8rem;
  }
  .ks-header__nav li.menu-item-has-children > a::after {
    content: ''; position: absolute; right: .2rem; top: 50%;
    width: .5rem; height: .5rem;
    border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: translateY(-65%) rotate(45deg);
    transition: transform .2s ease;
  }
  .ks-header__nav li.is-expanded > a::after { transform: translateY(-35%) rotate(-135deg); }
}

/* ==========================================================================
   NAV-ZUSAETZE
   ==========================================================================
   „Start" ist nur im Mobil-Drawer sinnvoll — auf breiten Schirmen traegt das Logo
   die Heimkehr (Skizze des Users: Logo, Tagline, ← Hauptseite, Gruppen). Den Drawer
   selbst (Umschalter + .ks-header__nav.is-open) liefert das Theme ks-neve-child. */
.ks-nav__start { display: none; }
.ks-nav__gutschein > a { color: var(--ks-blue) !important; font-weight: 700; }
.ks-nav__konto > a {
  display: inline-flex;
  align-items: center;
  font-weight: 700;
  color: var(--ks-t1) !important;
}
.ks-nav__konto > a:hover {
  color: var(--ks-blue) !important;
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-nav__konto > a {
  color: rgba(255, 255, 255, .95) !important;
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-nav__konto > a:hover {
  color: var(--ks-yellow) !important;
}
.ks-header__nav .ks-megapanel__highlight > a {
  border-left: 3px solid var(--ks-blue) !important;
  background: rgba(21, 16, 240, .05) !important;
  border-radius: 9px;
  font-weight: 700 !important;
}
.ks-header__nav .ks-megapanel__highlight > a:hover {
  background: rgba(21, 16, 240, .1) !important;
}
@media (max-width: 860px), (hover: none), (pointer: coarse) {
  .ks-nav__start { display: block; }
  .ks-header__nav .ks-nav__konto {
    margin-top: .6rem;
    padding-top: .6rem;
    border-top: 1px solid var(--ks-border, rgba(0, 0, 0, .08));
  }
}

/* ==== FOOTER ==== */
.ks-footer__brand a, .ks-footer__brand { font-family: var(--ks-fd); font-weight: 700; color: #fff; text-decoration: none; }
.ks-footer, .ks-footer p { color: #c7ccd6; }
.ks-footer__nav a { color: #c7ccd6; text-decoration: none; font-weight: 600; font-size: .9rem; }
.ks-footer__nav a:hover { color: #fff; }
.ks-footer__rule { border: 0; height: 2px; opacity: 1; }

/* ==== MARKEN-AKZENTE: kosten Kante, nicht Flaeche ====
   Direktive §5 — Marke wirkt ueber Kanten, Preis, CTA und einen Scrim, nicht ueber
   grosse Volltonflaechen, die ein Foto haetten tragen koennen. */
.ks-band-rule { height: 3px; border: 0; background: var(--hero-blue); margin: 0; }
.kf-card { border-top: 3px solid var(--kat, transparent); }
.kf-card__kat { display: inline-block; font-size: .66rem; font-weight: 800; text-transform: uppercase; letter-spacing: .07em; color: var(--kat, var(--ks-blue)); }

/* Karten-Titel bleiben laut Spec §4 System-Font (Space Grotesk nur Display). */
.kf-card__title, .kf-course__title { font-family: var(--ks-font); font-weight: 800; letter-spacing: -.02em; color: var(--ks-t1); }

/* Icons */
.ks-ico { width: 22px; height: 22px; display: inline-block; vertical-align: middle; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.ks-ico--sm { width: 15px; height: 15px; }
.ks-ico--lg { width: 26px; height: 26px; }

.ks-eyebrow { display: inline-block; font-weight: 800; font-size: 11px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--ks-blue); background: rgba(21, 16, 240, .09); padding: .4em .85em; border-radius: var(--wp--custom--radius--chip); }

/* Buttons: eigene Klassen. .wp-element-button/.wp-block-button__link kommen aus
   theme.json (elements.button) und brauchen hier nichts mehr.
   .kf-btn-book gehoert kursflow-booking -> !important unvermeidbar. */
.ks-btn { display: inline-flex; align-items: center; justify-content: center; min-height: 56px; gap: .5em; background: var(--ks-blue); color: #fff; border: 0; border-radius: var(--r-btn); padding: .8em 1.5em; font-family: var(--ks-font); font-weight: 800; text-decoration: none; transition: transform .15s, box-shadow .15s, background .15s; cursor: pointer; box-shadow: var(--wp--custom--shadow--btn); }
.ks-btn:hover { background: var(--ks-blue-dark); transform: translateY(-2px); box-shadow: var(--sh-hov); }
.ks-btn--ghost { background: transparent; color: var(--ks-blue); box-shadow: inset 0 0 0 2px var(--ks-blue); }
.kf-btn-book { display: inline-flex; align-items: center; justify-content: center; min-height: 56px; gap: .5em; background: var(--ks-blue) !important; color: #fff !important; border: 0 !important; border-radius: var(--r-btn) !important; padding: .8em 1.5em !important; font-weight: 800 !important; text-decoration: none; box-shadow: var(--wp--custom--shadow--btn); transition: transform .15s, box-shadow .15s, background .15s; }
.kf-btn-book:hover { background: var(--ks-blue-dark) !important; transform: translateY(-2px); box-shadow: var(--sh-hov); }

/* [kfp_gutschein]-Trigger-Button (gutschein-kaufen-Seite): erbt .kf-btn-book,
   sitzt aber als eigenstaendiges Element direkt im Content-Flow (kein Card-Footer
   mit eigenem Layout wie bei .kf-btn-book auf den Kurskarten) -> hier zentrieren
   und vom nachfolgenden Block abstand geben. width:max-content statt display:flex
   allein, sonst wuerde der Button auf volle Content-Breite gezogen und margin:auto
   liefe ins Leere. !important noetig aus demselben Grund wie bei .kf-btn-book oben:
   kursflow-booking/assets/kf-modal.css laedt NACH diesem Stylesheet und setzt
   .kf-btn-book (display:inline-flex, margin) erneut — bei gleicher Spezifitaet
   gewinnt sonst die spaeter geladene Fremd-Regel. */
.kf-gc-trigger-btn { display: flex !important; width: max-content !important; margin: 32px auto 48px !important; }

/* Einzeltraining & WooCommerce Single-Page Buttons & Info-Box (Brand-Icons & CI) */
.ks-events-info-box {
  background: #f8fafc;
  border: 1.5px solid #e2e8f0;
  border-radius: var(--wp--custom--radius--card, 12px);
  padding: 16px 20px;
  margin: 20px 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.ks-events-info-box p {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  color: var(--ks-slate, #334155);
  line-height: 1.4;
}
.ks-events-info-box .ks-info-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: rgba(21, 16, 240, 0.08);
  color: var(--ks-blue, #1510f0);
  flex-shrink: 0;
}
.ks-events-info-box .ks-info-icon svg {
  width: 18px;
  height: 18px;
  stroke-width: 1.9;
}
.ks-events-info-box strong {
  color: var(--ks-navy, #0a0a66);
  font-weight: 700;
}

.ks-ic-booking-btn {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  background: var(--ks-blue, #1510f0) !important;
  color: #fff !important;
  border: 0 !important;
  border-radius: var(--r-btn, 12px) !important;
  padding: 0.8em 1.6em !important;
  font-weight: 800 !important;
  font-size: 15px !important;
  text-decoration: none !important;
  box-shadow: var(--wp--custom--shadow--btn, 0 4px 14px rgba(21, 16, 240, 0.25));
  transition: transform .15s, box-shadow .15s, background .15s;
}
.ks-ic-booking-btn:hover {
  background: var(--ks-blue-dark, #0c098c) !important;
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(21, 16, 240, 0.35);
}
.ks-ic-whatsapp-btn {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0.6em 1.2em;
  background: #25d366 !important;
  color: #fff !important;
  border-radius: var(--r-btn, 10px) !important;
  font-weight: 700 !important;
  font-size: 14px !important;
  text-decoration: none !important;
  transition: transform .15s, background .15s, box-shadow .15s;
  box-shadow: 0 2px 8px rgba(37, 211, 102, 0.2);
}
.ks-ic-whatsapp-btn:hover {
  background: #1eb956 !important;
  color: #fff !important;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(37, 211, 102, 0.3);
}
.ks-ic-kontakt-hinweis {
  font-size: 13px;
  color: #64748b;
  margin: 12px 0 6px;
}

/* ==== HERO — Marken-Band ALS Scrim ueber dem Foto ====
 *
 * Loesung fuer den Konflikt "Marken-Baender erhalten, ohne die tragende Dominanz der
 * Fotos zu schwaechen": das blaue Band verschwindet nicht, es wandert vom Untergrund
 * auf das Foto. Zwei Ebenen, oberste zuerst:
 *   1. Marken-Scrim (blau, unten dicht, oben transparent) — traegt Marke + Textlesbarkeit
 *   2. das Foto, gesetzt ueber --ks-hero-photo
 * Ohne Foto faellt Ebene 2 auf den Marken-Verlauf zurueck — dann sieht es aus wie bisher.
 * So bleibt die Seite mit UND ohne Bildmaterial stimmig, und Marke ist in beiden Faellen da.
 *
 * Foto setzen:  <section class="ks-hero" style="--ks-hero-photo:url(...)">
 */
.ks-hero {
  --ks-hero-fallback: var(--hero-blue);
  background-color: var(--ks-blue-dark);
  background-image: var(--wp--custom--scrim--brand, linear-gradient(to bottom, rgba(10, 10, 102, 0) 0%, rgba(10, 10, 102, 0.4) 50%, rgba(10, 10, 102, 0.92) 100%)), var(--ks-hero-photo, var(--ks-hero-fallback));
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
  padding: clamp(3.5rem, 8vw, 6.5rem) 1.2rem clamp(3rem, 6vw, 5rem);
  text-align: center; position: relative; overflow: hidden;
}
/* Foto vorhanden -> mehr Bildflaeche zeigen: Text nach unten, Hoehe rauf. */
.ks-hero:not(.ks-hero--slim) { min-height: min(78vh, 720px); display: flex; align-items: flex-end; justify-content: center; }
.ks-hero--slim { padding: clamp(2.4rem, 5vw, 3.6rem) 1.2rem; }
/* Schmale Variante MIT eigenem Motiv (Kategorie-Archive): etwas mehr Hoehe, sonst
   bleibt vom Foto nur ein Streifen hinter der Schrift und die Kategorien sehen
   weiter aus wie Kopien voneinander. Bewusst deutlich flacher als der
   Startseiten-Hero — das Archiv soll zur Liste fuehren, nicht selbst wirken. */
.ks-hero--slim.ks-hero--foto {
  min-height: min(38vh, 340px);
  display: flex; align-items: flex-end; justify-content: center;
  padding-bottom: clamp(1.6rem, 3vw, 2.4rem);
}
.ks-hero__inner { max-width: 900px; margin: 0 auto; position: relative; z-index: 1; }
.ks-hero .ks-eyebrow { background: rgba(255, 255, 255, .16); color: #fff; }
/* Display gross und LEICHT (Direktive §6: Gewicht 500, nicht 800 — Wirkung ueber
   Groesse statt Strichstaerke, wie in der Referenz gemessen). */
.ks-hero h1 { font-family: var(--ks-fd); font-size: clamp(3.5rem, 9.5vw, 8.75rem); font-weight: 500; letter-spacing: -.04em; margin: .5rem 0 .4rem; color: #fff; line-height: .98; text-wrap: balance; }
.ks-hero--slim h1 { font-size: clamp(2.25rem, 5.5vw, 4rem); }
/* .hl bleibt als Haken im Markup, aber ohne gelbe Unterstreichung und ohne nowrap
   (das erzwang eine Zeile, die auf 390px abgeschnitten wurde). */
.ks-hero h1 .hl { white-space: normal; }
.ks-hero__sub { font-size: clamp(1.02rem, 2.3vw, 1.3rem); color: rgba(255, 255, 255, .88); max-width: 640px; margin: .5rem auto 1.7rem; line-height: 1.55; }
.ks-hero__cta { display: flex; gap: .7rem; justify-content: center; flex-wrap: wrap; }
.ks-hero .ks-btn { background: #fff; color: var(--ks-blue-dark); box-shadow: 0 8px 22px rgba(0, 0, 0, .28); }
.ks-hero .ks-btn:hover { background: var(--ks-yellow); color: #1a1a1a; }
.ks-hero .ks-btn--ghost { background: transparent; color: #fff; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .65); }
.ks-hero__trust { margin-top: 1.5rem; display: flex; gap: 1.3rem; justify-content: center; flex-wrap: wrap; font-size: .85rem; font-weight: 600; color: rgba(255, 255, 255, .85); }
.ks-hero__trust span { display: inline-flex; align-items: center; gap: .4rem; }

/* Sections */
/* Ridecake-Treue: keine Karten-Hintergruende mehr, dafuer JEDE Sektion mit einer satten
   Flaechenfarbe (Ridecake alterniert #E4E7EB / #6A7883 durchgaengig, nie weisser Leerraum
   hinter den "nackten" Foto-Karten). Eigene Marken-Palette statt fremder Hexcodes:
   hell = ks-border, dunkel = ks-blue-dark, CTA = ks-blue. */
.ks-sec { padding: clamp(2.6rem, 5vw, 4.2rem) 1.2rem; background: var(--ks-border); }
.ks-sec--alt { background: var(--ks-blue); }
.ks-kursrail-sec { background: var(--ks-blue-dark); }
/* Editorialer Sektionskopf: Titel links, Einstiegstext rechts — statt
   zentriertem Einzeiler (User 08-20: „schmale Spalte, besser layouten"). */
.ks-sec__head {
	max-width: 1200px;
	margin: 0 auto 2rem;
	text-align: left;
	display: grid;
	grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
	gap: 1.5rem 2.5rem;
	align-items: end;
}
.ks-sec__head h2 { font-family: var(--ks-fd); font-size: clamp(1.5rem, 3.4vw, 2.2rem); font-weight: 800; letter-spacing: -.03em; margin: .4rem 0 0; }
.ks-sec__head p { color: var(--ks-t2); margin: 0; }
@media (max-width: 700px) {
	.ks-sec__head { grid-template-columns: 1fr; }
}

/* ==== CINEMA-KATEGORIEN (bestehende Design-Sprache aus prod) ==== */
.ks-kat { max-width: 1100px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
/* Ridecake-Treue: keine Schatten/Rundung auf der Karte selbst — nackte Flaeche, die
   ganze Definition kommt vom Foto + Scrim (fuer Textlesbarkeit noetig) + Sektionsfarbe. */
.ks-kat__tile { position: relative; height: 300px; border-radius: 0; overflow: hidden; display: flex; flex-direction: column; justify-content: flex-end; color: #fff; text-decoration: none; transition: transform .4s cubic-bezier(.25, .46, .45, .94); }
/* Kachel-Untergrund: Foto wenn vorhanden (--kat-photo), sonst Kategorie-Verlauf.
   Dasselbe Prinzip wie beim Hero — Marke ueber dem Bild, nicht anstelle des Bildes. */
.ks-kat__bg { position: absolute; inset: 0; background-image: var(--kat-photo, var(--kat-grad, var(--hero-blue))); background-size: cover; background-position: center; z-index: 0; transition: transform .6s cubic-bezier(.25, .46, .45, .94); }
.ks-kat__tile:hover { transform: translateY(-6px) scale(1.02); }
.ks-kat__tile:hover .ks-kat__bg { transform: scale(1.08); }
/* Overlay ist der MARKEN-Scrim, nicht neutrales Schwarz: so traegt das Bild die Marke. */
.ks-kat__ov { position: absolute; inset: 0; background-image: var(--wp--custom--scrim--brand-soft); z-index: 1; }
.ks-kat__accent { position: absolute; top: 0; left: 0; right: 0; height: 4px; background: var(--kat, var(--ks-blue)); z-index: 3; }
.ks-kat__icobadge { position: absolute; top: 16px; left: 16px; width: 46px; height: 46px; border-radius: 13px; display: flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .16); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, .25); z-index: 3; color: #fff; }
.ks-kat__body { position: relative; z-index: 2; padding: 1.2rem 1.3rem; }
.ks-kat__name { display: block; font-family: var(--ks-fd); font-weight: 800; font-size: 1.2rem; letter-spacing: -.02em; }
.ks-kat__meta { color: rgba(255, 255, 255, .82); font-size: .85rem; font-weight: 600; }
.ks-kat__arrow { position: absolute; right: 1.1rem; bottom: 1.2rem; color: #fff; z-index: 3; transition: transform .2s; }
.ks-kat__tile:hover .ks-kat__arrow { transform: translateX(4px); }

/* Assessment-Banner nach dem Kategorie-Grid (User-Fund 08-21 ×2: eine Kachel
   IM Grid — egal welche Farbe/Rahmen — wurde zweimal als "zu aehnlich zur
   Kategorie-Kachel" zurueckgewiesen). Jetzt bewusst ein ANDERES Format statt
   nur anderer Optik: vollbreiter horizontaler Streifen AUSSERHALB von
   `.ks-kat`, eigene Zeilen-Anordnung (Icon | Text | CTA) statt Kachel-Raster. */
.ks-assessment-banner, .ks-hinweis-banner {
  display: flex; align-items: center; gap: 1.2rem;
  max-width: 1100px; margin: 1.4rem auto 0;
  border-radius: 18px;
  padding: 1.3rem 1.6rem;
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease;
}
.ks-assessment-banner { background: linear-gradient(100deg, var(--ks-yellow, #FFB800), #F5891F); box-shadow: 0 10px 30px rgba(245, 137, 31, .25); }
.ks-assessment-banner:hover { transform: translateY(-2px); box-shadow: 0 14px 38px rgba(245, 137, 31, .35); }
/* Zweitverwertung des Assessment-Banner-Bausteins (User-Fund 08-21: Legacy-
   "Private Gruppentrainings"-Block auf mehreren Kursseiten) — blauer statt
   gelber Ton, damit er nicht wie eine zweite Assessment-CTA wirkt. */
.ks-hinweis-banner { background: linear-gradient(100deg, var(--ks-blue), var(--ks-blue-dark)); box-shadow: 0 10px 30px rgba(21, 16, 240, .22); color: #fff; }
.ks-hinweis-banner:hover { transform: translateY(-2px); box-shadow: 0 14px 38px rgba(21, 16, 240, .3); }
.ks-assessment-banner__ico, .ks-hinweis-banner__ico {
  flex: 0 0 auto; width: 52px; height: 52px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(10, 14, 38, .16); color: #141414;
}
.ks-hinweis-banner__ico { background: rgba(255, 255, 255, .18); color: #fff; }
.ks-assessment-banner__text, .ks-hinweis-banner__text { flex: 1 1 auto; display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.ks-assessment-banner__text strong, .ks-hinweis-banner__text strong { font-family: var(--ks-fd); font-size: 1.1rem; font-weight: 800; }
.ks-assessment-banner__text strong { color: #141414; }
.ks-hinweis-banner__text strong { color: #fff; }
.ks-assessment-banner__text span, .ks-hinweis-banner__text span { font-size: .88rem; }
.ks-assessment-banner__text span { color: rgba(20, 20, 20, .75); }
.ks-hinweis-banner__text span { color: rgba(255, 255, 255, .82); }
.ks-assessment-banner__cta, .ks-hinweis-banner__cta {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: .5rem;
  font-weight: 700; font-size: .88rem;
  padding: .75rem 1.2rem; border-radius: 100px; white-space: nowrap;
}
.ks-assessment-banner__cta { background: #141414; color: #fff; }
.ks-hinweis-banner__cta { background: #fff; color: var(--ks-blue-dark); }
@media (max-width: 700px) {
  .ks-assessment-banner, .ks-hinweis-banner { flex-wrap: wrap; }
  .ks-assessment-banner__cta, .ks-hinweis-banner__cta { width: 100%; justify-content: center; }
}

/* Helle Banner-Variante mit dunkler Schrift */
.ks-hinweis-banner--light {
  background: #f4f6fb !important;
  border: 1px solid #d0d7e8 !important;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.05) !important;
  color: #111827 !important;
}
.ks-hinweis-banner--light:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(21, 16, 240, 0.1) !important;
}
.ks-hinweis-banner--light .ks-hinweis-banner__ico {
  background: rgba(21, 16, 240, 0.1) !important;
  color: var(--ks-blue) !important;
}
.ks-hinweis-banner--light .ks-hinweis-banner__text strong {
  color: #111827 !important;
}
.ks-hinweis-banner--light .ks-hinweis-banner__text span {
  color: #374151 !important;
}
.ks-hinweis-banner--light .ks-hinweis-banner__cta {
  background: var(--ks-blue) !important;
  color: #ffffff !important;
}
.ks-hinweis-banner--light .ks-hinweis-banner__cta:hover {
  background: var(--ks-blue-dark) !important;
}

/* Amber/Orange Banner-Variante */
.ks-hinweis-banner--amber {
  background: linear-gradient(100deg, var(--ks-yellow, #FFB800), #F5891F) !important;
  box-shadow: 0 10px 30px rgba(245, 137, 31, .25) !important;
  color: #141414 !important;
}
.ks-hinweis-banner--amber .ks-hinweis-banner__ico {
  background: rgba(10, 14, 38, .16) !important;
  color: #141414 !important;
}
.ks-hinweis-banner--amber .ks-hinweis-banner__text strong {
  color: #141414 !important;
}
.ks-hinweis-banner--amber .ks-hinweis-banner__text span {
  color: rgba(20, 20, 20, .85) !important;
}
.ks-hinweis-banner--amber .ks-hinweis-banner__cta {
  background: #141414 !important;
  color: #fff !important;
}


/* ==== PAKET-HIGHLIGHT (Homepage-Teaser "Pfad 1 — Fahrtechnik & Schräglage") ====
 * Sitzt zwischen der Kategorien-Sektion (.ks-sec, Flaeche --ks-border) und
 * [ks_konzept] (Flaeche --ks-bg) — dritter, heller Farbton (--ks-surface/Weiss)
 * fuer sichtbare Abgrenzung, ohne das Gate-Budget an dunklen Baendern
 * (LIMITS.darkSections) anzutasten.
 *
 * .kf-paket* kommt UNGESTYLT aus dem kursflow-booking-Plugin (roh <h3>/<p>/<ul>,
 * s. assets/kf-*.css dort) — [ks_paket_highlight] laesst das Markup unveraendert
 * (Preisdaten bleiben aus einer Quelle) und stylt nur um: die Kursliste wird per
 * CSS-Counter zu einer nummerierten 1→2→3-Schritt-Reihe (deckt die "In 3 Schritten"-
 * Headline visuell), ohne die drei Kursnamen ein zweites Mal im Markup zu pflegen.
 */
.ks-paket-highlight { background: var(--ks-surface); }
.ks-paket-highlight__grid {
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1.5rem;
  align-items: stretch;
}
.ks-paket-card {
  background: var(--ks-bg, #FAFBFC);
  border: 1px solid var(--ks-border);
  border-radius: var(--r-card);
  padding: clamp(1.5rem, 3vw, 2.2rem);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: center;
  box-shadow: 0 4px 16px rgba(0,0,0,0.03);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.ks-paket-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(21, 16, 240, 0.08);
  border-color: var(--ks-blue-light);
}
.ks-paket-highlight .kf-paket {
  width: 100%;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.ks-btn--full {
  width: 100%;
  margin-top: 1rem;
}
.ks-paket-highlight .kf-paket__name {
  display: block; font-family: var(--ks-fd); font-weight: 700; font-size: 1.15rem;
  letter-spacing: -.01em; color: var(--ks-t1); margin: 0 0 0.75rem; min-height: 2.8rem;
}
.ks-paket-highlight .kf-paket__preis {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center;
  gap: .6rem; margin: 0 0 1.25rem;
}
.ks-paket-highlight .kf-paket__preis strong {
  font-family: var(--ks-fd); font-weight: 700; font-size: clamp(1.9rem, 4vw, 2.5rem);
  color: var(--ks-blue);
}
/* --ks-t3 (#8A9199) faellt gegen --ks-bg auf ~3.1:1 Kontrast — unter der
 * Gate-Grenze von 4.5:1 (LIMITS.contrast, scripts/design-gate.mjs). --ks-t2
 * ist dieselbe "gedaempfte Text"-Rolle wie bei .ks-sec__head p, erreicht
 * hier aber ~6.1:1 und ist damit sicher. */
.ks-paket-highlight .kf-paket__streich { color: var(--ks-t2); text-decoration: line-through; font-size: .95rem; }
.ks-paket-highlight .kf-paket__ersparnis {
  display: inline-block; background: rgba(255, 184, 0, .16); color: var(--ks-amber-text);
  border: 1px solid rgba(255, 184, 0, .5); border-radius: var(--r-pill);
  padding: .28em .8em; font-weight: 800; font-size: .78rem; text-transform: uppercase; letter-spacing: .03em;
}
/* Immer vertikal gestapelt (nicht responsive auf horizontal umgeschaltet):
 * eine Zeile pro Schritt haelt bei jeder Panel-Breite (max-width 880px) bei
 * drei Kursnamen inkl. Preis nicht verlaesslich in einer Reihe — der erste
 * Versuch (flex-wrap: wrap, horizontal) brach bei ~1440px in eine schiefe
 * 1+2-Zeilenaufteilung um. Vertikal ist robust bei jeder Breite UND passt
 * lesbar zur "In 3 Schritten"-Headline (Reihenfolge von oben nach unten). */
.ks-paket-highlight .kf-paket__kurse {
  list-style: none; margin: 0 auto; padding: 0; counter-reset: ks-paket-schritt;
  display: flex; flex-direction: column; gap: .9rem;
  max-width: 420px; text-align: left;
}
.ks-paket-highlight .kf-paket__kurse li {
  counter-increment: ks-paket-schritt;
  display: flex; align-items: center; gap: .8rem;
  font-weight: 700; font-size: .95rem; color: var(--ks-t1);
}
.ks-paket-highlight .kf-paket__kurse li::before {
  content: counter(ks-paket-schritt);
  flex: 0 0 auto; width: 1.8rem; height: 1.8rem; border-radius: 50%;
  background: var(--ks-blue); color: #fff; font-family: var(--ks-fd); font-weight: 700; font-size: .85rem;
  display: flex; align-items: center; justify-content: center;
}
.ks-paket-highlight .kf-paket__kurs-preis { color: var(--ks-t2); font-weight: 500; font-size: .82rem; margin-left: auto; padding-left: .6rem; white-space: nowrap; }
.ks-paket-highlight .kf-paket__blocked { color: var(--ks-red-text); font-weight: 600; }

/* ==== KURS-CARDS (bild-betont, blaue Schatten) ==== */
.kf-kurse--grid, .kf-geo-grid { max-width: 1100px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 20px; }
.kf-card, .kf-geo-card { background: var(--ks-surface); border: 1px solid var(--ks-border); border-radius: var(--r-card); box-shadow: var(--sh-blue); overflow: hidden; transition: transform .25s, box-shadow .25s, border-color .25s; animation: ksFadeUp .45s ease both; }
.kf-card:hover, .kf-geo-card:hover { transform: translateY(-5px); box-shadow: var(--sh-hov); border-color: var(--ks-blue-light); }
.kf-card__img-wrap { overflow: hidden; height: 190px; }
.kf-card__img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s; }
.kf-card:hover .kf-card__img { transform: scale(1.06); }
.kf-card__body { padding: 16px 18px 0; }
.kf-card__footer { padding: 12px 18px 18px; }
.kf-card__badge { display: inline-block; background: rgba(21, 16, 240, .08); color: var(--ks-blue); border-radius: var(--wp--custom--radius--chip); padding: .24em .72em; font-weight: 800; font-size: .66rem; text-transform: uppercase; letter-spacing: .06em; }
.kf-card__price, .kf-geo-card__price { font-weight: 800; color: var(--ks-t1); font-size: 1.05rem; }
.kf-card__rating, .kf-geo-card__rating { color: var(--ks-yellow); font-weight: 800; }
.kf-card__spots, .kf-geo-card__spots { display: inline-block; background: rgba(255, 184, 0, .14); color: var(--ks-amber-text); border: 1px solid rgba(255, 184, 0, .45); border-radius: var(--r-pill); padding: .18em .6em; font-weight: 800; font-size: .72rem; }
.kf-sold-out, .kf-card__sold-out, .kf-geo-card__sold-out { display: inline-block; background: rgba(229, 62, 62, .1); color: var(--ks-red-text); border: 1px solid rgba(229, 62, 62, .4); border-radius: var(--r-pill); padding: .18em .6em; font-weight: 800; font-size: .72rem; }
@keyframes ksFadeUp { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* Cross-Funnel: Box/Hintergrund/Ueberschrift jetzt weiter unten definiert (Ridecake-
   Flaechenfarbe auf .ks-sec--alt) — hier bleiben nur Button- und Layout-Regeln, die
   dort nicht dupliziert sind. */
.ks-funnel .ks-btn { background: #fff; color: var(--ks-blue); }
.ks-funnel .ks-btn--ghost { background: transparent; color: #fff; box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .7); }
.ks-funnel__row { display: flex; gap: .7rem; justify-content: center; flex-wrap: wrap; }

/* Kurs-Detail */
.kf-course__meta-item strong { color: var(--ks-t2); text-transform: uppercase; letter-spacing: .06em; font-size: .72rem; font-weight: 800; }
.kf-course__hero-img { border-radius: var(--r-card); }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .kf-card:hover, .ks-kat__tile:hover { transform: none !important; }
}

/* ==== BEITRAGS-KARTEN ====
   Referenz-Sprache: das Foto traegt, Chrome ist minimal — 4:3, Radius 0 (Ridecake-
   Wechsel 2026-08-17, war vorher 12px), kein Rahmen, kein farbiger Schatten.
   Text darunter kurz: Kategorie, Titel, Datum.
   Kein Auszug-Absatz (Direktive §6: Wortbudget). */
.ks-beitraege { padding-block: clamp(2.4rem, 5vw, 4rem); }
.ks-post-grid { max-width: 1100px; margin: 0 auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1.5rem; }
.ks-post-rail { max-width: 1100px; margin: 0 auto; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(260px, 30%); gap: 1.25rem; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; padding-bottom: .5rem; }
.ks-post-rail::-webkit-scrollbar { display: none; }
.ks-post-rail > .ks-post { scroll-snap-align: start; }

/* min-width: 0 ist hier Pflicht, nicht Kosmetik: Flex- und Grid-Items haben
   min-width:auto, also mindestens ihre Inhaltsbreite. Die Beitragsbilder sind 1024px
   breit -> die Karte konnte nicht schrumpfen und sprengte bei 390px das Layout um
   653px (vom Gate gefangen). */
.ks-post { display: flex; flex-direction: column; gap: .75rem; min-width: 0; text-decoration: none; color: inherit; }
.ks-post__body, .ks-post__media { min-width: 0; }
.ks-post__title, .ks-post__kat { overflow-wrap: anywhere; }
.ks-post__media { display: block; aspect-ratio: 4 / 3; overflow: hidden; border-radius: 0; background: linear-gradient(155deg, #e7e9f5, #d9dcef); }
.ks-post__media img { width: 100%; max-width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s cubic-bezier(.25, .46, .45, .94); }
.ks-post:hover .ks-post__media img { transform: scale(1.045); }
.ks-post__body { display: flex; flex-direction: column; gap: .3rem; }
/* War Gelb (var(--ks-yellow)), weil die Karte damals eine dunkle Box (#0e1332) war und
   Blau darauf nur 2.04:1 schaffte. Seit dem Ridecake-Wechsel 2026-08-17 hat .ks-post
   keine eigene Kartenfarbe mehr — die Sektion (.ks-beitraege, erbt .ks-sec) ist jetzt
   hell (--ks-border), deshalb wieder Marken-Blau statt Gelb. */
.ks-post__kat { font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; color: var(--ks-blue); }
.ks-post__title { font-family: var(--ks-font); font-weight: 800; font-size: 1.02rem; line-height: 1.3; letter-spacing: -.01em; color: var(--ks-t1); }
.ks-post:hover .ks-post__title { color: var(--ks-blue); }
/* t3 (#8A9199) kam auf #FAFBFC nur auf 3.08:1 — Gate-Befund, echter Verstoss. */
.ks-post__meta { font-size: .8rem; font-weight: 500; color: var(--ks-t2); }

.ks-beitraege__alle { text-align: center; margin: 1.8rem 0 0; }
.ks-link-mehr { display: inline-flex; align-items: center; gap: .45em; font-weight: 800; font-size: .92rem; color: var(--ks-blue); text-decoration: none; }
.ks-link-mehr:hover { text-decoration: underline; }

/* Paginierung des Beitrags-Archivs */
.ks-pager { display: flex; gap: .4rem; justify-content: center; flex-wrap: wrap; margin: 2.2rem 0 0; }
.ks-pager .page-numbers { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; padding: 0 .6em; border-radius: 10px; border: 1px solid var(--ks-border); background: var(--ks-surface); color: var(--ks-t2); font-weight: 700; font-size: .9rem; text-decoration: none; }
.ks-pager .page-numbers:hover { border-color: var(--ks-blue); color: var(--ks-blue); }
.ks-pager .page-numbers.current { background: var(--ks-blue); border-color: var(--ks-blue); color: #fff; }

/* ==========================================================================
   HERO-KOMPOSITIONEN in Referenz-Richtung (v0 "Evasion")
   Der Unterschied zum Standard-WP-Muster liegt nicht in den Farben, sondern in
   der Komposition: Text UNTEN und LINKS statt zentriert, Display riesig und
   LEICHT, am Bildrand angeschnitten, kein Eyebrow-Chip, kein Trust-Band, EIN CTA.
   ========================================================================== */
.ks-visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Gemeinsame Basis der Foto-Heroes: Bild traegt, Scrim nur unten. */
/* Spezifitaet: .ks-hero:not(.ks-hero--slim) weiter oben ist (0,2,0) und hat die
   Ausrichtung hier ueberschrieben — der Kicker landete in der Mitte statt oben.
   Deshalb hier bewusst zweiklassig selektiert und alignment explizit gesetzt. */
.ks-hero.ks-hero--wort, .ks-hero.ks-hero--claim {
  position: relative; display: flex; flex-direction: column;
  align-items: stretch; justify-content: space-between;
  min-height: min(88vh, 820px); overflow: hidden; text-align: left;
  padding: calc(var(--ks-header-h, 76px) + 1.2rem) clamp(1.1rem, 4vw, 3.2rem) clamp(1.4rem, 3vw, 2.4rem);
  background-color: var(--ks-blue-dark);
  background-size: cover, cover; background-position: center, center;
}
/* Variante A braucht kaum Scrim: das Wort ist riesig und weiss, es liest sich auch
   ueber Bildmitte. Der starke brand-soft-Scrim deckte die Strasse zu — genau das
   Motiv, das die Seite verkauft. Nur ein schmaler Fuss zur Lesbarkeit. */
.ks-hero.ks-hero--wort {
  background-image: linear-gradient(to top, rgba(10, 10, 102, .58) 0%, rgba(10, 10, 102, .12) 34%, rgba(10, 10, 102, 0) 62%), var(--ks-hero-photo, var(--hero-blue));
}
/* Variante B traegt Text im Block -> etwas mehr Deckung, aber gerichtet von unten.
   Die background-image-Zeile ist hier ENTFERNT, nicht weiter unten ueberschrieben:
   dieselbe Datei hatte den Verlauf zweimal fuer denselben Selektor deklariert, und
   genau daran ist am 2026-08-17 schon der Funnel-Fix gescheitert (die unbenutzte
   Alt-Deklaration weiter oben gewann). Der Scrim steht jetzt einmal, als ::after. */
.ks-hero.ks-hero--claim {
  justify-content: flex-end;
}
.ks-hero__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.ks-hero__kicker { display: block; font-size: clamp(.7rem, 1.5vw, .82rem); font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: rgba(255, 255, 255, .82); text-shadow: 0 1px 10px rgba(0, 0, 0, .45); }
.ks-hero__link { display: inline-flex; align-items: center; gap: .4em; color: #fff; font-weight: 700; font-size: .88rem; text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, .45); padding-bottom: .15em; }
.ks-hero__link:hover { border-color: #fff; }

/* --- Variante A: Markenwort riesig, unten angeschnitten --- */
.ks-hero__wortzeile {
  font-family: var(--ks-fd); font-weight: 500; color: #fff;
  font-size: clamp(3rem, 14.5vw, 14rem); line-height: .84;
  letter-spacing: -.045em; white-space: nowrap;
  /* Absichtlich unten angeschnitten — wie das Wort in der Referenz, das der
     Bildrand kappt. Ohne den Anschnitt wirkt es wie ein normaler Titel. */
  margin-bottom: -.1em; user-select: none;
}

/* --- Header Brand Typography --- */
.ks-header__brand-link { text-decoration: none; color: inherit; display: inline-flex; align-items: center; }
.ks-header__brand-text { font-family: var(--ks-fd); font-weight: 700; font-size: 1.2rem; letter-spacing: -0.02em; color: var(--ks-t1, #101418); transition: color .28s ease; }
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__brand-text { color: #ffffff; text-shadow: 0 1px 12px rgba(0, 0, 0, .5); }

/* ==========================================================================
   KURSKARTEN MODERN & PLASTISCH (Card Elevation & Ambient Image Presentation)
   ==========================================================================
   Reaktivierung eigenständiger Kurskarten mit Schlagschatten, Border und
   Abständen, damit Karten auf weißem Hintergrund klar unterscheidbar sind.
   Bilder werden mit weichem Ambient-Blur im Hintergrund vollformatig (100%
   des Motivs sichtbar) dargestellt. */
.kf-grid {
  gap: 32px !important;
}
.kf-karte {
  background: #ffffff !important;
  border: 1px solid #e2e8f0 !important;
  border-radius: 16px !important;
  box-shadow: 0 4px 20px -2px rgba(16, 24, 40, 0.08), 0 2px 6px -1px rgba(16, 24, 40, 0.04) !important;
  padding: 0 0 20px 0 !important;
  overflow: hidden !important;
  display: flex !important;
  flex-direction: column !important;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.2s ease !important;
}
.kf-karte:hover {
  transform: translateY(-4px) !important;
  box-shadow: 0 16px 32px -4px rgba(21, 16, 240, 0.14), 0 4px 12px -2px rgba(16, 24, 40, 0.06) !important;
  border-color: rgba(21, 16, 240, 0.3) !important;
}
.kf-karte-bild-link {
  margin: 0 !important;
  border-radius: 0 !important;
  display: block !important;
}
.kf-karte-bild {
  position: relative !important;
  height: 240px !important;
  background: #0f172a !important;
  overflow: hidden !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  margin: 0 !important;
}
.kf-karte-bild__blur {
  position: absolute !important;
  inset: -40px !important;
  width: calc(100% + 80px) !important;
  height: calc(100% + 80px) !important;
  object-fit: cover !important;
  filter: blur(26px) brightness(0.65) saturate(1.2) !important;
  transform: scale(1.2) !important;
  pointer-events: none !important;
  z-index: 1 !important;
}
.kf-karte-bild img.kf-karte-bild__img,
.kf-karte-bild > img:not(.kf-karte-bild__blur) {
  position: relative !important;
  z-index: 2 !important;
  width: 100% !important;
  height: 100% !important;
  object-fit: contain !important;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.3)) !important;
  transition: transform 0.35s ease !important;
}
.kf-karte-bild-link:hover img.kf-karte-bild__img,
.kf-karte-bild-link:hover .kf-karte-bild > img:not(.kf-karte-bild__blur) {
  transform: scale(1.03) !important;
}
.kf-karte-top, .kf-karte h3, .kf-karte-teaser, .kf-karte-beschreibung, .kf-karte-meta, .kf-meta-liste, .kf-karte-footer {
  padding-left: 20px !important;
  padding-right: 20px !important;
}
.kf-karte-top { margin-top: 16px !important; }
.kf-karte-footer { margin-top: auto !important; }

@media (max-width: 640px) {
  .kf-grid { gap: 20px !important; }
  .kf-karte { padding: 0 0 16px 0 !important; }
  .kf-karte-bild { height: 200px !important; }
  .kf-karte-top, .kf-karte h3, .kf-karte-teaser, .kf-karte-beschreibung, .kf-karte-meta, .kf-meta-liste, .kf-karte-footer {
    padding-left: 16px !important;
    padding-right: 16px !important;
  }
}

/* Nackte Karten brauchen eine Flaeche hinter sich — sonst ist genau der weisse
   Leerraum wieder da, den der Ridecake-Entscheid ausschliesst. Auf der Startseite
   tragen das die `.ks-sec`-Sektionen; die Archivseiten (`/kurse/`, Kategorien) haben
   keine und standen nach dem Nacktmachen auf reinem Weiss (gemessen: body #fff).
   Farbe an die Kursliste, nicht an den body: der Kopfbereich der Archivseite traegt
   sein eigenes Foto. */
body.post-type-archive-kf_course .kf-grid,
body.tax-kf_category .kf-grid {
  background: var(--ks-border);
  /* Auf dem Band faellt das Plugin-Grau --kf-text2 (#6b7280) unter 4,5:1 — das
     design:gate maß 3,90:1. Unser Sekundaer-Token --ks-t2 (#5A6169) liegt bei
     5,0:1 und haelt den Abstand zum dunklen Titel (--ks-text). */
  --kf-text2: var(--ks-t2);
  /* Ueber die volle Breite, damit es ein Band ist und kein Kasten. Dieselbe Technik
     wie bei der Kurs-Rail auf der Startseite. */
  margin-inline: calc(50% - 50vw);
  padding: clamp(1.6rem, 4vw, 2.8rem) max(1.2rem, calc(50vw - 620px));
  box-sizing: border-box;
}
/* Der Filterbereich sitzt direkt darueber und wuerde sonst als weisser Streifen
   dazwischen stehen. Klasse ist `kf-filter-panel` — live im Markup nachgesehen; ein
   zuerst geschriebenes `.kf-filter` gibt es auf der Seite gar nicht und die Regel
   waere stumm ins Leere gelaufen. */
body.post-type-archive-kf_course .kf-filter-panel,
body.tax-kf_category .kf-filter-panel {
  background: var(--ks-border);
  /* Dasselbe Kontrastproblem wie beim Grid: Labels und Chips nutzen --kf-text2. */
  --kf-text2: var(--ks-t2);
  margin-inline: calc(50% - 50vw);
  padding-inline: max(1.2rem, calc(50vw - 620px));
  padding-block: clamp(1rem, 2.5vw, 1.6rem);
  box-sizing: border-box;
}

/* ==========================================================================
   COOKIE-BANNER (WPConsent)
   ==========================================================================
   Der Banner lebt im Shadow DOM, deshalb kommen wir nur ueber zwei Wege an ihn:
   CSS-Variablen (die erben in den Shadow-Baum hinein) und ::part(). Die Variablen
   setzt das Plugin INLINE auf #wpconsent-root — inline gewinnt gegen Stylesheet,
   ausser das Stylesheet ist !important. Deshalb steht es hier, und nur hier.

   Farben: das Plugin lieferte ein fremdes Dunkelblau (#04194e) und ein fremdes Gelb
   (#ffcd2a). Beides sieht aus wie unsere Marke, ist es aber nicht — und der Banner ist
   das erste Element, das ein Besucher sieht. */
#wpconsent-root {
  --wpconsent-background: #100e7a !important;   /* ks-blue-dark */
  --wpconsent-accept-bg: #FFB800 !important;    /* Marken-Gelb, nicht #ffcd2a */
  --wpconsent-accept-color: #101418 !important;
  --wpconsent-font-size: 15px !important;
}
/* ⚠️ Der Shadow-Host ist #wpconsent-container, NICHT #wpconsent-root.
   `::part()` funktioniert ausschliesslich am Host selbst — die erste Fassung stand auf
   #wpconsent-root und traf deshalb nichts, waehrend die Farben trotzdem stimmten (die
   CSS-Variablen oben ERBEN in den Shadow-Baum, ::part-Regeln nicht). Genau daran laesst
   sich so ein Irrtum sonst nicht erkennen: halb wirksam sieht aus wie ganz wirksam.
   Gemessen mit shadowRoot-Zugriff im Browser, nicht geraten. */
@media (max-width: 768px) {
  /* Auf 390px war der Banner 250px hoch und deckte den Hero-CTA. Ein Pflichtdialog
     darf das Angebot nicht verstecken, sonst kostet die Einwilligung Umsatz.
     Kompakter: Text kleiner, Knoepfe in EINE Reihe statt drei Zeilen. */
  #wpconsent-container::part(wpconsent-banner) { padding: .8rem .9rem; }
  #wpconsent-container::part(wpconsent-banner-body) { font-size: 14px; line-height: 1.38; }
  #wpconsent-container::part(wpconsent-banner-footer) {
    flex-direction: row; flex-wrap: wrap; gap: .4rem;
  }
  /* 44px, nicht die 56px unserer Direktive: das ist kein Angebots-CTA, sondern ein
     Pflichtdialog, und er soll so wenig Bildflaeche wie moeglich kosten. 44px ist die
     Untergrenze fuer Fingerziele — die Knoepfe waren mit 30px darunter. */
  #wpconsent-container::part(wpconsent-button-accept),
  #wpconsent-container::part(wpconsent-button-cancel),
  #wpconsent-container::part(wpconsent-button-preferences) {
    flex: 1 1 7rem; min-height: 44px;
  }
}
/* Solange der Dialog offen ist, rutscht der Hero-Inhalt ueber ihn. Die Klasse setzt
   ks-v0-skin.js und nimmt sie nach der Entscheidung wieder weg — ein dauerhafter
   Abstand im CSS waere danach ein Loch.
   Bewusst OHNE Media Query: der Dialog steht auch auf 1440px unten links und deckte
   dort denselben Knopf. Die erste Fassung stand in der Mobil-Abfrage und war auf dem
   Schirm, auf dem die Seite gestaltet wird, wirkungslos. */
body.ks-consent-offen .ks-hero__unten { padding-bottom: 11rem; }

/* ==========================================================================
   MEDIEN ALS <img>, NICHT ALS CSS-HINTERGRUND
   ==========================================================================
   Am 2026-08-19 live gemessen: die Startseite lieferte NULL `<img>` — Hero,
   Panels, Kacheln und Kursreihe trugen ihre Fotos alle als `background-image`.
   Folgen, alle vier echt: jedes Handy laedt die 2000px-Fassung (kein srcset),
   die Bilder haben kein `alt`, sie laden nicht lazy, und fuer Suchmaschinen und
   Social-Vorschauen existieren sie nicht. Die Referenz (ridecake.com) benutzt
   durchgehend `<picture>`.

   Regel ab hier: tragende Motive kommen als `<img>` ins Markup, der Scrim liegt
   als eigene Ebene darueber. Reihenfolge der Ebenen ist explizit ueber z-index
   gesetzt und NICHT der DOM-Reihenfolge ueberlassen — ein `::before`-Scrim ohne
   z-index verliert gegen ein spaeter im DOM stehendes `img` mit z-index 0. */
.ks-hero__foto, .ks-panel__foto, .ks-panel__video, .ks-kat__foto, .ks-kurs__foto {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center; z-index: 0;
  /* Das Bild ist Flaeche, nicht Ziel: Klick und Auswahl gehoeren dem Link darum. */
  pointer-events: none; user-select: none;
}
.ks-kat__foto, .ks-kurs__foto { transition: transform .6s cubic-bezier(.25, .46, .45, .94); }
.ks-kat__tile:hover .ks-kat__foto, .ks-kurs:hover .ks-kurs__foto { transform: scale(1.08); }

/* Bewegtes Bild auf Foto-Panels: sehr langsamer Zoom.
   Die Referenz erzeugt ihren Eindruck mit stummen Endlos-Videos. Solange es die nicht
   gibt (die Mediathek hat KEINE nutzbare Fahraufnahme, s. Notiz in hero.php), ist das
   naechstbeste Mittel eine Bewegung, die das Standbild nicht zum Standbild macht:
   40 Sekunden, 6 % Weg, kein Richtungswechsel. Nur auf breiten Schirmen — auf dem Handy
   kostet ein dauerhaft animiertes, formatfuellendes Bild Akku ohne Gewinn.
   Bei prefers-reduced-motion steht es still UND bleibt sichtbar (Direktive §7). */
@media (min-width: 900px) {
  @keyframes ksPanelZoom { from { transform: scale(1); } to { transform: scale(1.06); } }
  .ks-panel__foto { animation: ksPanelZoom 40s ease-out both; }
}
@media (prefers-reduced-motion: reduce) {
  .ks-panel__foto { animation: none !important; }
  /* Das Video wird NICHT ausgeblendet — es wird in ks-v0-skin.js angehalten. Ein
     `display: none` haette das Panel leer gelassen (der Verlauf darunter ist nur
     Rueckfall), und die Direktive verlangt ausdruecklich: bei reduzierter Bewegung
     steht alles still UND bleibt sichtbar. CSS kann kein Video pausieren. */
}

/* --- Clean High-Impact Hero: Text unten links auf Foto --- */
/* Kein Foto mehr im background-image: das Motiv ist jetzt ein <img> (s. oben), der
   Verlauf liegt als ::after darueber. Wichtig, sonst laedt der Browser dasselbe
   Bild ZWEIMAL — einmal als CSS-Hintergrund, einmal als img. */
.ks-hero.ks-hero--claim { background-image: none; }
.ks-hero.ks-hero--claim::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image: linear-gradient(to top, rgba(10, 10, 60, .88) 0%, rgba(10, 10, 60, .4) 45%, rgba(10, 10, 60, 0) 75%);
}
.ks-hero.ks-hero--claim .ks-hero__unten { position: relative; z-index: 2; }
.ks-hero__unten { display: flex; align-items: flex-end; justify-content: space-between; gap: clamp(1.5rem, 4vw, 3rem); flex-wrap: wrap; width: 100%; max-width: 1280px; margin: 0 auto; padding: 2rem 1.2rem; }
/* 620px -> 760px (User-Fund 08-23): bei 620px hatte die CTA-Zeile (Button + Reviews-Karte
   mit Zitat) nicht genug Platz und wrappte die Karte unter den Button — genau die
   Zeilen-Hoehe, die die Zeile eigentlich vermeiden sollte. 760px reicht fuer Button
   (~260px) + Gap (1rem) + Reviews-Karte (max-width 420px) auf einer Zeile. */
.ks-hero__links { max-width: 760px; text-align: left; }
.ks-hero__kicker { display: block; font-size: clamp(.72rem, 1.4vw, .82rem); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ks-yellow, #FFB800); text-shadow: 0 1px 8px rgba(0, 0, 0, .6); margin-bottom: .4rem; }
/* Display-Groesse nach Direktive §3: >=56px mobil, >=72px Tablet, >=96px Desktop.
   Vorher clamp(2.1rem, 4.8vw, 3.8rem) = 27/37/61px — die Regel stand in der Direktive,
   wurde aber von keinem Gate geprueft und war entsprechend nirgends eingehalten.
   Die Formel deckt alle drei Breiten mit EINER Zeile: 390px -> 56 (Untergrenze),
   768px -> 72,2, 1440px -> 104 (Obergrenze). Deshalb hebt die Mobil-Medienabfrage
   weiter unten die Groesse auch nicht mehr an oder ab. */
.ks-hero--claim h1 {
  font-family: var(--ks-fd); font-weight: 600; color: #fff;
  font-size: clamp(3.5rem, 9.4vw, 6.5rem); line-height: 1.02; letter-spacing: -.035em;
  margin: .3rem 0 .7rem; text-shadow: 0 2px 14px rgba(0, 0, 0, .65);
}
.ks-hero--claim .ks-hero__sub {
  font-size: clamp(0.95rem, 1.6vw, 1.12rem); color: rgba(255, 255, 255, .92);
  margin: 0 0 1.2rem; line-height: 1.5; text-shadow: 0 1px 8px rgba(0, 0, 0, .6); max-width: 540px;
}
.ks-hero--claim .ks-btn {
  background: var(--ks-blue, #1510f0); color: #fff; font-weight: 700;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .35); white-space: nowrap; border: none;
}
.ks-hero--claim .ks-btn:hover { background: #2b26ff; color: #fff; transform: translateY(-2px); }
/* CTA + Reviews-Karte auf einer Zeile statt gestapelt (User-Fund 08-23: Karte unter dem
   Button macht den Hero unnoetig hoch — "immer an Scrollfaulheit denken"). Erster Versuch
   war ein kompaktes Badge ohne Zitat (data-ks-reviews-compact) — vom User verworfen, er
   will den Rezensionstext sehen. Zeigt jetzt dieselbe volle Karte wie über-uns/Trainer-
   Archiv; .ks-hero__links auf 760px verbreitert, damit sie neben dem Button Platz hat
   (s. dort). flex-wrap faengt schmale Viewports auf, ohne dass es abgeschnitten wird —
   dort stapelt es sich wieder, das ist so gewollt. */
.ks-hero__cta-row { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
/* Der Termin-Block ist die "konkret"-Qualitaet: Preis und Datum sofort sichtbar. */
.ks-hero__karte {
  display: flex; flex-direction: column; gap: .3rem; min-width: 15rem; max-width: 20rem;
  padding: 1rem 1.15rem; border-radius: 16px; text-decoration: none;
  background: rgba(255, 255, 255, .13); border: 1px solid rgba(255, 255, 255, .3);
  -webkit-backdrop-filter: blur(16px) saturate(140%); backdrop-filter: blur(16px) saturate(140%);
  transition: background .2s, transform .2s;
}
.ks-hero__karte:hover { background: rgba(255, 255, 255, .2); transform: translateY(-3px); }
.ks-hero__karte-label { font-size: .66rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--ks-yellow); }
.ks-hero__karte-titel { font-weight: 800; font-size: 1rem; color: #fff; line-height: 1.25; }
.ks-hero__karte-meta { display: flex; gap: .9rem; font-size: .85rem; font-weight: 700; color: rgba(255, 255, 255, .88); }
/* Zwei naechste Termine nebeneinander + dezenter Alle-Kurse-Link (User 08-20:
   „CTA zu allen Kursen moeglichst weit streuen — das ist Core Business"). */
.ks-hero__karten { display: flex; flex-wrap: wrap; gap: .8rem; align-items: stretch; }
.ks-hero__karte { max-width: none; }
.ks-hero__alle {
  display: inline-flex; align-items: center; gap: .4rem; align-self: flex-end;
  margin-left: auto; padding: .45rem .85rem; border-radius: 999px;
  font-size: .82rem; font-weight: 600; color: #fff; text-decoration: none;
  background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .25);
  transition: background .2s;
}
.ks-hero__alle:hover { background: rgba(255, 255, 255, .18); }
.ks-hero__alle .ks-ico { color: var(--ks-yellow); }
.ks-hero__cta-row .ks-hero__alle { margin-left: 0; align-self: center; }
/* Dezenten Alle-Kurse-Link unter Sektionen zentrieren. */
.ks-sec__alle { display: flex; justify-content: center; margin-top: 1.6rem; }

/* --- Variante C: Editorial-Split, Text auf Weiss --- */
.ks-hero--split { display: grid; grid-template-columns: 1fr 1fr; min-height: min(86vh, 800px); background: var(--ks-surface); overflow: hidden; text-align: left; }
.ks-hero--split .ks-hero__spalte { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: .25rem; padding: calc(var(--ks-header-h, 76px) + 2rem) clamp(1.2rem, 4vw, 4rem) 2.5rem; }
.ks-hero--split .ks-hero__kicker { color: var(--ks-blue); text-shadow: none; }
.ks-hero--split h1 { font-family: var(--ks-fd); font-weight: 500; color: var(--ks-t1); font-size: clamp(2.6rem, 6.4vw, 5.6rem); line-height: .94; letter-spacing: -.04em; margin: .5rem 0 1rem; }
.ks-hero--split .ks-hero__sub { color: var(--ks-t2); font-size: 1.02rem; max-width: 34ch; margin: 0 0 1.6rem; }
.ks-hero--split .ks-hero__naechster { margin: 1.2rem 0 0; font-size: .88rem; color: var(--ks-t2); }
.ks-hero__bild { background-image: var(--ks-hero-photo, var(--hero-blue)); background-size: cover; background-position: center; }
@media (max-width: 860px) {
  .ks-hero--split { grid-template-columns: 1fr; }
  .ks-hero__bild { order: -1; min-height: 46vh; }
  .ks-hero--split .ks-hero__spalte { padding-top: 2rem; }
  body.ks-hero-page .ks-hero--split .ks-hero__bild { padding-top: var(--ks-header-h, 76px); }
}

/* ==== KURS-RAIL: nackte Fotos statt weisser Boxen ==== */
.ks-sec__head--links { text-align: left; max-width: 1100px; }
.ks-kursrail {
  max-width: 1100px; margin: 0 auto; display: grid; grid-auto-flow: column;
  grid-auto-columns: minmax(240px, 27%); gap: 1.1rem;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  /* Rechts absichtlich ueber die Kante laufen lassen — das ist das Scroll-Signal
     der Referenz. Ein sauber abschliessendes Grid sieht aus wie "Ende". */
  padding: 0 1.2rem .6rem; margin-inline: calc(50% - 50vw); padding-inline: max(1.2rem, calc(50vw - 550px));
  /* scroll-padding ist hier KEIN Feinschliff, sondern noetig: mit
     `scroll-snap-type: x mandatory` rastet der Browser sofort auf die erste
     Karte ein und scrollt dabei den linken Innenabstand weg. Gemessen begann die
     erste Karte deshalb bei 0px, waehrend Kategorien, Magazin und Fuss alle bei
     170px stehen — die Reihe klebte als einzige am Fensterrand. Mit
     scroll-padding respektiert der Snap den Einzug. */
  scroll-padding-inline-start: max(1.2rem, calc(50vw - 550px));
}
.ks-kursrail::-webkit-scrollbar { display: none; }
/* ==== RIDECAKE: nackte Foto-Karten, keine Box mehr — Definition kommt vom Foto + Scrim
   (fuer Text-Lesbarkeit ueber dem Bild noetig, das ist keine Karten-Chrome) + der jetzt
   dunklen .ks-kursrail-sec-Flaeche dahinter. ==== */
.ks-kurs {
  position: relative; scroll-snap-align: start; min-height: 350px; border-radius: 0;
  overflow: hidden; display: flex; flex-direction: column; justify-content: space-between;
  padding: 1.25rem; text-decoration: none; color: #ffffff;
  transition: transform .35s cubic-bezier(.2, .8, .2, 1);
}
.ks-kurs:hover { transform: translateY(-6px); }
.ks-kurs__bg { position: absolute; inset: 0; background-size: cover; background-position: center; z-index: 1; transition: transform .6s cubic-bezier(.2, .8, .2, 1); }
.ks-kurs:hover .ks-kurs__bg { transform: scale(1.08); }
.ks-kurs__scrim { position: absolute; inset: 0; z-index: 2; background: linear-gradient(to top, rgba(8, 11, 28, 0.95) 0%, rgba(8, 11, 28, 0.55) 55%, rgba(8, 11, 28, 0.15) 100%); }
.ks-kurs__top { position: relative; z-index: 3; display: flex; justify-content: space-between; align-items: center; width: 100%; }
.ks-kurs__kat { font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--ks-yellow, #FFB800); background: rgba(10, 14, 38, 0.82); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); padding: .35rem .75rem; border-radius: 100px; border: 1px solid rgba(255, 255, 255, 0.2); }
.ks-kurs__knapp { font-size: .68rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: #101418; background: var(--ks-yellow, #FFB800); padding: .35rem .7rem; border-radius: 100px; }
.ks-kurs__content { position: relative; z-index: 3; display: flex; flex-direction: column; gap: .6rem; width: 100%; }
.ks-kurs__titel { font-family: var(--ks-fd); font-weight: 700; font-size: 1.25rem; line-height: 1.25; color: #ffffff; margin: 0; text-shadow: 0 2px 10px rgba(0, 0, 0, .7); }
.ks-kurs__footer { display: flex; justify-content: space-between; align-items: center; padding-top: .65rem; border-top: 1px solid rgba(255, 255, 255, 0.2); }
.ks-kurs__datum { font-size: .85rem; font-weight: 600; color: rgba(255, 255, 255, .9); }
.ks-kurs__preis { font-family: var(--ks-fd); font-size: 1.1rem; font-weight: 800; color: #ffffff; background: var(--ks-blue, #1510f0); padding: .3rem .8rem; border-radius: 8px; box-shadow: 0 4px 12px rgba(21, 16, 240, .4); }

/* Foto-Heroes exakt auf Viewport-Hoehe.
 * Spezifitaets-Falle: body.ks-hero-page .ks-hero ist (0,2,1) und schlug meine
 * (0,2,0)-Variantenregel — dadurch kam ein 156px-Innenabstand oben dazu, der Hero
 * wuchs auf 903px und schob das angeschnittene Wort unter die Falz. Deshalb hier
 * dreiklassig (0,3,1). Ergebnis: das Wort wird vom Bildrand gekappt, nicht von der
 * Fensterkante — genau der Unterschied zwischen Absicht und Panne.
 */
body.ks-hero-page .ks-hero.ks-hero--wort,
body.ks-hero-page .ks-hero.ks-hero--claim {
  /* box-sizing ist hier der Punkt: ohne border-box addiert sich der Innenabstand auf
     die 100vh und der Hero wurde 1039px hoch statt 900. */
  box-sizing: border-box;
  height: 100vh; min-height: 100vh;
  padding-top: calc(var(--ks-header-h, 76px) + 1.1rem);
}
body.ks-hero-page .ks-hero.ks-hero--split { min-height: 100vh; }

/* ==========================================================================
   BEWEGUNG — nachgebaut aus der Referenz, nicht erfunden.
   Gemessen an v0 "Evasion": kein GSAP, kein Framer Motion, keine
   animation-timeline, und NULL Elemente die sich beim Scrollen transformieren
   (also kein Parallax und kein Scroll-Reveal). Der dynamische Eindruck kommt
   aus zwei Dingen:
     1. vier Panels mit `sticky top-0 h-screen overflow-hidden` — sie bleiben
        stehen, waehrend die naechste Sektion darueber schiebt
     2. eine einzige Keyframe-Animation namens slideUp + viele Hover-Transitions
   Beides ist CSS-only, damit reduced-motion sauber greift (Direktive §9).
   ========================================================================== */

/* --- 1. Sticky-Pinning: der Hero bleibt stehen, der Inhalt schiebt darueber --- */
body.ks-hero-page .ks-hero.ks-hero--claim,
body.ks-hero-page .ks-hero.ks-hero--wort {
  position: sticky; top: 0; z-index: 0;
}
/* --- 2. Foto-Panels: die "vier Panels" aus dem Kommentar oben sind Hero + [ks_panel],
   nicht jede Sektion — die pinnen als einzige (echte Foto-Momente, kein Sektions-Loop).
   Inhalts-Sektionen (Kategorien, Kursrail, Beitraege) bleiben im normalen Dokumentfluss,
   pinnen NICHT. Ihre Flaechenfarbe kommt seit dem Ridecake-Wechsel 2026-08-17 aber NICHT
   mehr zwingend von Weiss: .ks-kursrail-sec ist bewusst dunkel (siehe .ks-sec-Regeln
   oben), Kategorien/Beitraege bleiben hell. "Weiss + genau ein dunkles Band" (alte
   Evasion-Referenz) gilt nicht mehr woertlich — siehe Direktive-Hinweis am Dateikopf
   der web-design-direktive.md. */
body.ks-hero-page .ks-panel {
  position: sticky;
  top: 0;
  z-index: 2;
  min-height: 100vh;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
  /* Motiv kommt als <img class="ks-panel__foto"> (srcset/lazy/alt). Der Verlauf
     bleibt nur noch Rueckfall, falls ein Panel ohne Bild eingebaut wird. */
  background-image: var(--hero-blue);
  background-size: cover;
  background-position: center;
}
/* Scrim ueber dem Bild. z-index PFLICHT: das <img> liegt auf 0, ein ::before ohne
   z-index steht im DOM davor und wuerde vom Bild verdeckt — dann waere der Text
   wieder kontrastlos, also genau der Fehler, den PR #1 hier behoben hat.
   Scrim-Wert aus theme.json (custom.scrim.brand-soft), nicht neu erfunden. */
body.ks-hero-page .ks-panel::before {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: var(--wp--custom--scrim--brand-soft);
}
body.ks-hero-page .ks-panel .ks-panel__text {
  position: relative; z-index: 2; color: #ffffff;
  max-width: 620px; margin: 0 auto; width: 100%;
  padding: 2rem clamp(1.2rem, 4vw, 3rem);
  text-shadow: 0 2px 12px rgba(0, 0, 0, .5);
}
body.ks-hero-page .ks-panel .ks-panel__kicker {
  display: block; font-size: .74rem; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ks-yellow, #FFB800); margin-bottom: .6rem;
}
body.ks-hero-page .ks-panel h2 { font-family: var(--ks-fd); font-weight: 700; color: #fff; margin: 0 0 .8rem; }
body.ks-hero-page .ks-panel p { color: rgba(255, 255, 255, .85); margin: 0 0 1.2rem; }

/* Bugfix 2026-08-20 (User: "nur eine Sektion" + Menue flackert beim Runterscrollen):
   Ohne eigenen Stacking-Context malt der Browser positionierte z-index:0-Elemente
   (Hero/Panel, sticky) NACH normalen Fluss-Boxen — unabhaengig von der DOM-Reihenfolge.
   Die folgenden Sektionen (Kategorien, Kursrail, Beitraege, ...) hatten kein eigenes
   position/z-index und landeten dadurch HINTER statt VOR dem gepinnten Hero: er blieb
   sichtbar und ueberlagerte den Seiteninhalt, statt vom naechsten Abschnitt bedeckt zu
   werden ("pinnen NICHT" aus dem Kommentar oben griff nicht ohne eigene Stacking-Order).
   Fix: jede Sektion nach dem Hero/Panel bekommt eine hoehere Stacking-Order. */
body.ks-hero-page .ks-hero ~ section,
body.ks-hero-page .ks-panel ~ section {
  position: relative;
  z-index: 1;
}

/* Ex-Ridecake-Ueberbleibsel entfernt: erzwang #ffffff auf JEDEM .ks-sec__head, auch auf
   den jetzt wieder weissen Sektionen (Kategorien, Kursrail, Beitraege) — weisser Text auf
   weissem Grund, design-gate schlug mit 1.0-1.7:1 Kontrast Alarm. Ohne diese Regel greift
   theme.json (elements.heading.color = --ks-text, dunkel) plus Zeile 274 (--ks-t2 fuer p).
   Echte dunkle Kontexte (.ks-panel, .ks-funnel) haben ihre eigene, dort verankerte Regel. */
.ks-sec__head h2 { font-family: var(--ks-fd); font-weight: 700; }

/* Eyebrow ohne Chip-Optik, Ridecake-Stil — aber NUR auf dunklem Grund: helles Gelb auf
   Weiss (Kategorien/Beitraege-Koepfe) lag bei 1.67:1, also unterhalb 4.5:1.
   Auf Weiss bleibt die frueher definierte Chip-Variante (Zeile 207, Blau auf hellem
   Chip) automatisch stehen, weil diese Regel jetzt scoped ist statt global.
   .ks-kursrail-sec ist seit der Ridecake-Flaechenfarben-Umstellung wieder dunkel
   (var(--ks-blue-dark)) — gehoert deshalb in dieselbe Gruppe. */
.ks-hero .ks-eyebrow, .ks-funnel .ks-eyebrow, .ks-panel .ks-eyebrow, .ks-kursrail-sec .ks-eyebrow {
  background: none; padding: 0; border-radius: 0;
  font-size: .74rem; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ks-yellow, #FFB800);
}
.ks-kursrail-sec .ks-sec__head h2 { color: #ffffff; }
.ks-kursrail-sec .ks-sec__head p { color: rgba(255, 255, 255, .78); }

/* Magazine & Post Cards: Ridecake-Treue — keine Box mehr, .ks-beitraege ist jetzt hell
   (erbt --ks-border von .ks-sec), Text darum dunkel statt weiss. */
.ks-post, .ks-beitrag {
  overflow: hidden; color: var(--ks-t1);
  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ks-post:hover, .ks-beitrag:hover { transform: translateY(-5px); }
.ks-post__title, .ks-post__titel { color: var(--ks-t1); font-family: var(--ks-fd); font-weight: 700; }
.ks-post__excerpt, .ks-post__meta { color: var(--ks-t2); }

/* Funnel CTA: kein eigener Kartenrahmen mehr — die Flaechenfarbe traegt bereits
   .ks-sec--alt (siehe oben), .ks-funnel ist nur noch der zentrierte Textblock darin,
   randlos bis zum Sektionsrand statt eine schwebende gerundete Karte. */
.ks-funnel {
  max-width: 1100px; margin: 0 auto; padding: clamp(1rem, 3vw, 2rem) 0;
  color: #ffffff; text-align: center;
}
.ks-funnel h2 { color: #ffffff; font-family: var(--ks-fd); font-weight: 700; margin-bottom: 0.8rem; }
.ks-funnel p { color: rgba(255, 255, 255, 0.9); font-size: 1.1rem; max-width: 600px; margin: 0 auto 1.5rem; }
/* Sektionskoepfe linksbuendig wie der Hero — zentriert wirkt wie Standard-Template. */
.ks-sec__head { text-align: left; max-width: 1100px; margin-left: auto; margin-right: auto; }
.ks-sec__head h2 { font-family: var(--ks-fd); font-weight: 500; letter-spacing: -.035em; }

/* ── Terminreihe wandert beim Scrollen (nur Desktop/Tablet) ──────────────
 *
 * ⚠️ ABWEICHUNG VON DER DIREKTIVE, bewusst und begrenzt.
 * §Motion haelt fest, dass in der Referenz NULL Elemente beim Scrollen
 * Transform oder Opacity aendern — „weder Parallax noch Scroll-Reveal". Das
 * hier ist von dieser Gattung. Der benannte Bedarf: auf dem Desktop steht die
 * Terminreihe als waagerechter Streifen, und wer nur senkrecht scrollt — also
 * fast jeder — sieht drei von acht Terminen und ahnt nicht, dass da mehr ist.
 * Das kostet Sichtbarkeit fuer Termine, die verkauft werden sollen.
 *
 * Drei Sicherungen, damit die Abweichung klein bleibt:
 *   1. Nur ab 769px. Auf dem Telefon bleibt das Wischen unangetastet — dort
 *      ist der Streifen als Streifen erkennbar und die Geste vertraut.
 *   2. Nur wenn der Browser scrollgesteuerte Animationen kann. Wo nicht,
 *      bleibt die Reihe eine ganz normale Scroll-Reihe. Keine Bibliothek,
 *      kein Ersatz per JavaScript — nur Fortschritt, kein Zwang.
 *   3. `prefers-reduced-motion` schaltet alles ab, und zwar so, dass die
 *      Reihe SICHTBAR und bedienbar bleibt (Direktive: nichts auf opacity 0).
 *
 * Die Weglaenge kann CSS nicht ausrechnen (Inhaltsbreite minus Sichtbreite),
 * deshalb setzt ks-v0-skin.js sie einmal als `--ks-rail-weg`. JavaScript MISST
 * hier nur; die Bewegung selbst bleibt CSS.
 */
@media (min-width: 769px) and (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    /* `clip`, NICHT `hidden`.
     *
     * `overflow: hidden` macht den Abschnitt zum Scroll-Container. Dann haengt
     * sich `view()` an DIESEN Container statt ans Dokument — und weil der nie
     * scrollt, steht der Fortschritt fest. Gemessen: die Reihe klebte bei
     * -354px, egal wo man auf der Seite war.
     *
     * `overflow-x: clip` schneidet ebenso ab, erzeugt aber KEINEN
     * Scroll-Container. Derselbe Unterschied hat in diesem Projekt schon einmal
     * den schwebenden Kopf lahmgelegt. */
    .ks-kursrail-sec { overflow-x: clip; }
    .ks-kursrail {
      /* Der Streifen wird geschoben statt gescrollt — Snap und eigenes Scrollen
         wuerden dagegen arbeiten. Manuell bedienbar bleibt er trotzdem: faellt
         die Animation aus (siehe @supports), gelten wieder die Regeln oben. */
      overflow-x: visible;
      scroll-snap-type: none;
      /* LANGSCHREIBWEISE, nicht `animation:`.
       *
       * Die Kurzschreibweise setzt `animation-timeline` auf ihren Anfangswert
       * zurueck und die Dauer auf 0s. Beides bricht eine scrollgesteuerte
       * Animation: sie braucht `animation-duration: auto`, sonst ist sie sofort
       * fertig und steht fest. Genau so war es — die Reihe klebte bei -354px,
       * unabhaengig von der Scrollposition. */
      animation-name: ks-rail-wandern;
      animation-duration: auto;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: view();
      /* Erst wenn der Abschnitt gut im Bild ist, und fertig, bevor er oben
         hinausl aeuft — sonst bewegt sich etwas, das man noch gar nicht liest. */
      /* Ueber den ganzen Weg durchs Bild, nicht nur ein schmales Band —
         sonst passiert die Bewegung in wenigen Pixeln und wirkt wie ein Ruck. */
      animation-range: cover 15% cover 85%;
    }
  }
}

@keyframes ks-rail-wandern {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-1 * var(--ks-rail-weg, 0px))); }
}

/* WhatsApp Direkt-Kommunikation Floating Widget (#ks-wa-btn) */
#ks-wa-btn {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 99990;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #25D366;
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 16px rgba(37, 211, 102, 0.4);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  text-decoration: none;
}
#ks-wa-btn:hover {
  transform: scale(1.08);
  box-shadow: 0 6px 20px rgba(37, 211, 102, 0.55);
}
#ks-wa-btn .ks-wa-tooltip {
  position: absolute;
  right: 68px;
  background: #111827;
  color: #ffffff;
  font-size: 13px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 8px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
#ks-wa-btn:hover .ks-wa-tooltip {
  opacity: 1;
}
/* Code-Review-Fund (08-22): die urspruengliche Fassung haengte
   `(max-height: 820px)` an DIESEN ganzen Block — der aber weit mehr enthaelt
   als die Ueberlauf-Regel (Logo-Verkleinerung, Button-Stapelung, WhatsApp-
   Button-Groesse, Schriftgroessen). Damit bekam jeder Desktop-Nutzer mit
   Maus auf einem Bildschirm ≤820px Hoehe — allen voran 1366x768, der
   haeufigste Laptop-Bildschirm ueberhaupt — faelschlich das komplette
   Mobil-Layout (gestapelte Buttons, geschrumpftes Logo, volle Kartenbreite),
   obwohl nur EINE Regel (der Hero-Ueberlauf) tatsaechlich von der Hoehe
   abhaengt. Deshalb bleibt dieser Block bei der urspruenglichen, rein
   breitenbasierten Bedingung; die Hoehen-Bedingung sitzt jetzt in einem
   eigenen, eng geschnittenen Block direkt darunter. */
@media (max-width: 768px) {
  #ks-wa-btn {
    bottom: 20px;
    right: 20px;
    width: 50px;
    height: 50px;
  }

  /* User-Fund 08-21: die gelbe Eyebrow-Zeile (.ks-hero__kicker) ueberlappte auf
     manchen Mobilgeraeten die Logo-Zeile. Echte Ursache (per Messung, nicht
     nur Vermutung): diese Regel setzte bisher nur `min-height: auto`, aber
     `height: 100vh` aus der unbedingten Basisregel (Zeile ~906) blieb
     BESTEHEN — eine starre Box. Kombiniert mit `justify-content: flex-end`
     (bodenbuendig, aus der --claim-Basisregel) lief der auf schmalen Screens
     hohe Textblock (Kicker+H1+Absatz+Button) oben aus dieser starren Box
     HERAUS, egal wie gross `padding-top` war — mehr Puffer half nicht,
     verschaerfte es sogar (weniger Restplatz in der Box). Fix: `height: auto`
     zusaetzlich zu `min-height: auto`, damit die Box mit dem Inhalt waechst
     statt ihn abzuschneiden. Puffer bleibt grosszuegig (3rem statt 1.25rem). */
  body.ks-hero-page .ks-hero.ks-hero--claim {
    height: auto;
    min-height: auto;
    padding-top: calc(var(--ks-header-h, 84px) + 3rem);
    padding-bottom: 2rem;
    align-items: flex-start;
  }
  .ks-hero__unten {
    flex-direction: column;
    align-items: stretch;
    gap: 1.25rem;
    padding: 0.5rem 0;
  }
  .ks-hero__links {
    max-width: 100%;
  }
  /* KEIN font-size hier mehr: diese Abfrage griff bei max-width 768px und drueckte
     den Titel auf 27px (390) bzw. 37px (768) — beides unter der Direktive §3. Die
     Basis-Regel oben deckt mobil mit ab. Zeilenhoehe bleibt etwas luftiger, weil der
     Titel auf schmalem Schirm ueber mehrere Zeilen laeuft. */
  .ks-hero--claim h1 {
    line-height: 1.06;
    margin: 0.3rem 0 0.5rem;
  }
  .ks-hero--claim .ks-hero__sub {
    font-size: 0.95rem;
    line-height: 1.45;
    margin-bottom: 0.8rem;
  }
  .ks-hero__features {
    gap: 0.4rem 0.6rem;
    margin-bottom: 1.1rem;
    font-size: 0.82rem;
  }
  .ks-hero__features li {
    padding: 0.2rem 0.5rem;
  }
  .ks-hero__actions {
    flex-direction: column;
    align-items: stretch;
    gap: 0.6rem;
  }
  .ks-hero__actions .ks-btn {
    text-align: center;
    justify-content: center;
    width: 100%;
  }
  .ks-hero__karte {
    width: 100%;
    max-width: 100%;
  }
  .ks-header__logo {
    height: 26px;
  }
  .ks-header__brand-text {
    font-size: 1rem;
  }
}

/* Befund 08-22, gleiche Fehlerklasse wie der Mega-Menue-Fix desselben Tages:
   Breite ALLEIN war die falsche Weiche fuer den Hero-Ueberlauf. Landscape-
   Tablets (1024x768) und der mit Abstand haeufigste Laptop-Bildschirm
   (1366x768) sind breiter als 768px, haben aber dieselbe knappe Bildschirm-
   HOEHE wie ein Handy — der Textblock lief dort identisch aus der
   100vh-Box heraus und ueberlappte die Schrumpf-Header-Flaeche (per
   Playwright bei 1024x768 gemessen: h1 rendert bei top:151px, obwohl
   padding-top rechnerisch ~394px verlangt). NUR diese eine Regel haengt an
   der Hoehe — bewusst NICHT der ganze Mobil-Block oben (Logo-Groesse,
   Button-Stapelung, WhatsApp-Button-Groesse haben mit dem Ueberlauf nichts
   zu tun und sollen auf einem breiten Desktop-Fenster mit Maus, das nur
   zufaellig kurz ist, nicht das Mobil-Layout ausloesen — Code-Review-Fund). */
@media (max-height: 820px) {
  body.ks-hero-page .ks-hero.ks-hero--claim {
    height: auto;
    min-height: auto;
    padding-top: calc(var(--ks-header-h, 84px) + 3rem);
    padding-bottom: 2rem;
    align-items: flex-start;
  }
}


/* ==========================================================================
   TRAINER-ARCHIV + ORTE (User 08-20)
   ========================================================================== */
/* Trainer: Foto-Karten — „die Trainer sehen und kennenlernen". */
.ks-trainer-archiv { max-width: 1200px; margin-inline: auto; padding: 3rem 1.2rem; }
.ks-trainer-archiv__h1 { font-family: var(--ks-fd); font-weight: 500; font-size: clamp(2rem, 4.5vw, 3.4rem); letter-spacing: -.03em; margin: 0 0 .6rem; }
.ks-trainer-archiv__sub { color: var(--ks-t2); max-width: 52ch; margin: 0 0 2.2rem; }
.ks-trainer-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: 1.4rem; }
.ks-trainer-karte { display: flex; flex-direction: column; gap: .35rem; background: #fff; border: 1px solid var(--ks-border); border-radius: 20px; overflow: hidden; text-decoration: none; transition: transform .2s, box-shadow .2s; }
.ks-trainer-karte:hover { transform: translateY(-4px); box-shadow: var(--sh-hov); }
.ks-trainer-karte__foto { aspect-ratio: 1/1; overflow: hidden; background: var(--ks-border); }
.ks-trainer-karte__img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; display: block; }
.ks-trainer-karte__name { font-family: var(--ks-fd); font-weight: 700; font-size: 1.05rem; color: var(--ks-t1); padding: .7rem 1rem 0; }
.ks-trainer-karte__meta { font-size: .85rem; color: var(--ks-t2); padding: 0 1rem; }
.ks-trainer-karte__meta:last-child { padding-bottom: 1rem; }

/* Orte: Lokations-Karten mit Details. */
.ks-orte { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1.4rem; max-width: 1200px; margin: 3rem auto; padding-inline: 1.2rem; }
.ks-ort { background: #fff; border: 1px solid var(--ks-border); border-radius: 20px; padding: 1.5rem; display: flex; flex-direction: column; gap: .6rem; }
.ks-ort__titel { font-family: var(--ks-fd); font-size: 1.15rem; margin: 0; }
.ks-ort__text { color: var(--ks-t2); font-size: .92rem; margin: 0; }
.ks-ort__adresse { font-weight: 700; font-size: .9rem; color: var(--ks-t1); margin: 0; }
.ks-ort__kurse { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--ks-border); padding-top: .6rem; display: grid; gap: .35rem; }
.ks-ort__kurse li { display: flex; justify-content: space-between; gap: .8rem; font-size: .88rem; }
.ks-ort__kurse a { color: var(--ks-blue); font-weight: 600; text-decoration: none; }
.ks-ort__kurse span { color: var(--ks-t2); white-space: nowrap; }
.ks-ort .ks-btn { align-self: flex-start; margin-top: auto; }

/* Karten-Gleichmaß auf /kurse/ (User 08-20): jede Karte ist ein identischer
   Stapel — Foto, Titel, Infos, Footer mit Preis+Button. Der Footer klebt unten
   (margin-top:auto), damit unterschiedliche Textlaengen und der Lernpfad-Hinweis
   die Button-Zeile nie aus der Reihe schieben. */
.kf-karte { display: flex; flex-direction: column; height: 100%; }
.kf-karte-footer { margin-top: auto; min-height: 2.7rem; align-items: flex-end; }
.kf-lernpfad-hinweis { display: inline-flex; align-items: center; gap: .3rem; align-self: flex-start; margin-top: .1rem; }

/* DVR-Badge (User 08-20): Sicherheitstrainings folgen den DVR-Richtlinien. */
.ks-dvr {
  display: flex; gap: 1rem; align-items: flex-start;
  background: var(--ks-bg, #f4f6fb); border: 1px solid var(--ks-border);
  border-left: 4px solid var(--ks-blue); border-radius: 14px;
  padding: 1.1rem 1.3rem; margin: 1.6rem 0;
}
.ks-dvr__badge {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 3.2rem; height: 3.2rem; border-radius: 10px;
  background: var(--ks-blue); color: #fff; font-weight: 800;
  font-size: .78rem; letter-spacing: .06em;
}
.ks-dvr strong { font-size: 1rem; }
.ks-dvr p { margin: .35rem 0 0; color: var(--ks-t2); font-size: .92rem; }
.ks-dvr a { color: var(--ks-blue); font-weight: 600; }

/* DVR-Footnote-Sternchen (Qualität & Standards) */
.ks-footnote-ref {
  display: inline-block;
  font-size: 0.72em;
  line-height: 1;
  vertical-align: super;
  text-decoration: none;
  color: inherit;
  font-weight: 700;
  margin-left: 1px;
  padding: 0 1px;
  cursor: pointer;
  transition: color 0.15s ease;
}
.ks-footnote-ref:hover {
  color: var(--ks-blue, #1510f0);
  text-decoration: underline;
}
.ks-dvr__badge .ks-footnote-ref {
  color: #ffffff;
}

/* Links in der Hero-Subline: weiss wie der Text + Unterstreichung als
   Link-Signal — der Browser-Default (blau) fiel auf dem Foto unter 4,5:1
   (design:gate maß 2,34:1). */
.ks-hero__sub a { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.ks-hero__sub a:hover { color: var(--ks-yellow); }

/* ==========================================================================
   SCHRUMPF-HEADER: INFO-FLAECHE (User-GO 08-20, Direktive §9b Stand 08-20)
   ========================================================================== */
.ks-header__info {
	border-bottom: 1px solid var(--ks-border);
}
.ks-header__info-head {
	font-family: var(--ks-fd);
	font-weight: 500;
	font-size: 1.45rem;
	letter-spacing: -.02em;
	line-height: 1.2;
	color: var(--ks-t1);
	margin: 0 0 .45rem;
	transition: color .28s ease;
}
.ks-header__info-sub {
	margin: 0 0 .6rem;
	font-weight: 700;
	font-size: .82rem;
	letter-spacing: .02em;
	color: var(--ks-blue);
	transition: color .28s ease;
}
.ks-header__info-text {
	margin: 0 auto;
	font-size: .86rem;
	line-height: 1.55;
	color: var(--ks-t2);
	max-width: 58ch;
	transition: color .28s ease;
}
.ks-header__info-bullets li {
	font-size: .84rem;
	color: var(--ks-t2);
	line-height: 1.5;
	transition: color .28s ease;
}
.ks-header__info-bullets strong {
	color: var(--ks-t1);
	font-weight: 700;
	transition: color .28s ease;
}
.ks-header__info-cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 3.5rem; /* Gate: CTA-Hoehe >= 56px */
	padding: .55rem 1.2rem;
	border-radius: 999px;
	font-size: .85rem;
	font-weight: 700;
	text-decoration: none;
	transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.ks-header__info-cta--prim {
	background: var(--ks-blue);
	color: #fff;
}
.ks-header__info-cta--prim:hover {
	background: var(--ks-blue-dark, #101ac0);
}
.ks-header__info-cta--ghost {
	border: 1px solid var(--ks-t2);
	color: var(--ks-t2);
	background: transparent;
}
.ks-header__info-cta--ghost:hover {
	border-color: var(--ks-blue);
	color: var(--ks-blue);
}
/* Ueber dem Hero traegt die Flaeche weisse Schrift (wie Logo + Tagline) und
   einen eigenen dunklen Scrim — der Info-Text lag sonst weiss auf hellem
   Himmel und war unlesbar (User-Bug 08-20, per Screenshot verifiziert). */
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__info {
	border-bottom-color: rgba(255, 255, 255, .28);
	background: linear-gradient(180deg, rgba(9, 13, 28, .68) 0%, rgba(9, 13, 28, .34) 100%);
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__info-head {
	color: #fff;
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__info-sub {
	color: var(--ks-yellow);
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__info-text,
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__info-bullets li {
	color: #fff;
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__info-bullets strong {
	color: #fff;
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__info-cta--ghost {
	border-color: rgba(255, 255, 255, .55);
	color: #fff;
}
.ks-header-over-hero:not(.ks-header-stuck) .ks-header__info-cta--ghost:hover {
	border-color: var(--ks-yellow);
	color: var(--ks-yellow);
}
/* Mega-Panel: Beschreibungszeile (ridecake-Dichte, User-GO 08-20). */
.ks-megapanel__text {
	font-size: .76rem;
	font-weight: 400;
	line-height: 1.35;
	color: var(--ks-t2);
	margin-top: .15rem;
}
/* SLT-Kursseiten: Video-Sektion „So sieht das Training aus" (User-GO 08-20).
   Das Video ist die EINE bewegte Flaeche der Seite — Poster als Ruhezustand,
   bei reduced-motion bleibt es beim Poster (Skin-JS). */
.ks-slt-video {
	margin: 2rem 0;
}
.ks-slt-video__titel {
	font-family: var(--ks-fd);
	font-weight: 500;
	font-size: 1.5rem;
	letter-spacing: -.02em;
	margin: 0 0 1rem;
}
.ks-slt-video__player {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
	border-radius: 20px;
	background: var(--ks-border);
}
/* Offene Mega-Panels bleiben beim Scrollen zu (Skin-JS setzt die Klasse,
   solange gescrollt wird + 180ms Ruhe) — nur der Hover-Fall, Tastatur-Fokus
   bleibt offen. */
header.ks-header-scrollt li:hover > .ks-megapanel {
	visibility: hidden;
	opacity: 0;
}
/* Der Hero-Freiraum folgt der schrumpfenden Leiste weich statt zu springen
   (das --ks-header-h-Nachmessen aendert genau dieses padding-top). */
body.ks-hero-page .ks-hero {
	transition: padding-top .3s ease;
}

/* ==========================================================================
   P4: 360°-KONZEPT ALS RUHIGE SAEULEN + FLAECHEN-PANEL (User 08-20)
   ========================================================================== */
/* Konzept: helle Sektion, die drei Saeulen selbst tragen die Markenfarben
   (P4: „drei ruhige Saeulen in Markenfarben"). Die Sektion bleibt hell, weil
   das Gate dunkle Baender zaehlt (ks-blue zaehlt WCAG-dunkel) — Kursrail +
   Funnel sind bereits zwei. */
.ks-konzept {
	background: var(--ks-bg, #f4f6fb);
	color: var(--ks-t1);
	padding: 4.5rem max(1.2rem, calc(50vw - 620px));
}
.ks-konzept__kopf {
	max-width: 46rem;
}
.ks-konzept__kicker {
	display: inline-block;
	font-size: .72rem;
	font-weight: 800;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--ks-blue);
	margin-bottom: .8rem;
}
.ks-konzept h2 {
	font-family: var(--ks-fd);
	font-weight: 500;
	font-size: clamp(1.9rem, 3.6vw, 2.8rem);
	letter-spacing: -.02em;
	margin: 0 0 .8rem;
}
.ks-konzept__kopf p {
	color: var(--ks-t2);
	max-width: 60ch;
	margin: 0 0 2.2rem;
}
.ks-konzept__rail {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: minmax(17rem, 1fr);
	overflow-x: auto;
	gap: 1.2rem;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	padding-bottom: .5rem;
}
.ks-konzept__rail::-webkit-scrollbar { display: none; }
.ks-konzept__saeule {
	scroll-snap-align: start;
	background: var(--ks-blue);
	color: #fff;
	border-radius: 14px;
	padding: 1.8rem 1.5rem;
	min-height: 14rem;
	display: flex;
	flex-direction: column;
}
.ks-konzept__saeule:nth-child(2) {
	background: var(--ks-yellow);
	color: #141414;
}
.ks-konzept__saeule:nth-child(3) {
	background: var(--ks-blue-dark);
	color: #fff;
}
.ks-konzept__saeule h3 {
	font-family: var(--ks-fd);
	font-weight: 600;
	font-size: 1.25rem;
	margin: 0 0 .7rem;
	color: inherit;
}
.ks-konzept__saeule p {
	font-size: .95rem;
	line-height: 1.55;
	margin: 0;
	color: inherit;
}
.ks-konzept__pfeile {
	display: flex;
	gap: .6rem;
	margin-top: 1.2rem;
}
.ks-konzept__pfeil {
	width: 3rem;
	height: 3rem;
	border-radius: 999px;
	cursor: pointer;
	background: #fff;
	border: 1px solid var(--ks-border);
	color: var(--ks-t1);
	font-size: 1.1rem;
	display: flex; align-items: center; justify-content: center;
}
/* Icon fehlte bisher (User-Fund 08-21: leere Kreise ohne sichtbares Pfeil-
   Symbol) — ksfp_icon('arrow') zeigt serienmaessig nach rechts, der Links-
   Pfeil wird per Spiegelung gedreht statt eine zweite SVG zu pflegen. */
.ks-konzept__pfeil .ks-ico { width: 20px; height: 20px; }
.ks-konzept__pfeil--links .ks-ico { transform: scaleX(-1); }
.ks-konzept__pfeil:hover { background: var(--ks-border); }
.ks-konzept__pfeil:disabled { opacity: .35; cursor: default; background: #fff; }
.ks-konzept__pfeil:disabled:hover { background: #fff; }

/* Kursrail-Pfeile (User-Fund 08-21: Rail hatte gar keine) — gleiches Muster
   wie .ks-konzept__pfeil, eigene Klasse weil die Rail auf dunklem Grund
   (.ks-kursrail-sec) sitzt und die Pfeile dort als weisse Kreise mit
   dunklem Icon deutlicher wirken als auf hellem Grund. */
.ks-kursrail__pfeile { display: flex; gap: .6rem; justify-content: flex-end; margin: 1rem max(1.2rem, calc(50vw - 600px)) 0; }
.ks-kursrail__pfeil {
	width: 3rem; height: 3rem; border-radius: 999px; cursor: pointer;
	background: #fff; border: 0; color: var(--ks-blue-dark);
	display: flex; align-items: center; justify-content: center;
}
.ks-kursrail__pfeil .ks-ico { width: 20px; height: 20px; }
.ks-kursrail__pfeil--links .ks-ico { transform: scaleX(-1); }
.ks-kursrail__pfeil:hover { background: var(--ks-yellow, #FFB800); }
.ks-kursrail__pfeil:disabled { opacity: .3; cursor: default; background: #fff; }
.ks-kursrail__pfeil:disabled:hover { background: #fff; }
.ks-konzept__cta { margin-top: 2rem; }
/* Ridecake-Vorbild (User-Wunsch 08-21): Pfeile bleiben IMMER sichtbar, statt
   sich bei fehlendem Ueberlauf zu verstecken — Skin-JS deaktiviert sie an den
   Scroll-Enden (disabled-Zustand) statt sie ganz auszublenden. Auf breiten
   Screens (>1000px) blieb die Rail bisher starr dreispaltig (overflow-x:
   visible) und zeigte nie Pfeile; das faellt jetzt weg, die Rail bleibt bei
   jeder Breite eine echte Scroll-Leiste. */

/* Panel als ruhige Farbflaeche (flaeche-Attribut des Shortcodes).
   ⚠️ Die Selektoren muessen `body.ks-hero-page .ks-panel` ueberbieten —
   dessen Regeln (dunkler Hintergrund, weisse Schrift) gelten sonst weiter
   und die helle Flaeche traegt weissen Text (User-Bug 08-20: „blau
   hinterlegt, nicht lesbar"). */
body.ks-hero-page .ks-panel--flaeche {
	background: linear-gradient(160deg, #eef1f7 0%, #e2e7f0 100%);
}
body.ks-hero-page .ks-panel--flaeche .ks-panel__text {
	position: static;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(18rem, 22rem);
	gap: 2.5rem;
	align-items: center;
	padding: 4.5rem max(1.2rem, calc(50vw - 620px));
}
body.ks-hero-page .ks-panel--flaeche .ks-panel__kicker { color: var(--ks-blue); }
body.ks-hero-page .ks-panel--flaeche h2 { color: var(--ks-t1); }
body.ks-hero-page .ks-panel--flaeche p { color: var(--ks-t2); }
body.ks-hero-page .ks-panel--flaeche .ks-panel__bild-wrap {
	margin: 0;
	text-align: center;
}
body.ks-hero-page .ks-panel--flaeche .ks-panel__bild {
	width: 100%;
	height: 100%;
	min-height: 16rem;
	object-fit: cover;
	border-radius: 20px;
	box-shadow: 0 18px 44px rgba(16, 20, 24, .16);
}
body.ks-hero-page .ks-panel--flaeche .ks-panel__bild-meta {
	font-size: .78rem;
	color: var(--ks-t2);
	margin: .5rem 0 0;
}
@media (max-width: 900px) {
	body.ks-hero-page .ks-panel--flaeche .ks-panel__text { grid-template-columns: 1fr; }
}
.ks-panel--flaeche-blau { background: var(--ks-blue); }
.ks-panel--flaeche-dunkel { background: var(--ks-blue-dark); }
.ks-panel--flaeche-blau h2,
.ks-panel--flaeche-dunkel h2 { color: #fff; }
.ks-panel--flaeche-blau p,
.ks-panel--flaeche-dunkel p { color: rgba(255, 255, 255, .85); }
.ks-panel--flaeche-blau .ks-panel__kicker,
.ks-panel--flaeche-dunkel .ks-panel__kicker { color: var(--ks-yellow); }

/* ==========================================================================
   TRAININGSGELAENDE-SEKTION: zwei Karten + Vergleichstabelle (User 08-20)
   ========================================================================== */
.ks-gelaende {
	background: var(--ks-bg, #f4f6fb);
	padding: 4.5rem max(1.2rem, calc(50vw - 620px));
}
.ks-gelaende__kicker {
	display: inline-block;
	font-size: .72rem;
	font-weight: 800;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--ks-blue);
	margin-bottom: .5rem;
}
.ks-gelaende__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 1.4rem;
}
.ks-gelaende__karte {
	background: #fff;
	border: 1px solid var(--ks-border);
	border-radius: 20px;
	padding: 1.8rem 1.6rem;
}
.ks-gelaende__karte h3 {
	font-family: var(--ks-fd);
	font-weight: 600;
	font-size: 1.3rem;
	margin: 0 0 .6rem;
}
.ks-gelaende__karte h4 {
	font-size: .95rem;
	font-weight: 700;
	margin: 1.3rem 0 .35rem;
}
.ks-gelaende__karte p {
	color: var(--ks-t2);
	font-size: .92rem;
	line-height: 1.55;
}
.ks-gelaende__lead {
	margin: 0 0 1rem;
}
.ks-gelaende__liste {
	list-style: none;
	margin: 0 0 1rem;
	padding: 0;
	display: grid;
	gap: .55rem;
	font-size: .92rem;
	line-height: 1.5;
	color: var(--ks-t2);
}
.ks-gelaende__liste strong { color: var(--ks-t1); }
.ks-gelaende__infra {
	font-size: .86rem;
	margin: 0 0 1rem;
}
.ks-gelaende__bild-wrap { margin: 0 0 1rem; }
.ks-gelaende__bild {
	width: 100%;
	height: auto;
	max-height: 15rem;
	object-fit: cover;
	border-radius: 14px;
}
.ks-gelaende__maps {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
	margin-top: 1rem;
}
.ks-gelaende__maplink {
	display: inline-flex;
	align-items: center;
	padding: .45rem .85rem;
	border-radius: 999px;
	border: 1px solid var(--ks-border);
	font-size: .82rem;
	font-weight: 600;
	color: var(--ks-blue);
	text-decoration: none;
	background: #fff;
}
.ks-gelaende__maplink:hover { border-color: var(--ks-blue); }
.ks-gelaende__vergleich {
	width: 100%;
	border-collapse: collapse;
	margin-top: 1.4rem;
	font-size: .88rem;
	background: #fff;
	border: 1px solid var(--ks-border);
	border-radius: 14px;
	overflow: hidden;
}
.ks-gelaende__vergleich th,
.ks-gelaende__vergleich td {
	padding: .7rem .9rem;
	text-align: left;
	border-top: 1px solid var(--ks-border);
}
.ks-gelaende__vergleich thead th {
	background: var(--ks-bg, #f4f6fb);
	font-family: var(--ks-fd);
	font-weight: 600;
	font-size: .95rem;
}
.ks-gelaende__vergleich tbody th {
	color: var(--ks-t2);
	font-weight: 600;
	white-space: nowrap;
}
.ks-gelaende__vergleich thead th:first-child,
.ks-gelaende__vergleich tbody tr:first-child th,
.ks-gelaende__vergleich tbody tr:first-child td {
	border-top: 0;
}
@media (max-width: 900px) {
	.ks-gelaende__grid { grid-template-columns: 1fr; }
}

/* Hero-Beruhigung (P2-Rest, User 08-20): Foto blendet zu ruhiger dunkler
   Markenflaeche, sobald die Kurskategorien erscheinen (Skin-JS, one-way bis
   fast ganz oben; RM: aus — Foto bleibt). */
.ks-hero {
	background-color: var(--ks-blue-dark);
}
.ks-hero__foto {
	transition: opacity .5s ease;
}
body.ks-hero-beruhigt .ks-hero__foto {
	opacity: 0;
}

/* ==========================================================================
   VIDEO-SEKTION (Frontpage-Ausbau 08-20): hell, Video gerahmt rechts.
   ========================================================================== */
.ks-video-sektion {
	background: #fff;
	padding: 4.5rem max(1.2rem, calc(50vw - 620px));
}
.ks-video-sektion__inner {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(18rem, 30rem);
	gap: 2.5rem;
	align-items: center;
}
.ks-video-sektion__kicker {
	display: inline-block;
	font-size: .72rem;
	font-weight: 800;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--ks-blue);
	margin-bottom: .8rem;
}
.ks-video-sektion h2 {
	font-family: var(--ks-fd);
	font-weight: 500;
	font-size: clamp(1.9rem, 3.6vw, 2.8rem);
	letter-spacing: -.02em;
	margin: 0 0 .8rem;
	color: var(--ks-t1);
}
.ks-video-sektion p {
	color: var(--ks-t2);
	max-width: 52ch;
	margin: 0 0 1.4rem;
}
.ks-video-sektion__player {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	border-radius: 20px;
	display: block;
	background: var(--ks-border);
}
@media (max-width: 900px) {
	.ks-video-sektion__inner { grid-template-columns: 1fr; }
}

/* Foto-Sequenz-Variante von [ks_video_sektion] (User-Wunsch 08-21): reiner
   CSS-Crossfade + Ken-Burns-Zoom durch bis zu 8 gestapelte Bilder, ein Bild
   nach dem anderen sichtbar+zoomend, endlos. `overflow:hidden` PFLICHT: ohne
   das würde der gezoomte Bildrand (scale 1.08) die runde Ecke überragen.
   Grundzustand (auch mobil, auch vor JS/CSS-Load): erstes Bild fest sichtbar
   — dieselbe "steht still UND bleibt sichtbar"-Regel wie beim Einzelbild-Zoom
   von .ks-panel__foto weiter unten. Die Animation läuft nur ab 900px
   (Direktive: kein dauerhaft animiertes, formatfüllendes Bild auf dem Handy
   ohne Mehrwert fürs Akku). */
.ks-video-sektion__player--fotos { position: relative; overflow: hidden; }
.ks-video-sektion__foto {
	position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
	opacity: 0;
}
.ks-video-sektion__foto:first-child { opacity: 1; }
@media (min-width: 900px) {
	@keyframes ksVideoSektionSequenz {
		0%    { opacity: 0; transform: scale(1); }
		1.5%  { opacity: 1; }
		11%   { opacity: 1; transform: scale(1.08); }
		12.5% { opacity: 0; transform: scale(1.08); }
		100%  { opacity: 0; }
	}
	.ks-video-sektion__foto { animation: ksVideoSektionSequenz 36s ease-in-out infinite; }
	/* Acht Zeitfenster à 12,5 % der 36-s-Schleife — negativer Delay versetzt jedes
	   Bild um ein Fenster, damit immer genau eins sichtbar+zoomend ist. */
	.ks-video-sektion__foto:nth-child(1) { animation-delay: 0s; }
	.ks-video-sektion__foto:nth-child(2) { animation-delay: -4.5s; }
	.ks-video-sektion__foto:nth-child(3) { animation-delay: -9s; }
	.ks-video-sektion__foto:nth-child(4) { animation-delay: -13.5s; }
	.ks-video-sektion__foto:nth-child(5) { animation-delay: -18s; }
	.ks-video-sektion__foto:nth-child(6) { animation-delay: -22.5s; }
	.ks-video-sektion__foto:nth-child(7) { animation-delay: -27s; }
	.ks-video-sektion__foto:nth-child(8) { animation-delay: -31.5s; }
}
@media (prefers-reduced-motion: reduce) {
	.ks-video-sektion__foto { animation: none !important; opacity: 0; transform: none; }
	.ks-video-sektion__foto:first-child { opacity: 1; }
}

/* ==== KURS-FAQS (AKKORDEON) ==== */
.kf-faq-container {
  margin: 3rem 0 2rem;
  width: 100%;
}
.kf-faq-heading {
  font-family: var(--ks-fd);
  font-size: clamp(1.25rem, 2.5vw, 1.55rem);
  font-weight: 700;
  color: var(--ks-t1);
  margin-bottom: 1.25rem;
}
.kf-faq-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.kf-faq-item {
  background: #ffffff;
  border: 1px solid #e0e4ef;
  border-radius: 12px;
  overflow: hidden;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.kf-faq-item:hover {
  border-color: #cbd5e1;
}
.kf-faq-item[open] {
  border-color: rgba(21, 16, 240, 0.35);
  box-shadow: 0 4px 16px rgba(21, 16, 240, 0.06);
}
.kf-faq-question {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 1.1rem 1.25rem;
  font-size: 1rem;
  font-weight: 600;
  color: #1a1a2e;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.kf-faq-question::-webkit-details-marker {
  display: none;
}
.kf-faq-question:focus-visible {
  outline: 2px solid #1510f0;
  outline-offset: -2px;
}
.kf-faq-icon {
  color: #1510f0;
  flex-shrink: 0;
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.kf-faq-item[open] .kf-faq-icon {
  transform: rotate(180deg);
}
.kf-faq-answer {
  padding: 0 1.25rem 1.25rem;
  border-top: 1px solid transparent;
}
.kf-faq-item[open] .kf-faq-answer {
  border-top-color: #f1f5f9;
}
.kf-faq-answer p {
  margin: 0.75rem 0 0;
  font-size: 0.95rem;
  line-height: 1.65;
  color: #4b5563;
}
@media (max-width: 640px) {
  .kf-faq-question {
    padding: 0.95rem 1rem;
    font-size: 0.92rem;
  }
  .kf-faq-answer {
    padding: 0 1rem 1rem;
  }
}

/* ==== SEITEN-HERO-BILDER (z. B. /schraeglagentrainings/) ==== */
.ks-page-hero-image {
  margin-bottom: 2rem;
  border-radius: 12px;
  overflow: hidden;
  height: 440px;
  max-height: 440px;
  position: relative;
  background: #f1f5f9;
}
.ks-page-hero-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  display: block;
}
@media (max-width: 768px) {
  .ks-page-hero-image {
    height: 260px;
    max-height: 260px;
  }
}
