/* kit.css — generiert aus designsystem/ am 2026-08-31
   NICHT von Hand bearbeiten: sh designsystem/build-kit-css.sh */


/* ======== tokens/fonts.css ======== */
/* ============================================================================
   SCHRIFTEN — self-hosted, aus dem App-Land-Export
   ----------------------------------------------------------------------------
   Beide Familien sind frei nutzbar, auch kommerziell (geprüft 17.08.2026):
   · Switzer — Indian Type Foundry, fontshare.com/fonts/switzer
   · Raveo Variable — Jakub Foglar, SIL Open Font License 1.1

   Raveo trägt ALLES: die Überschriften-Hierarchie (650/600) UND seit
   Entscheid 6 (29.08.2026) auch den Fließtext auf wght 400 — exakt so läuft
   bikepass.eu live (nachgemessen: raveo-variable.woff2, font-weight 400,
   Base 16/1.55). Switzer bleibt als geladener Fallback in zweiter Position,
   trägt aber keine Ebene mehr.

   App Land aktiviert auf beiden Familien dieselben OpenType-Features.
   ========================================================================== */

@font-face {
  font-family: "Raveo";
  src: url("../fonts/raveo-variable.woff2") format("woff2-variations"),
       url("../fonts/raveo-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Switzer";
  src: url("../fonts/switzer-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Switzer";
  src: url("../fonts/switzer-500-italic.woff2") format("woff2");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Switzer";
  src: url("../fonts/switzer-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Switzer";
  src: url("../fonts/switzer-700-italic.woff2") format("woff2");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

:root {
  /* PageHero-Ausnahme (readme, Entscheid 5): Bebas Neue kommt von der Site
     (Google Fonts), nicht aus diesem Ordner — hier nur der benannte Stack. */
  --font-hero-upper: 'Bebas Neue', Impact, sans-serif;

  --font-display: "Raveo", "Switzer", system-ui, sans-serif;  /* @kind font */
  /* Fließtext = Raveo 400, exakt der Live-Stand von bikepass.eu
     (Entscheid 6, 29.08.2026 — live: font-family 'Raveo', wght 400). */
  --font-sans:    "Raveo", "Switzer", system-ui, sans-serif;  /* @kind font */

  /* App Land aktiviert diese Features auf jeder Textebene. Sie sind Teil
     der Anmutung, nicht Dekoration — nicht weglassen. */
  --font-features: "blwf" on, "cv03" on, "cv04" on, "cv09" on, "cv11" on;
}

/* ======== tokens/colors.css ======== */
/* ============================================================================
   FARBEN — BikePass × App Land
   ----------------------------------------------------------------------------
   Herkunft: App Land definiert 93 Farb-Tokens, davon sind 13 aktiv im Einsatz
   (≥ 25 Verwendungen im statischen Export). Der Rest stammt aus anderen
   Template-Varianten des Autors und ist bewusst NICHT übernommen.

   BikePass-Anteil: ausschließlich die Akzentfarbe. Überall dort, wo das
   Template Orange bzw. den Navy-Bildwash gesetzt hat, steht jetzt die
   Teal-Familie. Neutrals, Alpha-Leiter und Flächenlogik bleiben App Land.

   Drei Schichten: Primitive → Semantic → Component.
   ========================================================================== */

:root {
  /* --------------------------------------------------------------------
     SCHICHT 1 — PRIMITIVE (Rohwerte, nie direkt in Komponenten benutzen)
     -------------------------------------------------------------------- */

  /* Neutrals — App Land, unverändert */
  --ink:            #101011; /* @kind color */ /* Text primär, dunkle Flächen */
  --steel:          #606266; /* @kind color */ /* Text sekundär */
  --mist:           #f4f6f9; /* @kind color */ /* helle Sections */
  --paper:          #ffffff; /* @kind color */ /* Karten, Basisfläche */

  /* Alpha-Leiter — eigenständige Flächenfarben, keine abgeleiteten
     Transparenzen. App Land nutzt sie als Füllung, nicht als Effekt. */
  --ink-10:         rgba(16, 16, 17, 0.10); /* @kind color */ /* Rahmen auf Hell */
  --ink-15:         rgba(16, 16, 17, 0.15);  /* @kind color */ /* Rahmen betont */
  --ink-30:         rgba(16, 16, 17, 0.30);  /* @kind color */ /* inaktiver Text */
  --ink-90:         rgba(16, 16, 17, 0.90);  /* @kind color */ /* Overlay dunkel */
  --white-06:       rgba(255, 255, 255, 0.06); /* @kind color */ /* Fläche auf Dunkel */
  --white-10:       rgba(255, 255, 255, 0.10); /* @kind color */ /* Rahmen auf Dunkel */
  --white-15:       rgba(255, 255, 255, 0.15); /* @kind color */ /* Rahmen betont dunkel */
  --white-70:       rgba(255, 255, 255, 0.70); /* @kind color */ /* Text auf Dunkel */
  --black-50:       rgba(0, 0, 0, 0.50);       /* @kind color */ /* Scrim über Foto */
  --ink-55:         rgba(16, 16, 17, 0.55);     /* @kind color */ /* Hero-Ebene über Foto */
  --steel-60:       rgba(96, 98, 102, 0.60);   /* @kind color */ /* Text tertiär */
  --mist-0:         rgba(244, 246, 249, 0);    /* @kind color */ /* Verlaufs-Endpunkt */

  /* Marke — BikePass. Der einzige Marken-Anteil im ganzen System. */
  --teal:           #36d0bc;  /* @kind color */ /* Akzent, CTA-Fläche, Icon-Kreis */
  --teal-hover:     #14b8a6;  /* @kind color */ /* Hover/Aktiv */
  --teal-deep:      #0d9488;  /* @kind color */ /* Text auf Hell, Fokus-Ring */
  --teal-light:     #e6f7f5;  /* @kind color */ /* zarte Akzentfläche */
  --teal-veil:      #0e3b32;  /* @kind color */ /* Bildwash (Template: #133954) */

  /* Illustration — Gehäuse und Bühne. Keine Markenfarben, sondern
     Bestandteile zweier konkreter Bauteile (iPhone-Rahmen, CTA-Bühne). */
  --phone-shell-1:  #43474d;   /* @kind color */
  --phone-shell-2:  #111418;   /* @kind color */
  --phone-shell-3:  #0a0c10;   /* @kind color */
  --scene-1:        #07211c;   /* @kind color */
  --scene-2:        #0b3a32;   /* @kind color */
  --scene-3:        #072019;   /* @kind color */
  --mask:           #000;      /* @kind color */ /* nur für mask-image */

  /* Wash & Bühne — die benannten Ebenenfarben der beiden Gradient-Bauteile
     (Hero-Wash, CTA-Szene). Vorher lagen diese Werte als rohe rgba() in
     component-styles.css — Verstoß gegen die eigene Token-Pflicht
     (bereinigt 2026-08-29). */
  --teal-10:        rgba(54, 208, 188, 0.10); /* @kind color */ /* Feature-Kartenfläche */
  --teal-35:        rgba(54, 208, 188, 0.35); /* @kind color */ /* Feature-Kartenrahmen */
  --teal-22:        rgba(54, 208, 188, 0.22); /* @kind color */ /* Icon-Chip-Rahmen */
  /* PageHero-Bühne — exakt der Live-EBD-Hero (nachgemessen 29.08.2026):
     Fläche Slate-50, Vignette und Objektschatten auf Slate-900-Basis. */
  --hero-surface:    #f5f6f9;                  /* @kind color */ /* E13d (Chris 30.08.): helle Studio-Bühne — löst die Teal-Bühne ab, die Foto-Freisteller verschmelzen mit dem Grund */
  --teal-lift:      color-mix(in srgb, var(--teal) 76%, #ffffff); /* hellere Hero-Mitte (E13: Ink-Copy braucht Kontrast) */
  --teal-surface:   color-mix(in srgb, var(--teal) 72%, #ffffff); /* Text-tragende Teal-Fläche (Buttons, Tabellen-Highlight) — heller für Ink-Lesbarkeit (Chris 30.08.) */
  /* E13 (Chris 29.08. spät): DREI Farbstopps — links und rechts dasselbe Teal,
     die Mitte heller, damit die schwarze Schrift besser herauskommt. */
  --hero-vignette:  rgba(13, 148, 136, 0.38); /* @kind color */ /* PageHero-Randabdunklung (teal-deep) */
  --hero-glow:      rgba(255, 255, 255, 0.18); /* @kind color */ /* PageHero-Lichtschein oben (subtil — der Verlauf trägt) */
  --star:           #f59e0b;                   /* @kind color */ /* Bewertungs-Sterne — Live-Kanon der review-card */
  /* E34 — bp-buybox: Ampel-Grün der Lagerzeile (Live-Kanon des Stock-Dots)
     und Streichpreis-Rot (Chris 22.08.: immer rot — als Ersparnis lesbar,
     nicht als ausgegraute Nebeninformation). */
  --ok:             #22c55e;                   /* @kind color */
  --ok-ring:        rgba(34, 197, 94, 0.18);   /* @kind color */ /* Puls-Ring des Lager-Punkts */
  --ok-ring-soft:   rgba(34, 197, 94, 0.10);   /* @kind color */
  --price-cut:      #dc2626;                   /* @kind color */
  /* E25 — bp-cta-video: ganz dezenter Teal-Mesh auf der Night-Bühne */
  --cta-video-mesh-a: color-mix(in srgb, var(--teal) 13%, transparent);
  --cta-video-mesh-b: color-mix(in srgb, var(--teal) 8%, transparent);
  --cta-video-glow:   color-mix(in srgb, var(--teal) 20%, transparent); /* Lichtkegel hinter dem Video-iPhone */
  /* E23 — bp-showcase: weicher Ink-Schatten unter den App-Kacheln */
  --showcase-phone-shadow: color-mix(in srgb, var(--ink) 10%, transparent);
  --hero-obj-shadow: rgba(14, 59, 50, 0.30);  /* @kind color */ /* Drop-Shadow der 3D-Objekte auf Teal */
  --solo-shadow-strong: rgba(15, 23, 42, 0.13);  /* @kind color */ /* Journey-Schlagschatten flacher Grafik-Solos, satte Stufe */
  --solo-shadow-soft:   rgba(15, 23, 42, 0.08);  /* @kind color */ /* dito, weiche Stufe */

  /* Funktionen-Bento — effektiver Live-Stand der Startseite (29.08.2026) */
  --bento-tile-bg:   var(--paper);             /* Karten auf grauer Fläche sind WEISS (Chris 30.08.) */
  --bento-visual-bg: #f0fdfa;                  /* @kind color */ /* Verlaufsstart der Bild-Bühne */

  /* Night-CTA + dunkler Footer — Live-Tiefton unterhalb von Ink */
  --ink-deep:        #050a14;                  /* @kind color */ /* Night-Bühne, Live-Footer */
  --night-mesh-a:   rgba(54, 208, 188, 0.18); /* @kind color */ /* Mesh-Radial oben links */
  --night-mesh-b:   rgba(54, 208, 188, 0.12); /* @kind color */ /* Mesh-Radial unten rechts */
  --night-copy:      #cbd5e1;                  /* @kind color */ /* Copy auf Night (live slate-300) */
  --night-fine:      #94a3b8;                  /* @kind color */ /* Fine-Print auf Night (slate-400) */

  /* Aurora-Schein des hellen Final-Clusters (Live: cta-glow--aurora) */
  --aurora-a:       rgba(54, 208, 188, 0.22); /* @kind color */
  --aurora-b:       rgba(167, 243, 208, 0.28); /* @kind color */
  --aurora-c:       rgba(254, 240, 138, 0.12); /* @kind color */

  /* iPhone-Frame des App-Clusters (bpg-Familie, Live-Werte) */
  --phone-frame-a:   #43474d;                  /* @kind color */
  --phone-frame-b:   #111418;                  /* @kind color */
  --phone-frame-c:   #0a0c10;                  /* @kind color */
  --phone-homebar:  rgba(15, 23, 42, 0.32);   /* @kind color */
  --phone-gloss:    rgba(255, 255, 255, 0.14);/* @kind color */
  --phone-screen-line: rgba(0, 0, 0, 0.06);   /* @kind color */

  /* Fremdmarken-Farben der Payment-Pills (keine Systemfarben — Markenvorgaben) */
  --brandmark-paypal-a: #003087;  /* @kind color */
  --brandmark-paypal-b: #009cde;  /* @kind color */
  --brandmark-visa:     #1a1f71;  /* @kind color */
  --brandmark-gpay:     #5f6368;  /* @kind color */
  --brandmark-black:    #1a1a1a;  /* @kind color */ /* Pill-Text, Apple-Wortmarke */

  --wash-deep-a:    rgba(8, 48, 41, 0.98);   /* @kind color */
  --wash-deep-b:    rgba(8, 48, 41, 0.92);   /* @kind color */
  --wash-teal-a:    rgba(54, 208, 188, 0.95); /* @kind color */
  --wash-teal-b:    rgba(54, 208, 188, 0.75); /* @kind color */
  --wash-hover:     rgba(20, 184, 166, 0.90); /* @kind color */
  --wash-base-1:    rgba(11, 64, 55, 0.40);  /* @kind color */
  --wash-base-2:    rgba(13, 148, 136, 0.18); /* @kind color */
  --wash-base-3:    rgba(20, 184, 166, 0.24); /* @kind color */
  --wash-glow:      rgba(94, 234, 212, 0.90); /* @kind color */
  --scene-glow-1:   rgba(13, 148, 136, 0.55); /* @kind color */
  --scene-glow-2:   rgba(54, 208, 188, 0.35); /* @kind color */

  /* --------------------------------------------------------------------
     SCHICHT 2 — SEMANTIC (Zweck statt Wert — hier greifen Komponenten zu)
     -------------------------------------------------------------------- */

  --color-text:             var(--ink);
  --color-text-muted:       var(--steel);
  --color-text-subtle:      var(--steel-60);
  --color-text-inverse:     var(--paper);
  --color-text-inverse-muted: var(--white-70);
  --color-text-accent:      var(--teal-deep);

  --color-surface:          var(--paper);      /* Karten */
  --color-surface-sunken:   var(--mist);       /* helle Sections */
  --color-surface-inverse:  var(--ink);        /* Ink-Flächen */
  --color-surface-accent:   var(--teal-light);
  --color-surface-on-dark:  var(--white-06);   /* Karte auf Ink */

  --color-border:           var(--ink-10);
  --color-border-strong:    var(--ink-15);
  --color-border-on-dark:   var(--white-10);
  --color-border-on-dark-strong: var(--white-15);

  --color-accent:           var(--teal);
  --color-accent-hover:     var(--teal-hover);
  --color-accent-contrast:  var(--ink);        /* Text auf Teal-Fläche */

  --color-surface-hover:    var(--mist);       /* Hover-Fläche tone-responsiver Bauteile */
  --color-scrim:            var(--black-50);   /* Foto abdunkeln */
  --color-hero-veil:        var(--ink-55);     /* durchgehende Hero-Ebene */
  --color-veil:             var(--teal-veil);  /* Foto einfärben */
  --color-focus:            var(--teal-deep);

  /* --------------------------------------------------------------------
     SCHICHT 3 — COMPONENT
     -------------------------------------------------------------------- */

  /* ⚠️ E7-TEST (Chris 31.08., sitewide, bewusst temporär): Primär-Button wieder
     im Live-Verlauf mit weißem Label — 1:1 der alte .btn-primary-Verlauf
     (plugin.css: 90deg, teal-deep → teal). Revert = die zwei auskommentierten
     Kanon-Zeilen zurücktauschen und den Header-CTA-Contract in
     verify-kit-live.mjs wieder auf „bg-image: none" stellen. */
  --button-bg:              linear-gradient(90deg, var(--teal-deep) 36%, #1cd2ba 100%); /* @kind color */ /* Chris-Justage 31.08.: Deep-Anteil bis 36 %, Endton heller */
  --button-fg:              var(--paper);
  /* Kanon (E18-Nachfass): --button-bg: var(--teal-surface); --button-fg: var(--color-accent-contrast); */
  --button-bg-hover:        var(--color-accent);   /* Hover sättigt aufs Brand-Teal */
  --button-icon-bg:         var(--paper);          /* DECKEND — keine Opacity-Pfeilboxen (Chris 30.08.) */

  --button-light-bg:        var(--color-surface);
  --button-light-fg:        var(--color-text);
  --button-light-bg-hover:  var(--mist);       /* friert wie bg/fg — der Light-Button ist IMMER hell */
  --button-dark-bg:         var(--color-surface-inverse);
  --button-dark-fg:         var(--color-text-inverse);
  --button-dark-icon-bg:    var(--teal-surface);   /* DECKEND, Pfeil in Ink */

  --chip-bg:                var(--color-surface);
  --chip-fg:                var(--color-text);
  --chip-border:            var(--color-border);

  --card-bg:                var(--color-surface);
  --card-fg:                var(--color-text);
  --card-border:            transparent;
  --card-inverse-bg:        var(--color-surface-inverse);
  --card-inverse-fg:        var(--color-text-inverse);

  --nav-link-fg:            var(--color-text);
  --nav-link-bg-hover:      var(--color-surface-sunken);

  --accordion-border:       var(--color-border);
  --accordion-icon-bg:      var(--color-surface-sunken);
}

/* Ink-Kontext: auf dunklen Flächen kippen die semantischen Rollen mit.
   Nicht Dark-Mode — App Land hat keinen. Es ist ein Flächen-Kontext. */
[data-tone="ink"] {
  --color-text:             var(--paper);
  --color-text-muted:       var(--white-70);
  --color-text-subtle:      var(--white-70);
  --color-surface:          var(--white-06);
  --color-surface-sunken:   var(--ink);
  --color-border:           var(--white-10);
  --color-border-strong:    var(--white-15);
  /* Hover-Flächen kippen mit — Component-Tokens (button-*) sind am :root
     eingefroren und bleiben hier bewusst unangetastet: der Light-Button ist
     auf Ink genauso hell wie auf Paper (Bug-Lesson 2026-08-29: sein Hover
     lief über --color-surface-sunken und wurde auf Ink unsichtbar). */
  --color-surface-hover:    var(--white-10);
  --chip-bg:                transparent;
  --chip-fg:                var(--paper);
  --chip-border:            var(--white-15);
  --card-bg:                var(--white-06);
  --card-fg:                var(--paper);
  --nav-link-bg-hover:      var(--white-10);
  --accordion-border:       var(--white-10);
  --accordion-icon-bg:      var(--white-10);
}

/* ======== tokens/typography.css ======== */
/* ============================================================================
   TYPOGRAFIE — 16 Ebenen, 3 Breakpoints
   ----------------------------------------------------------------------------
   Gemessen aus dem statischen App-Land-Export (16 `framer-styles-preset-*`
   Regeln), 1:1 deckungsgleich mit den 16 benannten Text-Styles im Framer-
   Projekt. Die Namen hier sind die Framer-Namen.

   ZWEI KORREKTUREN gegenüber der ersten Extraktion (uploads/design-tokens-appland.md):

   1. Die Gewichte sind NICHT „nur 400 und 500". Bei einer Variable-Font steht
      `font-weight` immer auf 400 — das echte Gewicht liegt auf der wght-Achse.
      App Land staffelt seine Hierarchie darüber: 700 · 650 · 600 · 500.
   2. Tracking ist ein FESTER px-Wert, kein em-Wert. Auf Mobile bleibt das
      Tracking damit absolut gleich — genau das erzeugt die enge Anmutung.

   Breakpoints wie im Original: ≥1200 · 810–1199,98 · ≤809,98.
   ========================================================================== */

:root {
  /* --- Display-Ebenen (Raveo) ------------------------------------------ */
  --text-h1:          86px;  --text-h1-wght:  700;  --text-h1-ls:  -2px;
  --text-h2:          52px;  --text-h2-wght:  650;  --text-h2-ls:  -0.6px; /* 58 → 52 (Chris 30.08.) */
  --text-h2-sm:       32px;  --text-h2-sm-wght: 650;
  --text-h3:          44px;  --text-h3-wght:  500;
  --text-h3-sm:       28px;  --text-h3-sm-wght: 600;
  --text-h4:          34px;  --text-h4-wght:  500;
  --text-h4-sm:       26px;  --text-h4-sm-wght: 600;
  --text-h5:          26px;  --text-h5-wght:  500;
  --text-h5-sm:       24px;  --text-h5-sm-wght: 600;  /* Kartentitel-Ebene (Blog/Team) — Staffel 600 */
  --text-h6:          22px;  --text-h6-wght:  600;  /* Kartentitel-Ebene (FAQ/Steps/Kontakt) — Staffel 600 */
  --text-mega:       220px;  --text-mega-wght: 650;  /* 404-Zahl, Footer-Wortmarke */

  /* --- Text-Ebenen (Fließtext = Raveo 400 — Live-Stand bikepass.eu) -----
     Entscheid 6 (29.08.2026): exakt nachgemessen auf bikepass.eu —
     Base 16px/1.55 · Sub/LG 16.8px/1.55 · Lead 18.4px/1.6 (Live-clamp
     1rem–1.15rem, hier als feste Stufen der Breakpoint-Staffel). */
  --text-lead:        18.4px;
  --text-lg:          16.8px;
  --text-base:        16px;
  --text-cms:         16px;
  --text-xs:          14px;
  --text-btn:         15px;  /* Button- und Pill-Label */
  --text-hero-trust:  13.12px; /* Hero-Trustzeile (live 0.82rem) */
  --text-pay-pill:    11px;    /* Payment-Pill-Beschriftung (Live-Checkout-Optik) */
  --pay-mark-wght:    900;     /* VISA-Wortmarke */
  --pay-sub-wght:     600;     /* GPay/ApplePay-Zusatz */
  --pay-paypal-ls:    -0.02em; /* Markenvorgabe PayPal */
  --pay-visa-ls:      -0.01em; /* Markenvorgabe VISA */
  --text-pay-mark:    13px;    /* PayPal-/VISA-Wortmarke in der Pill */
  --text-table-head:  13px;    /* Tabellen-Kopfzeile (bp-table, Stil A) + Trust-Strip-Pills */
  --text-stat:          clamp(56px, 5vw, 72px); /* E24: Bebas-Zahlenwert der freien Stats */
  --stat-lh:            1;      /* @kind other */
  --stat-ls:            0.01em;
  --table-head-ls:    0.04em;  /* Uppercase-Tracking der Tabellen-Kopfzeile */
  --btn-wght:         600;     /* Button-Label — 1:1 der Live-.bp-jr-link (Chris 29.08.) */
  --text-step-num:    17px;    /* Ziffer im Timeline-Nummernkreis (bp-steps, E22) */
  --text-statement:   clamp(34px, 4.2vw, 60px); /* Cluster-Statement — kleiner als die Hero-H1 (Chris 30.08.) */
  --star-ls:          0.08em;  /* Sterne-Tracking der Bewertungs-Karte (Live-Kanon) */
  /* E34 — bp-buybox (Produkt-Kaufbühne, 31.08.2026): Live-Kanon der Buybox
     v2.29/v2.32 (Chris 22.08.: H1 15 % kleiner; Preis Ink, eine Spur größer). */
  --text-buybox-title: clamp(38px, 4.25vw, 57px); /* H1 Bebas der Kaufspalte */
  --buybox-title-lh:  1.02; /* @kind other */ /* Live-Messwert der bp-order-h1 */
  --text-price:       clamp(32px, 3.2vw, 41.6px); /* Verkaufspreis, Raveo */
  --text-price-wght:  800;
  --price-ls:         -0.015em; /* Verkaufspreis-Tracking (tabular-nums im CSS) */
  --strip-lh:         1.35; /* @kind other */ /* Kundenzeile im Trust-Strip (Live-Messwert) */
  --bento-title-lh:   1.3;     /* @kind other */ /* Tile-Titel der Funktionen-Bento (live) */

  /* --- Konstanten über alle Ebenen ------------------------------------- */
  --display-ls:      -0.6px;  /* alle Raveo-Ebenen außer H1 und Mega */
  --display-lh:       1.1; /* @kind other */
  --copy-lh:          1.55; /* @kind other */ /* Live-Stand bikepass.eu (16/24.8) — Entscheid 6 */
  --lead-lh:          1.6; /* @kind other */ /* Live-Stand der Lead-/Hero-Subzeile */
  --xs-lh:            1.1; /* @kind other */
  --mega-lh:          0.8; /* @kind other */ /* Wortmarken-Wasserzeichen */
  --control-lh:       1;   /* @kind other */ /* Buttons, Chips, Badges, Pay-Marken */
  --control-multiline-lh: 1.2; /* @kind other */ /* mehrzeilige Button-Labels (v2.60.0, Chris 31.08.) */
  --text-section-sub: clamp(1rem, 1.6vw, 1.2rem); /* Sektionskopf-Subzeile (v2.62.1, Chris 31.08.) */
  --copy-wght:        400; /* Fließtext Raveo 400 — exakt live (Entscheid 6) */
  --strong-wght:      700; /* Bold-Auszeichnung im Fließtext */
  --display-ps:       40px;   /* Absatzabstand Raveo */
  --copy-ps:          20px;   /* Absatzabstand Switzer */
  --cms-ps:           10px;   /* Fließtext aus dem CMS */
  --measure:         700px;   /* maximale Lesebreite */

  /* PageHero-H1 (bp-page-hero) — die dokumentierte Bebas-Ausnahme.
     Exakt der Live-EBD-Hero (nachgemessen 29.08.2026, bikepass.eu):
     ≥1024 Bebas 500, clamp bis 96px; darunter Raveo 600, clamp bis 70.4px.
     Dazu die Live-Konstanten Zeilenhöhe 1.06 und Laufweite −2 %. */
  --text-hero-page:     clamp(48px, 7vw, 90px);  /* Deckel 96 → 90; Minimum 44 → 48 (Chris 30.08., Runde 10: mobile Hierarchie — die Hero-H1 muss klar über der 33px-H2 liegen, Bebas wirkt condensed kleiner) */
  --text-hero-page-sm:  clamp(40px, 6vw, 70.4px);
  --hero-title-wght:    500;  /* Bebas-Schnitt des Live-Heros */
  --hero-title-stroke:  0em; /* @kind other */ /* E13c-Nachfass 2: Stroke abgeschafft — auch 0.016em war Chris zu dick; es gilt der pure 500er-Schnitt */
  --hero-title-lh:      1.06; /* @kind other */
  --hero-title-ls:      -0.02em;

  /* Finale-Statement (bp-cta-cluster) — Live-Werte des cta-statement:
     Bebas 400 in Hero-Größe, engere Zeile, leicht positives Tracking. */
  --statement-wght:     400;
  --statement-lh:       0.98; /* @kind other */
  --statement-ls:       0.015em;
}

@media (max-width: 1199.98px) {
  :root {
    --text-h1: 70px;  --text-h2: 48px;  --text-h2-sm: 32px;
    --text-h3: 32px;  --text-h3-sm: 24px;
    --text-h4: 24px;  --text-h4-sm: 24px;
    --text-h5: 24px;  --text-h5-sm: 22px;
    --text-h6: 20px;  --text-mega: 176px;
    --text-lead: 16.8px; --text-lg: 16px;
  }
}

@media (max-width: 809.98px) {
  :root {
    /* Runde 9 (Chris 30.08.): Section- und Kartentitel mobil im Verhältnis
       etwas kleiner — h2 36 → 33, h4-sm 22 → 20. */
    --text-h1: 48px;  --text-h2: 33px;  --text-h2-sm: 28px;
    --text-h3: 22px;  --text-h3-sm: 21px;
    --text-h4: 20px;  --text-h4-sm: 22px; /* v2.60: Karten-Titel mobil 20→22px (Chris 31.08.) */
    --text-h5: 20px;  --text-h5-sm: 20px;
    --text-h6: 19px;  --text-mega: 141px;
    --text-lead: 16px; --text-lg: 14px; --text-base: 14px; --text-cms: 14px;
  }
}

/* ============================================================================
   ANWENDUNGSKLASSEN
   Jede Ebene hat genau eine Klasse. Nie font-size direkt setzen.
   ========================================================================== */

.bp-t-h1, .bp-t-h2, .bp-t-h2-sm, .bp-t-h3, .bp-t-h3-sm, .bp-t-h4, .bp-t-h4-sm,
.bp-t-h5, .bp-t-h5-sm, .bp-t-h6, .bp-t-mega {
  font-family: var(--font-display);
  font-feature-settings: var(--font-features);
  letter-spacing: var(--display-ls);
  line-height: var(--display-lh);
  color: var(--color-text);
  margin: 0;
}

.bp-t-h1    { font-size: var(--text-h1);    font-weight: var(--text-h1-wght);    font-variation-settings: "opsz" 16, "wght" var(--text-h1-wght); letter-spacing: var(--text-h1-ls); }
.bp-t-h2    { font-size: var(--text-h2);    font-weight: var(--text-h2-wght);    font-variation-settings: "opsz" 16, "wght" var(--text-h2-wght); }
.bp-t-h2-sm { font-size: var(--text-h2-sm); font-weight: var(--text-h2-sm-wght); font-variation-settings: "opsz" 16, "wght" var(--text-h2-sm-wght); }
.bp-t-h3    { font-size: var(--text-h3);    font-weight: var(--text-h3-wght);    font-variation-settings: "opsz" 16, "wght" var(--text-h3-wght); }
.bp-t-h3-sm { font-size: var(--text-h3-sm); font-weight: var(--text-h3-sm-wght); font-variation-settings: "opsz" 16, "wght" var(--text-h3-sm-wght); }
.bp-t-h4    { font-size: var(--text-h4);    font-weight: var(--text-h4-wght);    font-variation-settings: "opsz" 16, "wght" var(--text-h4-wght); }
.bp-t-h4-sm { font-size: var(--text-h4-sm); font-weight: var(--text-h4-sm-wght); font-variation-settings: "opsz" 16, "wght" var(--text-h4-sm-wght); }
.bp-t-h5    { font-size: var(--text-h5);    font-weight: var(--text-h5-wght);    font-variation-settings: "opsz" 16, "wght" var(--text-h5-wght); }
.bp-t-h5-sm { font-size: var(--text-h5-sm); font-weight: var(--text-h5-sm-wght); font-variation-settings: "opsz" 16, "wght" var(--text-h5-sm-wght); }
.bp-t-h6    { font-size: var(--text-h6);    font-weight: var(--text-h6-wght);    font-variation-settings: "opsz" 16, "wght" var(--text-h6-wght); }
.bp-t-mega  { font-size: var(--text-mega);  font-weight: var(--text-mega-wght);  font-variation-settings: "opsz" 16, "wght" var(--text-mega-wght); letter-spacing: 0; line-height: var(--mega-lh); }

.bp-t-lead, .bp-t-lg, .bp-t-base, .bp-t-cms, .bp-t-xs {
  font-family: var(--font-sans);
  font-feature-settings: var(--font-features);
  font-weight: var(--copy-wght);
  letter-spacing: 0;
  line-height: var(--copy-lh);
  color: var(--color-text-muted);
  margin: 0;
}

.bp-t-lead { font-size: var(--text-lead); line-height: var(--lead-lh); }
.bp-t-lg   { font-size: var(--text-lg); }
.bp-t-base { font-size: var(--text-base); }
.bp-t-cms  { font-size: var(--text-cms); }
.bp-t-xs   { font-size: var(--text-xs); line-height: var(--xs-lh); }

/* Absatzfolgen — der Abstand kommt aus dem System, nicht aus margin-bottom */
.bp-t-cms  > * + * { margin-top: var(--cms-ps); }
.bp-t-lead + p, .bp-t-lg + p, .bp-t-base + p { margin-top: var(--copy-ps); }

/* ======== tokens/spacing.css ======== */
/* ============================================================================
   RAUM, FORM UND TIEFE
   ----------------------------------------------------------------------------
   App Land arbeitet nicht mit einem 4er- oder 8er-Raster, sondern mit einer
   kurzen Liste tatsächlich benutzter Werte. Gemessen aus dem Export nach
   Häufigkeit — die Skala unten ist erschöpfend, es gibt keine weiteren Stufen.

   Der wichtigste Wert des Systems ist nicht eine Zahl, sondern eine Regel:
   der Sektionsrhythmus ist KONSTANT, nicht pro Sektion individuell.
   ========================================================================== */

:root {
  /* --- Abstands-Skala (gemessen, nach Häufigkeit) ---------------------- */
  --space-2:    4px;
  --space-3:    6px;
  --space-4:   10px;   /* häufigster Gap überhaupt */
  --space-5:   12px;
  --space-6:   16px;
  --space-8:   20px;   /* Grid-Gap, Absatzabstand Switzer */
  --space-10:  30px;   /* Karten-Padding, Container-Rand */
  --space-12:  40px;   /* Absatzabstand Raveo */
  --space-14:  50px;
  --space-16:  60px;
  --space-20:  80px;   /* Kopf-Block → Inhalt */
  --space-24: 100px;   /* Sektions-Padding je Seite, Desktop */

  /* --- Sektionsrhythmus ------------------------------------------------ */
  /* Zwischen zwei Sektions-Inhalten liegen auf Desktop 200 px — also 100 je
     Seite bei angrenzenden Flächen. Mobile: 60 je Seite. Eine Formel deckt
     beides ab und ist die einzige, die je anzuwenden ist. */
  --section-pad:      clamp(60px, 6.5vw, 100px);
  --section-pad-solo: clamp(90px, 13vw, 200px);  /* Sektion ohne Nachbarfläche */

  /* --- Kopf-Kette (Chip → H2 → Sub → Inhalt) --------------------------- */
  /* Überall im System identisch. Wer hier abweicht, bricht den Rhythmus. */
  --head-chip-gap:  26px;   /* Chip → H2 */
  --head-sub-gap:   20px;   /* H2 → Subline */
  --head-body-gap:  80px;   /* Kopf-Block → erste Karte */

  /* --- Container ------------------------------------------------------- */
  --container-outer: 1380px;  /* äußere Begrenzung inkl. Rand */
  --container:       1320px;  /* reine Inhaltsbreite */
  --container-pad:     30px;  /* Rand links/rechts */
  --grid-gap:          20px;

  /* --- Radien ---------------------------------------------------------- */
  --radius-card:      30px;  /* große Karten, Sections, Bildrahmen */
  --radius-card-alt:  25px;  /* Sonderfall im Original, selten */
  --radius-card-sm:   20px;  /* kleine Karten, FAQ-Zeilen */
  --radius-tile:      16px;  /* Kacheln, Eingabefelder */
  --radius-chip:      10px;  /* eckige Kleinstflächen */
  /* E34 — bp-buybox: Funnel-Paritäts-Radien (Chris v2.28.1: bewusst FESTE
     Werte, damit Produktseite und /bestellen/ identisch aussehen — Hauptbild
     14, Thumbs 12; die Kartensprache beider Flächen). */
  --radius-funnel:    14px;
  --radius-funnel-sm: 12px;
  --radius-button:     8px;  /* Buttons */
  --radius-pill:     100px;  /* Chips, Tabs */
  --radius-circle:     50%;  /* Icon-Kreise, Avatare */

  /* --- Bauteil-Maße ---------------------------------------------------- */
  /* Button-Metriken = 1:1 der Live-.bp-jr-link (Chris 29.08. spät):
     48px Gesamthöhe, Icon 32px rechts bündig (8px Rand), Label-Einzug 20px. */
  --pill-height:      48px;
  --pill-pad:  8px 8px 8px 20px;
  --pill-icon:        32px;
  --btn-icon-inset:    8px;  /* Abstand des Icon-Quadrats zur rechten Buttonkante (Wellen-Ursprung) */
  --card-pad:         30px;
  --nav-height:       80px;
  --nav-link-pad: 6px 14px;


  /* --- Bauteil-Maße, die aus dem Original gemessen sind ---------------- */
  --size-icon-sm:      22px;  /* Icon im kompakten Button */
  --size-icon:         24px;  /* Aufzählungs-Kreis */
  --size-feature-icon: 48px;  /* Icon-Kreis der Feature-/Methoden-Karten */
  --size-accordion:    32px;  /* Plus/Kreuz-Kreis */
  --size-avatar-sm:    32px;
  --size-avatar:       44px;
  --size-avatar-lg:    64px;
  --size-avatar-lap:  -12px;  /* Überlappung der Avatar-Reihe */
  --size-control-sm:   34px;  /* Höhe bp-btn--sm */
  --size-social:       40px;
  --size-roadmap-num:  40px;
  --size-play:         64px;
  --size-logo:         32px;
  --size-logo-footer:  40px;
  --size-logo-tile:    80px;  /* Mindesthöhe Ticker-Kachel */
  --size-testimonial: 380px;  /* Breite der Stimmen-Karte im Marquee */
  --size-compare-min: 720px;  /* ab hier scrollt die Vergleichstabelle */
  --marquee-gap:       64px;
  --dropdown-min:     280px;
  --toc-width:        280px;  /* Sticky-Inhaltsverzeichnis auf Rechtstextseiten */
  --phone-w-min:      190px;  /* Fächer-Phone, unterer Anschlag */
  --phone-w-max:      240px;  /* Fächer-Phone, oberer Anschlag */
  --size-pay-logo:     18px;  /* Höhe der Zahlarten-Wortmarken (bp-pay-mono) */
  --border-w:           1px;  /* die eine Rahmenstärke des Systems */
  --border-w-strong:    2px;  /* Avatar-Ring auf Fläche */

  /* --- Seitenverhältnisse — vorher an 6 Stellen als rohe Werte ---------- */
  --ratio-media:      4 / 3;  /* Feature-/Inhalts-Media */
  --ratio-photo:      3 / 2;  /* Blog-/Foto-Karten */
  --ratio-portrait:   3 / 4;  /* Team-Porträts */
  --ratio-wide:      21 / 9;  /* breite Header-/CTA-Bilder */

  /* --- Hero-Layout — vorher 4 verschiedene Textbreiten (720/720/680/620)
         und 2 ungetokente Mindesthöhen quer durch ui_kits und templates --- */
  /* PageHero-Maße — Anatomie dem Live-EBD-Hero nachgemessen (29.08.2026).
     Padding-Entscheid gleichen Tags (Chris): Bühnen laufen im NORMALEN
     Sektionsrhythmus — das Live-128er-Sonderpadding ist abgeschafft. */
  --page-hero-pad:        var(--section-pad);        /* = clamp(60→100), nie mehr Sonder-Padding */
  --hero-inner-pad-btm:   clamp(32px, 4vw, 50px);    /* Titelblock → Bühnenrand */
  --hero-inner-pad-btm-sm: clamp(104px, 24vw, 144px);/* mobil: Platz für die untere Dekor-Reihe */
  --hero-inner-max:       1280px;  /* Innenraum (live 80rem — breiter als --measure-hero) */
  --hero-title-gap:       24px;    /* Abstand über dem Titel (live 1.5rem) */
  --hero-actions-gap:     28px;    /* Sub → CTA-Zeile (live 1.75rem) */
  --hero-trust-gap:       25.6px;  /* CTA-Zeile → Trustzeile (live 1.6rem) */
  --hero-float-lift:      12px;    /* Hub des Schwebe-Loops (live −12px) */
  --hero-inset:           clamp(16px, 2vw, 24px); /* Seitenrand randvoller Bühnen (live --section-inset-x) */
  --measure-faq:          1100px; /* FAQ-Modul-Inhaltsbreite (Entscheid 29.08.: breiter als 820) */
  --measure-stage:         900px; /* Copy-Breite der Bühnen (Foto-CTA, Cluster) — 720 lief zu schmal (Chris 29.08.) */
  --size-review:           320px; /* Breite der Bewertungs-Karte im Marquee (Live-Kanon) */
  --measure-table:        1000px; /* Tabellen-Inhaltsbreite — schmaler als der Container (Chris 30.08.) */
  --measure-head:          860px; /* E9-Nachfass: Zeilenmaß der Section-Headlines — liefen vorher containerbreit (Chris 30.08.) */
  --size-measure-icon: 52px;  /* Icon-Chip der Maßnahmen-Karte (48px mobil via --size-feature-icon-Nähe bewusst NICHT geteilt) */

  --hero-min:         520px;  /* Start-/Vollhero */
  --hero-min-sm:      420px;  /* kompakter Hero (Leistungs-/Wartelisten-Seite) */
  --measure-hero:     720px;  /* Hero-Textspalte (bewusst breiter als --measure) */

  /* --- Weichzeichnung — Teil der Anmutung, keine Zufallswerte ---------- */
  --blur-wash:         60px;  /* Hero-Wash-Blobs */
  --blur-scene:        26px;  /* Ambient-Video hinter der CTA-Bühne */
  --blur-glass:         8px;  /* Glass-Badge über Fotos */
  --focus-offset:       3px;

  /* --- Tiefe ----------------------------------------------------------- */
  /* Das System ist fast schattenlos — Trennung entsteht über Fläche und
     Kontrast, nicht über Schlagschatten. Es gibt genau vier Tiefen. */
  --shadow-card:
      0 0.602px 1.566px -1.5px rgba(0, 0, 0, 0.17),
      0 2.289px 5.950px -3px   rgba(0, 0, 0, 0.14),
      0 10px    26px   -4.5px  rgba(0, 0, 0, 0.02);
  --shadow-rail:  0 8px 30px rgba(16, 16, 17, 0.06);   /* aktives Rail-Element */
  --shadow-float: 0 12px 40px rgba(0, 0, 0, 0.45);     /* Dropdown über Dunkel */
  --shadow-phone:
      0 28px 54px -16px rgba(15, 23, 42, 0.34),
      0 10px 22px -12px rgba(15, 23, 42, 0.22),
      inset 0 0 0 1px rgba(255, 255, 255, 0.10),
      inset 0 0 0 2.5px rgba(0, 0, 0, 0.55);           /* iPhone-Gehäuse */
}

@media (max-width: 809.98px) {
  :root {
    --head-chip-gap: 16px;
    --head-sub-gap:  10px;
    --head-body-gap: 48px;
    --container-pad: 20px;
  }
}

/* ======== tokens/motion.css ======== */
/* ============================================================================
   BEWEGUNG
   ----------------------------------------------------------------------------
   Quelle: `__framer__appearAnimationsContent` im Export sowie die
   transition-Deklarationen der Link- und Button-Presets. Beide sagen dasselbe.

   App Land hat genau eine Bewegungsidee: Inhalte steigen leicht auf und werden
   sichtbar. Keine Skalierung, keine Rotation, kein Blur, kein Overshoot.
   Die Kurve ist symmetrisch (0.44/0.56) — sie beschleunigt und bremst gleich
   stark. Das wirkt sachlich statt verspielt und ist Teil der Anmutung.

   HINWEIS ZUR PROJEKTGESCHICHTE: Am 17.08.2026 lief ein „Apple-Design-Pass"
   über das BikePass-Projekt, der auf .65s / cubic-bezier(.22,.61,.21,1) /
   80 ms Stagger / 26 px Weg umgestellt hat. Entscheidung vom 22.08.2026:
   zurück auf die App-Land-Werte. Diese Datei ist der Kanon.
   ========================================================================== */

:root {
  --ease:        cubic-bezier(0.44, 0, 0.56, 1); /* @kind other */
  --dur:         0.45s; /* @kind other */ /* Standard: Reveals, Farb- und Flächenwechsel */
  --dur-fast:    0.3s; /* @kind other */ /* kleine Zustände: Icon, Rail, Hover-Fläche */
  --dur-press:   0.1s; /* @kind other */ /* Press-Feedback, muss unter der Wahrnehmung liegen */

  --reveal-y:      40px;  /* Weg, den ein Element beim Erscheinen zurücklegt */
  --reveal-stagger: 0.1s; /* @kind other */ /* Versatz zwischen Geschwistern */
  --reveal-delay:   0.2s; /* @kind other */ /* Grundverzögerung der ersten Stufe */

  --marquee-dur:    90s; /* @kind other */ /* Ticker, linear, endlos — weiter verlangsamt (Chris 30.08., Runde 8; davor 60s) */
  --press-scale:  0.97; /* @kind other */ /* Buttons */
  --press-scale-sm: 0.94; /* @kind other */ /* Icon-Buttons */
}

/* ----------------------------------------------------------------------------
   Reveal — Elemente erscheinen nie statisch.
   `--reveal-i` vergibt das aufrufende Skript pro Geschwisterkind (0,1,2,…).
   Die Regeln greifen nur mit `.js` am <html>, damit ohne JavaScript nichts
   unsichtbar bleibt.
   -------------------------------------------------------------------------- */
.js [data-reveal],
.js [data-reveal-group] > * {
  opacity: 0.001;
  transform: translateY(var(--reveal-y));
  transition:
    opacity   var(--dur) var(--ease),
    transform var(--dur) var(--ease);
  transition-delay: calc(var(--reveal-i, 0) * var(--reveal-stagger));
}

.js [data-reveal].revealed,
.js [data-reveal-group].revealed > * {
  opacity: 1;
  transform: none;
}

:root {
  --dur-wash-a: 18s;  /* Hero-Wash, untere Blob-Ebene */
  --dur-wash-b: 24s;  /* Hero-Wash, obere Blob-Ebene */
  --dur-float:   8s;  /* Schwebe-Loop PageHero-Dekor, Slot tl (live: je Slot eigene Dauer) */
  --dur-float-b: 10s; /* Slot tr */
  --dur-float-c: 9s;  /* Slot br-lg */
  --dur-float-d: 12s; /* Slot bl */
  --dur-pulse:   2.4s; /* E34 — Puls des Lager-Punkts (Live-Kanon der Buybox) */
}

/* ----------------------------------------------------------------------------
   Press — Rückmeldung auf pointer-down, nicht erst beim Loslassen.
   Nur transform, damit die GPU es allein erledigt.
   -------------------------------------------------------------------------- */
[data-press] {
  transition-property: color, background-color, transform;
  transition-duration: var(--dur-fast);
  transition-timing-function: var(--ease);
}
[data-press]:active           { transform: scale(var(--press-scale));    transition-duration: var(--dur-press); }
[data-press="sm"]:active      { transform: scale(var(--press-scale-sm)); transition-duration: var(--dur-press); }

/* ----------------------------------------------------------------------------
   Fokus — sichtbar auf hellen wie auf dunklen Flächen.
   -------------------------------------------------------------------------- */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  /* Kein border-radius hier: Die Outline folgt dem Radius des Elements von
     selbst. Der frühere 4px-Wert bog beim Fokussieren den Element-Radius um
     (Pill wurde zur 4px-Ecke) und erzwang Reparatur-Overrides in den
     Komponenten — beide entfernt (Bereinigung 2026-08-29). */
}

/* ----------------------------------------------------------------------------
   Bewegungsreduktion — Crossfade statt Weg, kein Autoscroll.
   Nicht optional: das System bewegt sich sonst dauerhaft (Ticker, Wash).
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal],
  .js [data-reveal-group] > * {
    transform: none;
    transition: opacity var(--dur-fast) ease;
    transition-delay: 0ms;
  }
  [data-press]:active,
  [data-press="sm"]:active { transform: none; }
  /* html-Präfix: (0,1,1) schlägt die !important-Longhands der Marquee-Härtung
     in der Komponenten-Schicht (0,1,0) — reduced-motion gewinnt immer. */
  html [data-marquee] > * { animation: none !important; }
  [data-wash]::before,
  [data-wash]::after { animation: none !important; }
  /* Komponenten mit eigenem Press-/Hover-Transform (bereinigt 2026-08-29) */
  .bp-btn:active,
  .bp-btn-icon:active,
  .bp-social-item:active,
  .bp-video-btn:active,
  .bp-accordion__summary:active .bp-accordion__icon,
  .bp-card--measure:hover { transform: none; }
  .bp-btn:hover .bp-btn__icon i { animation: none; }
  .bp-page-hero__obj { animation: none !important; }
}

/* ======== tokens/base.css ======== */
/* ============================================================================
   BASIS — Reset und Grundeinstellungen
   ----------------------------------------------------------------------------
   Bewusst kurz. Das System braucht keinen großen Reset, weil es fast alles
   über Komponentenklassen setzt.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: var(--text-base);
  line-height: var(--copy-lh);
  font-feature-settings: var(--font-features);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* height:auto lässt width/height-Attribute (CLS-Schutz) im Markup zu,
   ohne dass sie das fluide Layout festnageln. */
img, svg, video { display: block; max-width: 100%; height: auto; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }

/* Überschriften-Tags erben die Display-Schrift, tragen aber keine Größe.
   Die Größe kommt immer aus einer .t-*-Klasse — sonst driften Tag-Semantik
   und optische Ebene auseinander. Genau das macht App Land auch so:
   ein <h2> kann optisch H2, H2-SM oder H5 sein. */
h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--font-display);
  font-feature-settings: var(--font-features);
  letter-spacing: var(--display-ls);
  line-height: var(--display-lh);
  /* Fallback für klassenlose Headings: opsz-Pflicht + kein UA-Faux-Bold */
  font-weight: 400;
  font-variation-settings: "opsz" 16;
}

p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
/* Der Browser gibt figure und blockquote einen Rand von 14px/40px — ohne
   diesen Reset schiebt jede Stimmen-Karte ihr Raster um 40 px nach rechts. */
figure, blockquote, dl, dd { margin: 0; }

/* Layout-Hilfen, die das System überall braucht */
.bp-container {
  width: 100%;
  max-width: var(--container-outer);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.bp-measure { max-width: var(--measure); }

.bp-visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ======== components/component-styles.css ======== */
/* ============================================================================
   KOMPONENTEN-SCHICHT
   ----------------------------------------------------------------------------
   Wert-Literale (Farbe, Typo, Radius, Dauer) sind hier verboten — das hält
   `tools/ds-guard.py` auf Baseline 0 (der oxlint prüft nur JSX). Erlaubt und
   als solche kommentiert sind ausschließlich GEOMETRIE-Konstanten gemessener
   Bauteile: Dekor-Slot-Breiten des PageHero, Phone-Fächer-Proportionen und
   Interaktions-Transforms (2px-Icon-Shift, scale 0.9).

   Reihenfolge: Aktionen · Labels · Karten · Aufklappen · Navigation · Layout
   ========================================================================== */

/* ============================================================================
   1 — AKTIONEN
   ----------------------------------------------------------------------------
   App-Land-Anatomie: Pill mit Label und einem Icon-Kreis rechts, der flächen-
   bündig im Innenabstand sitzt. Der Kreis ist nie ein nacktes Icon.
   ========================================================================== */

/* Metriken 1:1 der Live-.bp-jr-link (E18, Chris 29.08.): 48px Höhe,
   Label-Gewicht 600, Gap 10, Icon 32px rechts bündig, Hover hebt 1px. */
.bp-btn {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  min-height: var(--pill-height);
  padding: var(--pill-pad);
  border-radius: var(--radius-button);
  background: var(--button-bg);
  color: var(--button-fg);
  font-family: var(--font-sans);
  font-size: var(--text-btn);
  font-weight: var(--btn-wght);
  /* v2.60.0 (Chris 31.08.): lange Labels brechen um statt über den Viewport zu
     ragen — white-space normal + eigene Zeilenhöhe (control-lh 1 wäre mehrzeilig
     zu eng) + max-width als Container-Deckel. Einzeilige Buttons bleiben durch
     min-height unverändert 48px; das Icon-Quadrat behält flex-shrink: 0. */
  line-height: var(--control-multiline-lh);
  white-space: normal;
  max-width: 100%;
  transition-property: color, transform;
  transition-duration: var(--dur);
  transition-timing-function: var(--ease);
}
/* E18-Hover „Pfeil-Durchlauf" (Chris-Wahl 30.08., ersetzt die Welle):
   Flächen, Farben und Label bleiben völlig ruhig — im Quadrat schießt der
   Pfeil (als <i> markiert) nach rechts hinaus und kommt von links nach. */
.bp-btn__icon { overflow: hidden; }
.bp-btn__icon i { font-style: normal; display: block; }
.bp-btn:hover .bp-btn__icon i { animation: bp-arrow-swap var(--dur) var(--ease); }
@keyframes bp-arrow-swap {
  0%   { transform: translateX(0);     opacity: 1; }
  45%  { transform: translateX(140%);  opacity: 0; }
  50%  { transform: translateX(-140%); opacity: 0; }
  100% { transform: translateX(0);     opacity: 1; }
}
.bp-btn:active { transform: scale(var(--press-scale)); transition-duration: var(--dur-press); }

.bp-btn__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: var(--pill-icon);
  height: var(--pill-icon);
  border-radius: var(--radius-button);
  background: var(--button-icon-bg);
  color: var(--ink); /* Pfeilfarbe ist fest — erbt NICHT den Label-Umklapp der Hover-Welle */
  transition: transform var(--dur-fast) var(--ease);
}


.bp-btn--light { background: var(--button-light-bg); color: var(--button-light-fg); }
/* Heller Button: Ink-Quadrat mit Paper-Pfeil (deckend — auf Weiß wäre das
   weiße Quadrat unsichtbar). Welle = Default (Ink). */
.bp-btn--light .bp-btn__icon { background: var(--ink); color: var(--paper); }

.bp-btn--dark  { background: var(--button-dark-bg); color: var(--button-dark-fg); }
.bp-btn--dark .bp-btn__icon { background: var(--button-dark-icon-bg); color: var(--ink); }

/* E18-Nachfass (Chris 30.08.): KEINE Kleinvariante mehr — alle Buttons laufen
   in den jr-link-Metriken. --sm bleibt als toleranter Alias ohne Wirkung. */
.bp-btn--sm { min-height: var(--pill-height); }

.bp-btn--block { display: flex; width: 100%; justify-content: center; }

/* Icon-Button ohne Label — quadratisch, immer mit Beschriftung für Screenreader */
.bp-btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--pill-height);
  height: var(--pill-height);
  border-radius: var(--radius-circle);
  background: var(--color-surface);
  color: var(--color-text);
  border: var(--border-w) solid var(--color-border);
  transition-property: background-color, color, transform;
  transition-duration: var(--dur-fast);
  transition-timing-function: var(--ease);
}
.bp-btn-icon:hover  { background: var(--color-surface-hover); }
.bp-btn-icon:active { transform: scale(var(--press-scale-sm)); transition-duration: var(--dur-press); }
.bp-btn-icon--white { background: var(--color-surface); border-color: transparent; }
.bp-btn-icon--ghost { background: transparent; border-color: var(--color-border); }

/* Nav-Link als Pill — Hover legt eine Fläche unter, kein Unterstrich */
.bp-nav-link {
  display: inline-flex;
  align-items: center;
  padding: var(--nav-link-pad);
  border-radius: var(--radius-pill);
  color: var(--nav-link-fg);
  font-size: var(--text-base);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.bp-nav-link:hover,
.bp-nav-link[aria-current="page"] { background: var(--nav-link-bg-hover); }

/* Deaktiviert — ein Zustand, überall gleich. Bei Links gilt zusätzlich die
   Tastatur-Regel: aria-disabled braucht tabindex="-1", sonst navigiert Enter
   trotz pointer-events:none (Lesson 2026-08-29). */
.bp-btn:disabled,
.bp-btn[aria-disabled="true"],
.bp-btn-icon:disabled,
.bp-btn-icon[aria-disabled="true"],
.bp-form-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

/* Formular-Button mit Zustand */
.bp-form-btn[data-state="loading"] { opacity: 0.6; pointer-events: none; }
.bp-form-btn[data-state="sent"]    { background: var(--teal-deep); color: var(--paper); }

/* Newsletter: Feld und Button in einer Fläche */
.bp-subscribe {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3);
  padding-left: var(--space-8);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
}
.bp-subscribe__input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: none;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: var(--copy-wght);
  color: var(--color-text);
}
.bp-subscribe__input::placeholder { color: var(--color-text-subtle); }
.bp-subscribe__input:focus { outline: none; }
.bp-subscribe:focus-within { outline: 2px solid var(--color-focus); outline-offset: var(--focus-offset); }

/* Play/Pause über einem Video */
.bp-video-btn {
  width: var(--size-play); height: var(--size-play);
  border-radius: var(--radius-circle);
  background: var(--color-surface);
  color: var(--color-text);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-card);
  transition: transform var(--dur-fast) var(--ease);
}
.bp-video-btn:active { transform: scale(var(--press-scale-sm)); transition-duration: var(--dur-press); }

/* ============================================================================
   2 — LABELS
   ========================================================================== */

/* Section-Chip: outline-Pill, steht immer über der H2 */
.bp-chip {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  padding: var(--space-3) var(--space-6);
  border: var(--border-w) solid var(--chip-border);
  border-radius: var(--radius-pill);
  background: var(--chip-bg);
  color: var(--chip-fg);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--copy-wght);
  line-height: var(--xs-lh);
}
.bp-chip--accent { border-color: transparent; background: var(--color-surface-accent); color: var(--teal-deep); }

/* Badge: gefüllte Kleinstfläche */
.bp-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-pill);
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  font-weight: var(--copy-wght);
  line-height: var(--xs-lh);
  background: var(--color-surface-sunken);
  color: var(--color-text);
}
.bp-badge--ink    { background: var(--color-surface-inverse); color: var(--color-text-inverse); }
.bp-badge--accent { background: var(--color-accent); color: var(--color-accent-contrast); }
/* Glass nur über Flächen, die bereits per scrim/veil abgedunkelt sind —
   die Glasfläche selbst garantiert keinen Textkontrast. */
.bp-badge--glass  { background: var(--white-15); color: var(--paper); backdrop-filter: blur(var(--blur-glass)); }

/* Icon-Kreis der Feature- und Methoden-Karten: 48 px, zarte Akzentfläche,
   Icon in Teal-deep mit 1,8er-Strich. Auf Ink-Karten kippt er automatisch mit. */
.bp-feature-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: var(--size-feature-icon);
  height: var(--size-feature-icon);
  border-radius: var(--radius-circle);
  background: var(--color-surface-accent);
  color: var(--teal-deep);
}
[data-tone="ink"] .bp-feature-icon { background: var(--white-10); color: var(--color-accent); }

/* Blog-Badge: Datum und Rubrik als zusammenhängendes Paar */
.bp-blog-badge { display: inline-flex; align-items: center; gap: var(--space-4); }
.bp-blog-badge__date { color: var(--color-text-subtle); font-size: var(--text-xs); line-height: var(--xs-lh); }

/* Aufzählungspunkt mit Icon-Kreis */
.bp-bullet { display: flex; align-items: flex-start; gap: var(--space-5); }
.bp-bullet__icon {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--size-icon); height: var(--size-icon);
  border-radius: var(--radius-circle);
  background: var(--color-surface-accent);
  color: var(--teal-deep);
}
.bp-bullet--ink .bp-bullet__icon { background: var(--white-10); color: var(--color-accent); }

.bp-avatar {
  display: block;
  width: var(--size-avatar); height: var(--size-avatar);
  border-radius: var(--radius-circle);
  object-fit: cover;
  background: var(--color-surface-sunken);
}
.bp-avatar--sm { width: var(--size-avatar-sm); height: var(--size-avatar-sm); }
.bp-avatar--lg { width: var(--size-avatar-lg); height: var(--size-avatar-lg); }

.bp-avatar-stack { display: flex; }
.bp-avatar-stack > .bp-avatar + .bp-avatar { margin-left: var(--size-avatar-lap); }
.bp-avatar-stack > .bp-avatar { border: var(--border-w-strong) solid var(--color-surface); }

.bp-social-item {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--size-social); height: var(--size-social);
  border-radius: var(--radius-circle);
  border: var(--border-w) solid var(--color-border);
  color: var(--color-text);
  transition-property: background-color, color, transform;
  transition-duration: var(--dur-fast);
  transition-timing-function: var(--ease);
}
.bp-social-item:hover  { background: var(--color-surface-hover); }
.bp-social-item:active { transform: scale(var(--press-scale-sm)); transition-duration: var(--dur-press); }

/* ============================================================================
   3 — KARTEN
   ----------------------------------------------------------------------------
   Eine Karte ist im Kern immer dasselbe: 30 px Radius, 30 px Padding, weiße
   Fläche. Die Ink-Variante ist keine Dekoration — sie markiert im BikePass-
   Kontext, was von BikePass selbst kommt.
   ========================================================================== */

.bp-card {
  display: flex;
  flex-direction: column;
  padding: var(--card-pad);
  border-radius: var(--radius-card);
  background: var(--card-bg);
  color: var(--card-fg);
}
.bp-card--sunken { background: var(--color-surface-sunken); gap: var(--space-8); } /* E10: Inhaltskarten laufen im 20er-Gap */
.bp-card--ink    { background: var(--card-inverse-bg); color: var(--card-inverse-fg); }
.bp-card--sm     { border-radius: var(--radius-card-sm); }
.bp-card--flat   { padding: 0; overflow: hidden; }
.bp-card--raised { box-shadow: var(--shadow-card); }

.bp-card__body  { display: flex; flex-direction: column; gap: var(--space-4); }
.bp-card__media { border-radius: var(--radius-card-sm); overflow: hidden; }
.bp-card__media > img { width: 100%; height: 100%; object-fit: cover; }

/* Bento-Feature-Karte: Medium oben, Text unten */
.bp-feature-card { gap: var(--space-8); }
.bp-feature-card--about { flex-direction: row; align-items: center; gap: var(--space-10); }
@media (max-width: 809.98px) { .bp-feature-card--about { flex-direction: column; align-items: flex-start; } }

/* Zähler: die Wirkung kommt aus Raveo und der Fläche, nicht aus der Größe */
.bp-counter-card__value { font-family: var(--font-display); font-size: var(--text-h3); font-weight: var(--text-h3-wght); font-variation-settings: "opsz" 16, "wght" var(--text-h3-wght); line-height: var(--display-lh); letter-spacing: var(--display-ls); }

/* Schritt-Karte mit vorangestellter Nummer */
.bp-step-card__number {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  line-height: var(--xs-lh);
  color: var(--color-text-subtle);
  letter-spacing: 0;
}

/* Roadmap-Rail: aktives Element hebt sich über Fläche und Schatten ab */
.bp-roadmap-item {
  display: flex; align-items: center; gap: var(--space-5);
  padding: var(--space-4) var(--space-6);
  border-radius: var(--radius-card-sm);
  transition: background-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.bp-roadmap-item.is-active { background: var(--color-surface); box-shadow: var(--shadow-rail); }
.bp-roadmap-item__num {
  display: flex; align-items: center; justify-content: center;
  flex: 0 0 auto; width: var(--size-roadmap-num); height: var(--size-roadmap-num);
  border-radius: var(--radius-circle);
  background: var(--ink-10);
  color: var(--color-text);
  font-size: var(--text-btn);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.bp-roadmap-item.is-active .bp-roadmap-item__num { background: var(--color-surface-inverse); color: var(--color-text-inverse); }

/* Blog-Karte: Bild randlos, Text im Innenabstand */
.bp-blog-card { padding: 0; overflow: hidden; }
.bp-blog-card__media { aspect-ratio: var(--ratio-photo); }
.bp-blog-card__body  { padding: var(--card-pad); gap: var(--space-4); }

.bp-team-card__photo { aspect-ratio: var(--ratio-portrait); border-radius: var(--radius-card-sm); overflow: hidden; }

.bp-client-card {
  display: flex; align-items: center; justify-content: center;
  min-height: var(--size-logo-tile); padding: var(--space-8) var(--space-10);
  color: var(--color-text-subtle);
}

.bp-contact-card { gap: var(--space-4); }

/* Im Marquee braucht die Karte eine feste Breite und darf nicht schrumpfen;
   in einer Rasterzelle füllt sie die Zelle und deckelt bei 380 px. */
.bp-testimonial-card { gap: var(--space-8); width: 100%; max-width: var(--size-testimonial); }
[data-marquee] .bp-testimonial-card { flex: 0 0 auto; width: var(--size-testimonial); }
.bp-testimonial-card__foot { display: flex; align-items: center; gap: var(--space-5); }

/* Vergleichstabelle — App-Land-Muster „Compare Plan".
   Behält unterhalb lg die Spaltenachse und scrollt horizontal. */
.bp-compare { width: 100%; overflow-x: auto; }
.bp-compare table { width: 100%; border-collapse: collapse; min-width: var(--size-compare-min); }
.bp-compare th, .bp-compare td {
  padding: var(--space-6) var(--space-8);
  text-align: left;
  border-bottom: var(--border-w) solid var(--color-border);
  font-size: var(--text-base);
}
.bp-compare thead th { font-family: var(--font-display); font-size: var(--text-h6); font-weight: var(--text-h6-wght); font-variation-settings: "opsz" 16, "wght" var(--text-h6-wght); letter-spacing: var(--display-ls); line-height: var(--display-lh); }
@media (max-width: 1023.98px) {
  .bp-compare {
    -webkit-mask-image: linear-gradient(to right, var(--mask) 0, var(--mask) 90%, transparent 100%);
            mask-image: linear-gradient(to right, var(--mask) 0, var(--mask) 90%, transparent 100%);
  }
}

/* ============================================================================
   4 — AUFKLAPPEN
   ----------------------------------------------------------------------------
   Auf <details>/<summary> gebaut: funktioniert ohne JavaScript, ist tastatur-
   bedienbar und für Screenreader korrekt. Die Höhenanimation ist progressive
   Verbesserung — ältere Browser schalten hart.
   ========================================================================== */

.bp-accordion { display: flex; flex-direction: column; gap: var(--space-4); }

.bp-accordion__item {
  /* Bewusst 20/30 statt Karten-Padding 30: die FAQ-Zeile ist eine Zeile,
     keine Karte — vertikal dichter, horizontal im Karten-Raster. */
  border: var(--border-w) solid var(--accordion-border);
  border-radius: var(--radius-card-sm);
  background: var(--color-surface);
  padding: var(--space-8) var(--space-10);
}
.bp-accordion__summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-8);
  list-style: none; cursor: pointer;
}
.bp-accordion__summary::-webkit-details-marker { display: none; }

.bp-accordion__icon {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--size-accordion); height: var(--size-accordion);
  border-radius: var(--radius-circle);
  background: var(--accordion-icon-bg);
  transition: transform var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.bp-accordion__icon::before { content: "+"; font-size: var(--text-lead); line-height: var(--control-lh); }
.bp-accordion__item[open] .bp-accordion__icon::before { content: "×"; }
.bp-accordion__summary:active .bp-accordion__icon { transform: scale(0.9); transition-duration: var(--dur-press); }

.bp-accordion__panel { padding-top: var(--space-8); color: var(--color-text-muted); }

@supports (interpolate-size: allow-keywords) {
  :root { interpolate-size: allow-keywords; }
  .bp-accordion__item::details-content {
    block-size: 0;
    overflow: clip;
    transition: block-size var(--dur) var(--ease), content-visibility var(--dur) allow-discrete;
  }
  .bp-accordion__item[open]::details-content { block-size: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .bp-accordion__item::details-content { transition: none; }
}

/* Home-Variante: ohne Rahmen, nur Trennlinien */
.bp-accordion--home .bp-accordion__item {
  border: 0; border-bottom: var(--border-w) solid var(--accordion-border);
  border-radius: 0; background: none; padding-inline: 0;
}

/* ============================================================================
   5 — NAVIGATION
   ========================================================================== */

.bp-nav {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-8);
  height: var(--nav-height);
}
.bp-nav__links { display: flex; align-items: center; gap: var(--space-2); }
@media (max-width: 1023.98px) { .bp-nav__links { display: none; } }

.bp-brand-logo { display: inline-flex; align-items: center; }
.bp-brand-logo img { height: var(--size-logo); width: auto; }
.bp-brand-logo--footer img { height: var(--size-logo-footer); }

.bp-dropdown { position: relative; }
.bp-dropdown__panel {
  position: absolute; top: calc(100% + var(--space-4)); left: 0;
  min-width: var(--dropdown-min); padding: var(--space-4);
  border-radius: var(--radius-tile);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.bp-dropdown__link {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-chip);
  transition: background-color var(--dur-fast) var(--ease);
}
.bp-dropdown__link:hover { background: var(--color-surface-hover); }

.bp-footer {
  padding-block: var(--section-pad);
  /* Das Wasserzeichen ist breiter als der Viewport — der Fuß beschneidet es.
     Ohne diese Zeile erzeugt es auf Mobil horizontalen Seiten-Scroll. */
  overflow: hidden;
}
.bp-footer__cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-12); }
@media (max-width: 809.98px) { .bp-footer__cols { grid-template-columns: repeat(2, 1fr); gap: var(--space-10); } }

/* Wortmarke als Wasserzeichen — die 220-px-Ebene des Systems */
.bp-footer__watermark {
  white-space: nowrap;
  text-align: center;
  font-family: var(--font-display);
  font-size: var(--text-mega);
  font-weight: var(--text-mega-wght);
  font-variation-settings: "opsz" 16, "wght" var(--text-mega-wght);
  line-height: var(--mega-lh);
  letter-spacing: 0;
  color: var(--color-text);
  opacity: 0.08;
  user-select: none;
}

/* ============================================================================
   6 — LAYOUT
   ========================================================================== */

.bp-section { padding-block: var(--section-pad); }
.bp-section--solo   { padding-block: var(--section-pad-solo); }
.bp-section--sunken { background: var(--color-surface-sunken); }
.bp-section--ink    { background: var(--color-surface-inverse); color: var(--color-text-inverse); }

/* Kopf-Kette — überall identisch: 26 / 20 / 80 (Desktop), 16 / 10 / 48 (Mobil).
   Die Abstände sind hier festgeschrieben, damit sie nicht jede Sektion neu
   erfindet. Entscheid 9 (Chris 29.08.): Sektionsköpfe stehen MITTIG — das ist
   der Default. Linksbündig nur in Split-Intros (Kopf neben Bild) via --left. */
.bp-section__head { display: flex; flex-direction: column; align-items: center; text-align: center; }
/* E9-Nachfass (Chris 30.08.): Headlines bekommen ein Zeilenmaß — sie liefen
   auf breiten Containern ungebremst durch. */
.bp-section__head > h2, .bp-section__head > h3 { max-width: var(--measure-head); text-wrap: balance; }
/* Sub-Abstand greift auch, wenn nur die Typo-Klasse gesetzt ist (p reicht);
   die Chip-Regel steht danach und gewinnt im Chip+Sub-Randfall (26 statt 20). */
.bp-section__head > * + .bp-section__sub,
.bp-section__head > * + p { margin-top: var(--head-sub-gap); }
.bp-section__head > .bp-chip + * { margin-top: var(--head-chip-gap); }
.bp-section__head + * { margin-top: var(--head-body-gap); }
.bp-section__head--center { align-items: center; text-align: center; } /* Alias, seit E9 Default */
.bp-section__head--left { align-items: flex-start; text-align: left; }

.bp-grid { display: grid; gap: var(--grid-gap); }
.bp-grid--2 { grid-template-columns: repeat(2, 1fr); }
.bp-grid--3 { grid-template-columns: repeat(3, 1fr); }
.bp-grid--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1023.98px) { .bp-grid--3, .bp-grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 809.98px)  { .bp-grid--2, .bp-grid--3, .bp-grid--4 { grid-template-columns: 1fr; } }

/* Bildrahmen mit den drei Overlay-Ebenen des Systems */
.bp-media-frame { position: relative; border-radius: var(--radius-card); overflow: hidden; }
.bp-media-frame > img,
.bp-media-frame > video { width: 100%; height: 100%; object-fit: cover; }
.bp-media-frame[data-overlay="scrim"]::after,
.bp-media-frame[data-overlay="veil"]::after {
  content: ""; position: absolute; inset: 0;
}
.bp-media-frame[data-overlay="scrim"]::after { background: var(--color-scrim); }
.bp-media-frame[data-overlay="veil"]::after  { background: var(--color-veil); opacity: 0.8; }

/* Hero-Wash — die Teal-Besetzung des GradientWave-Slots aus dem Template.
   Zwei driftende Blob-Ebenen, stark geblurrt. Kein WebGL. */
[data-wash] { position: relative; overflow: hidden; }
[data-wash]::before,
[data-wash]::after {
  content: ""; position: absolute; inset: -12%;
  filter: blur(var(--blur-wash)) saturate(1.3);
  will-change: transform;
  pointer-events: none;
}
[data-wash]::before {
  background:
    radial-gradient(46% 60% at 10% 94%, var(--wash-deep-a), transparent 68%),
    radial-gradient(52% 66% at 90% 52%, var(--wash-teal-a), transparent 68%),
    radial-gradient(36% 46% at 60% 108%, var(--wash-hover), transparent 66%),
    radial-gradient(34% 46% at 22% -8%, var(--wash-deep-b), transparent 68%),
    linear-gradient(115deg, var(--wash-base-1), var(--wash-base-2) 55%, var(--wash-base-3));
  animation: wash-a var(--dur-wash-a) ease-in-out infinite alternate;
}
[data-wash]::after {
  background:
    radial-gradient(26% 36% at 86% 46%, var(--wash-glow), transparent 60%),
    radial-gradient(18% 26% at 68% 86%, var(--wash-teal-b), transparent 60%);
  mix-blend-mode: screen;
  animation: wash-b var(--dur-wash-b) ease-in-out infinite alternate;
}
@keyframes wash-a { from { transform: translate(-3%, 2%) scale(1); }        to { transform: translate(4%, -3%) scale(1.12); } }
@keyframes wash-b { from { transform: translate(3%, -2%) scale(1.08) rotate(2deg); } to { transform: translate(-4%, 3%) scale(1) rotate(-2deg); } }

/* Endlosbewegung (Marquee, Wash, Hero-Float): Hover/Fokus pausiert das
   Marquee, prefers-reduced-motion stoppt alles. data-motion="paused" auf
   einem Vorfahren friert zusätzlich alle drei ein — der Mechanismus bleibt
   als System-Feature; die frühere Schalter-Pflicht pro Seite ist
   aufgehoben (Chris, Runde 8, 30.08.2026). */
[data-motion="paused"] [data-marquee] > *,
[data-motion="paused"] [data-wash]::before,
[data-motion="paused"] [data-wash]::after,
[data-motion="paused"] .bp-page-hero__obj { animation-play-state: paused !important; }

/* Ticker / Marquee — Kantenmaske statt harter Schnitt, Pause bei Hover */
[data-marquee] {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, var(--mask) 12%, var(--mask) 88%, transparent);
          mask-image: linear-gradient(to right, transparent, var(--mask) 12%, var(--mask) 88%, transparent);
}
[data-marquee] > * {
  display: flex;
  gap: var(--marquee-gap);
  width: max-content;
  /* v2.61.0-Härtung, zwei dokumentierte Fallen:
     (1) Elementor/uicore setzen global `animation: .4s` auf Inhaltselemente und
         nullen damit den Namen (home.css-Lesson v1.0.3) — die Longhands tragen
         deshalb !important; play-state bleibt frei (Hover-Pause + data-motion).
     (2) iOS/WebKit malte Reihe 1 (direction: normal) teils gar nicht: der
         implizite from-Frame startet auf transform:none, der maskierte Layer
         wird erst mit Verzug composited. Expliziter from + will-change seeden
         den Layer ab dem ersten Frame; reverse (Reihe 2) war nie betroffen. */
  animation-name: marquee !important;
  animation-duration: var(--marquee-dur) !important;
  animation-timing-function: linear !important;
  animation-iteration-count: infinite !important;
  will-change: transform;
}
[data-marquee="reverse"] > * { animation-direction: reverse !important; }
[data-marquee]:hover > *,
[data-marquee]:focus-within > * { animation-play-state: paused; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* Finale CTA-Bühne */
.bp-cta-scene {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-card);
  background:
    radial-gradient(60% 80% at 20% 20%, var(--scene-glow-1), transparent 70%),
    radial-gradient(50% 70% at 85% 75%, var(--scene-glow-2), transparent 72%),
    linear-gradient(160deg, var(--scene-1), var(--scene-2) 55%, var(--scene-3));
  color: var(--color-text-inverse);
}
.bp-cta-scene__video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; transform: scale(1.12);
  filter: blur(var(--blur-scene)) saturate(1.2) brightness(0.55);
}
/* Weiß-Text lag ungesichert auf den hellsten Stellen der Teal-Radiale —
   dieselbe Scrim-Pflicht wie beim Hero (bereinigt 2026-08-29). */
.bp-cta-scene::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--color-scrim);
  pointer-events: none;
}
.bp-cta-scene > * { position: relative; z-index: 1; }

/* 3-iPhone-Fächer der finalen Bühne */
.bp-phone-fan { display: flex; justify-content: center; align-items: center; --pw: clamp(var(--phone-w-min), 20vw, var(--phone-w-max)); /* @kind spacing */ }
.bp-phone-fan > * { flex: 0 0 auto; width: var(--pw); }
.bp-phone-fan__c { z-index: 3; transform: scale(1.05); }
.bp-phone-fan__l { z-index: 1; transform: rotate(-8deg) translateY(4%); margin-right: calc(var(--pw) * -0.24); filter: brightness(0.96); }
.bp-phone-fan__r { z-index: 1; transform: rotate(8deg)  translateY(4%); margin-left:  calc(var(--pw) * -0.24); filter: brightness(0.96); }
@media (max-width: 767.98px) { .bp-phone-fan { --pw: clamp(118px, 31vw, 165px); /* @kind spacing */ } }

.bp-phone {
  position: relative;
  width: var(--pw, var(--phone-w-max));
  padding: calc(var(--pw, var(--phone-w-max)) * 0.038);
  border-radius: calc(var(--pw, var(--phone-w-max)) * 0.168);
  background: linear-gradient(150deg, var(--phone-shell-1) 0%, var(--phone-shell-2) 34%, var(--phone-shell-3) 100%);
  box-shadow: var(--shadow-phone);
}
.bp-phone__screen { position: relative; overflow: hidden; border-radius: calc(var(--pw, var(--phone-w-max)) * 0.135); }

/* --- Nachträge: Bauteile, die aus den Primitives referenziert werden ------ */

.bp-nav__actions { display: flex; align-items: center; gap: var(--space-4); }
.bp-nav__burger  { display: none; }
@media (max-width: 1023.98px) { .bp-nav__burger { display: inline-flex; } }

/* Subline im Section-Kopf — nur ein Haken für die Abstandskette, kein eigener Stil */
.bp-section__sub { max-width: var(--measure); font-size: var(--text-section-sub); text-wrap: pretty; } /* v2.62.1 (Chris): eigene Sub-Größe 16→19.2, schlägt die bp-t-lg-Markup-Klasse per Kaskadenposition */

/* Fußzeile: innerer Rhythmus */
.bp-footer .bp-container { display: flex; flex-direction: column; gap: var(--space-12); }
.bp-footer nav h2 { color: var(--color-text-subtle); margin-bottom: var(--space-6); }
.bp-footer nav li + li { margin-top: var(--space-4); }
.bp-footer nav a { color: var(--color-text-muted); transition: color var(--dur) var(--ease); }
.bp-footer nav a:hover { color: var(--color-text); }

/* Finale Bühne: innerer Abstand und Stapelung über dem Video */
.bp-cta-scene .bp-container {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
  text-align: center;
  padding-block: var(--section-pad);
}

/* --- Dokumentseite: Sprungmarken neben Fließtext --------------------------
   Für Rechtstexte und lange Erklärseiten. Unterhalb 810 px stapelt es und
   das Inhaltsverzeichnis verliert seine Klebrigkeit — sonst frisst es auf
   Mobil den halben Bildschirm. */
.bp-doc {
  display: grid;
  grid-template-columns: var(--toc-width) 1fr;
  gap: var(--space-20);
  align-items: start;
}
.bp-doc__toc { position: sticky; top: var(--space-8); }
.bp-doc__toc a { display: block; color: var(--color-text-muted); transition: color var(--dur-fast) var(--ease); }
.bp-doc__toc a:hover { color: var(--color-text); }
@media (max-width: 809.98px) {
  .bp-doc { grid-template-columns: 1fr; gap: var(--space-12); }
  .bp-doc__toc { position: static; }
}

/* --- Hero-Scrim -----------------------------------------------------------
   Textblöcke über Fotos brauchen eine Abdunklung, sonst verliert die Copy auf
   unruhigen Bildern den Kontrast — auf Mobil zuerst. Der Verlauf ist unten
   dicht und oben offen, damit das Motiv sichtbar bleibt. */
.bp-hero-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* Durchgehend, nicht als Verlauf: das Original legt eine Ink-55-%-Ebene über
     das gesamte Titelbild. Ein Verlauf ist genau dort dünn, wo das Motiv am
     unruhigsten ist — und die Copy wird auf Mobil unlesbar. */
  background: var(--color-hero-veil);
}

/* --- Zahlarten: einfarbige Wortmarken statt bunter Badges --------------------
   Haus-Kanon (Projekt-Entscheid v0.4.0): Zahlungsarten laufen als gedämpfte
   Wortmarken-Textur, nie als farbige Logos — die Aufmerksamkeit gehört dem
   Preis daneben, nicht den Kartenmarken. */
.bp-pay-mono {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4) var(--space-8);
}
.bp-pay-mono > * {
  display: inline-flex;
  align-items: center;
  height: var(--size-pay-logo);
  font-family: var(--font-sans);
  font-weight: var(--strong-wght);
  font-size: var(--text-xs);
  letter-spacing: 0; /* Switzer läuft trackinglos — der frühere em-Wert war der einzige em im System */
  line-height: var(--control-lh);
}

/* ============================================================================
   7 — BIKEPASS-SEKTIONEN
   ----------------------------------------------------------------------------
   Drei Bausteine, die 2026-08-29 aus dem laufenden bikepass.eu-Refactoring in
   dieses System übernommen wurden. Sie sind DEFINIERT (Chris) und werden hier
   nur systematisiert, nicht neu gestaltet.
   ========================================================================== */

/* --- PageHero — der Seiteneinstieg aller Unterseiten -----------------------
   1:1 der Live-EBD-Hero (bikepass.eu/e-bike-diebstahlschutz, nachgemessen
   29.08.2026, E13c-Umbau 30.08.): Teal-Verlaufsbühne mit Rand-Vignette,
   Split-Anatomie — Copy links, rechts die __stage mit dem Objekt-Ensemble
   (top/main/bottom, von oben nach unten drapiert, ohne Anschnitt). Unter
   1000 px zentrierter Content, Objekte auf einer Linie mit Rand-Anschnitt.
   H1 immer Bebas, seit E13c in 700. */
.bp-page-hero {
  margin-top: 10px; /* Chris 31.08.: Luft zum Header auf allen Heroes */
  position: relative;
  overflow: hidden;
  padding-block: var(--page-hero-pad);
  border-radius: var(--radius-card);
  background: var(--hero-surface); /* E13d: flache helle Studio-Bühne (der Teal-Verlauf E13/E21 ist Geschichte) */
  color: var(--color-text);
  text-align: left; /* E13c: Split-Hero — Copy linksbündig, mobil zentriert (MQ unten) */
}
.bp-page-hero__fx {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: none; /* E13d: auf der hellen Bühne keine Teal-Vignette/kein Glow — der Hook bleibt im Markup */
}
.bp-page-hero__obj {
  position: absolute;
  height: auto;
  will-change: transform;
  filter: drop-shadow(0 18px 32px var(--hero-obj-shadow));
  animation: bp-hero-float var(--dur-float) ease-in-out infinite alternate;
}
@keyframes bp-hero-float {
  from { transform: rotate(var(--obj-rot, 0deg)) translateY(0); }
  to   { transform: rotate(var(--obj-rot, 0deg)) translateY(calc(var(--hero-float-lift) * -1)); }
}
/* E13c — Ensemble-Slots (Chris-Wahl 30.08., „Objekt-Duo/Ensemble"-Vorschau):
   drei Objekte in der rechten __stage, von oben nach unten drapiert, alle
   ohne Anschnitt. --main ist auf jeder Seite das iso-iPhone; top/bottom
   wählen das seitenspezifische Motiv. Rotation über --obj-rot, damit
   bp-hero-float weiterläuft. */
.bp-page-hero__stage { position: relative; min-height: 520px; align-self: stretch; }
.bp-page-hero__stage--empty { min-height: 0; } /* Chris 31.08.: Höhe kommt jetzt aus __inner */
.bp-page-hero__obj--top    { right: 4%; top: 0; width: clamp(120px, 10.5vw, 160px); --obj-rot: 10deg; animation-duration: var(--dur-float-b); animation-delay: -3s; }
.bp-page-hero__obj--main   { left: 6%; top: 25%; z-index: 1; width: clamp(330px, 29vw, 440px); --obj-rot: -3deg; animation-duration: var(--dur-float-c); animation-delay: -5s; }
.bp-page-hero__obj--bottom { right: 3%; bottom: 0; width: clamp(150px, 13vw, 200px); --obj-rot: -8deg; animation-duration: var(--dur-float-d); animation-delay: -7s; }
/* E13c-Solo (in Erprobung, Chris 30.08., Nachfass „größer, angeschnitten,
   REALE Bilder"): EIN großer fotorealer Freisteller — Apple-Duktus. Die Box
   ankert rechts unten und ragt aus der Bühne (Anschnitt unten/rechts),
   object-fit hält das Motiv verzerrungsfrei am Anker. Statisch (kein Float —
   eine wandernde Anschnitt-Kante wirkt unruhig). */
/* Der Solo sitzt als DIREKTES Bühnen-Kind (Markup: vor __inner) — so ist
   der Anschnitt unabhängig von der Texthöhe der linken Spalte. Die leere
   __stage hält im Split-Grid nur den Platz der rechten Spalte frei. */
.bp-page-hero__obj--solo {
  position: absolute; z-index: 1;
  right: clamp(16px, 4vw, 72px); bottom: -9%;
  width: 50vw; height: 104%;
  object-fit: contain;
  object-position: right bottom;
  animation: none;
}
/* Liegende Landscape-Motive (z. B. das iso-iPhone der App-Seite) laufen
   größer und großzügig im Anschnitt nach rechts unten aus der Bühne. */
.bp-page-hero__obj--solo.bp-page-hero__obj--solo-wide {
  right: -7%; bottom: -20%;
  width: 58vw; height: 128%;
}
/* Flache Grafik-Motive ohne eingebauten Schatten (QR-Sticker):
   der Journey-Schlagschatten trennt Weiß von der hellen Bühne (Runde 9). */
.bp-page-hero__obj--solo-shadow { filter: drop-shadow(0 18px 30px var(--solo-shadow-strong)) drop-shadow(0 4px 10px var(--solo-shadow-soft)); }
/* Frei stehende Motive (Chris, Runde 9b: „nicht oben und unten an den
   Boxrand"): vollständig sichtbar, mit Luft ober- und unterhalb, rechts
   verankert — kein Anschnitt. top+height statt transform, weil das
   Reveal-System transform beim Einblenden überschreibt. */
.bp-page-hero__obj--solo.bp-page-hero__obj--solo-float { top: 12%; bottom: auto; height: 76%; object-position: right center; }

/* E13c-Nachfass (Chris 31.08., 3. Runde — VERBINDLICH): Solo-sm-Bühne für
   Kanon-Assets (normalize-hero-solo.py: Canvas 1200×1500, Motiv zentriert,
   86 %-Breite, Unterkante 72 px). Chris-Werte 55vw/100 %/-17 %; der
   Basis-drop-shadow entfällt (BG-matched Motive tragen ihr Licht selbst).
   Gleicher Doppel-Selektor-Trick wie --solo-float. */
.bp-page-hero__obj--solo.bp-page-hero__obj--solo-sm {
  width: 70vw; height: 108%; /* Chris-Finaljustage 31.08. (aus Live-Override übernommen) */
  bottom: -17%;
  filter: none;
}
.bp-page-hero__inner {
  position: relative; z-index: 2;
  min-height: 400px; /* Chris 31.08.: ersetzt die 480er-Stage-Höhe */
  margin-inline: auto;
  display: grid; /* E13c: Split — __copy links, __stage rechts */
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.8fr);
  align-items: center;
  gap: 40px;
  padding: 0 clamp(24px, 5vw, 72px); /* E13c-Nachfass 2: Split läuft randnah über die volle Bühne (Chris: 1280er-Deckel war zu schmal); kein Bottom-Padding — Content sitzt vertikal mittig */
}
.bp-page-hero__title {
  margin: 0;
  font-family: var(--font-hero-upper);
  font-weight: var(--hero-title-wght);
  font-size: var(--text-hero-page);
  line-height: var(--hero-title-lh);
  letter-spacing: var(--hero-title-ls);
  -webkit-text-stroke: var(--hero-title-stroke) currentColor; /* E13c: halbfett */
  max-width: 26ch;  /* Live-Zeilenmaß */
  text-wrap: balance;
}
/* E13-Nachfass (Chris 30.08.): der Hero-Titel bleibt auf ALLEN Breiten
   Bebas — kein Font-Wechsel unter 1024 mehr (--text-hero-page clamp skaliert). */
.bp-page-hero__sub {
  margin: var(--head-sub-gap) 0 0;
  max-width: 672px;  /* Live-Lesebreite (42rem) */
  color: var(--color-text); /* E13: auf der Teal-Bühne steht Copy in Ink */
  text-wrap: pretty;
}
.bp-page-hero .bp-page-hero__actions { margin-top: var(--hero-actions-gap); display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: var(--space-5); }
/* E13 — Hero-Button-Kanon (Chris-Mockup 29.08.): Primär = Ink-Fläche mit
   Teal-Icon-Quadrat (Pfeil in Ink), Sekundär (--light) = Paper-Fläche mit
   Ink-Icon-Quadrat und Paper-Pfeil. Gilt nur im PageHero — außerhalb bleibt
   der Rundeck-Teal-Kanon (E4). */
.bp-page-hero__actions .bp-btn { background: var(--button-dark-bg); color: var(--button-dark-fg); }
.bp-page-hero__actions .bp-btn .bp-btn__icon { background: var(--teal-surface); color: var(--ink); }
.bp-page-hero__actions .bp-btn--light { background: var(--button-light-bg); color: var(--button-light-fg); }
.bp-page-hero__actions .bp-btn--light .bp-btn__icon { background: var(--ink); color: var(--paper); }
.bp-page-hero__trust {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--space-4) var(--space-6);
  margin: var(--hero-trust-gap) 0 0;
  padding: 0; list-style: none;
  font-family: var(--font-sans);
  font-size: var(--text-hero-trust);
  color: var(--color-text); /* E13: Trustzeile in Ink */
}
.bp-page-hero__trust li { display: flex; align-items: center; gap: var(--space-3); }
.bp-page-hero__trust li::before {
  content: ""; width: var(--space-3); height: var(--space-3);
  border-radius: var(--radius-circle);
  background: var(--ink); /* E13: Teal-Punkte wären auf Teal unsichtbar */
}
/* Außerhalb des Heros (Cluster-Finale zitiert die Trustzeile auf Paper)
   behalten die Punkte den Teal-Akzent. */
.bp-cta-cluster .bp-page-hero__trust li::before { background: var(--color-accent); }
.bp-page-hero--calm { padding-block: var(--section-pad) calc(var(--section-pad) + var(--space-12)); }
/* E13c — Mobil: Content zentriert, die drei Objekte auf EINER Linie unter den
   Buttons, außen mit Anschnitt an den Bühnenrand. Float aus, weil die
   Transform-Zentrierung sonst mit der Animation kollidiert. */
@media (max-width: 999px) {
  .bp-page-hero { text-align: center; padding-bottom: 24px; }
  .bp-page-hero__inner { grid-template-columns: 1fr; gap: 0; }
  .bp-page-hero__title { margin-inline: auto; }
  .bp-page-hero__sub { margin-inline: auto; }
  .bp-page-hero .bp-page-hero__actions { justify-content: center; }
  .bp-page-hero__stage { min-height: 230px; margin-top: 30px; align-self: auto; }
  .bp-page-hero__obj { animation: none; }
  .bp-page-hero__obj--top    { left: -16%; right: auto; top: 50%; transform: translateY(-50%) rotate(10deg); width: min(130px, 30vw); }
  .bp-page-hero__obj--main   { left: 50%; top: 50%; transform: translate(-50%, -50%) rotate(-3deg); width: min(250px, 54vw); }
  .bp-page-hero__obj--bottom { right: -17%; left: auto; bottom: auto; top: 50%; transform: translateY(-50%) rotate(-8deg); width: min(140px, 32vw); }
  /* Doppel-Selektor: muss die 0-2-0-Spezifität der wide-Desktop-Regel
     schlagen, sonst gilt mobil weiter 58vw/128 % mit Rechts-Anschnitt.
     Runde 10 (Chris 30.08., Varianten-Entscheid „Stempel + Anschnitt"):
     Motiv MITTIG in Stempel-Größe, unten aus der Karte angeschnitten —
     die Bühne wird flacher (Stage 210 statt 290), kein leerer Kartenraum.
     Gilt einheitlich für alle Solo-Spielarten (wide/float/panorama). */
  /* --solo-sm MUSS hier stehen (0,2,0 wie die Desktop-Regel, MQ gewinnt per
     Reihenfolge) — sonst schlägt die Desktop-sm-Regel mobil die Basisliste
     und die Grafik rendert 55vw rechts statt 100 % mittig (Bug 31.08.). Die
     Kanon-Assets sind horizontal zentriert, center bottom sitzt damit exakt. */
  .bp-page-hero__obj--solo,
  .bp-page-hero__obj--solo.bp-page-hero__obj--solo-sm,
  .bp-page-hero__obj--solo.bp-page-hero__obj--solo-wide,
  .bp-page-hero__obj--solo.bp-page-hero__obj--solo-wide.bp-page-hero__obj--solo-panorama,
  .bp-page-hero__obj--solo.bp-page-hero__obj--solo-float { top: auto; left: 0; right: 0; bottom: -12%; width: 100%; max-width: none; height: 58%; object-position: center bottom; } /* height 58 % statt 40 % — Chris-Wert 31.08. (Grafik war mobil zu klein) */
  /* Ausnahme QR-Sticker (float): ein unten angeschnittener QR-Code mit
     halbem Logo wirkt defekt — der Sticker bleibt vollständig sichtbar
     und bündig, den Anschnitt tragen nur die Fotomotive. */
  .bp-page-hero__obj--solo.bp-page-hero__obj--solo-float { bottom: 0; height: 36%; }
  /* Solo-sm mobil: fixe 260px-Höhe statt Prozent (Chris-Finaljustage 31.08.) —
     steht NACH der Solo-Liste, gleiche 0,2,0-Spezifität → gewinnt per Reihenfolge. */
  .bp-page-hero__obj--solo.bp-page-hero__obj--solo-sm { height: 260px; }
  .bp-page-hero__stage--empty { min-height: 135px; } /* Chris 31.08. */
}

/* E13c — Sekundär-CTA als Textlink mit Pfeil (Chris 30.08.): bewusst
   unprominent neben dem Hauptbutton, Zeilenhöhe wie die Pille. */
.bp-link-cta {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: var(--pill-height);
  padding-inline: 6px;
  font-family: var(--font-sans); font-weight: var(--btn-wght); font-size: var(--text-base);
  color: var(--ink); text-decoration: none;
}
.bp-link-cta > span { transition: transform var(--dur) var(--ease); }
.bp-link-cta:hover > span { transform: translateX(5px); }

@media (prefers-reduced-motion: reduce) {
  .bp-page-hero__obj { animation: none; }
  .bp-link-cta > span { transition: none; }
}
/* Einsatz-Lage: Bühnen (PageHero, Foto-CTA, Night-CTA, Final-Cluster)
   sitzen IMMER randvoll mit schmalem Seitenrand (live-Kanon), nie im
   Inhalts-Container — dieser Wrapper stellt das her. */
.bp-bleed, .bp-page-hero-bleed { margin-inline: var(--hero-inset); }

/* --- Maßnahmen-Karte — der Karten-Kanon der Ratgeber-Sektionen -------------
   Übernommen von bikepass.eu/e-bike-diebstahlschutz (Chris-Referenz):
   weiße Karte, heller Icon-Chip mit Teal-Liniensymbol, Titel auf der
   H4-SM-Ebene (26/600), Copy auf Base. Typo kommt aus den bp-t-*-Klassen im
   Markup — diese Komponente stylt nur Fläche, Chip und Verhalten. */
.bp-card--measure {
  gap: var(--space-8);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-card-sm);
  box-shadow: var(--shadow-card);
  transition: transform var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.bp-card--measure:hover {
  transform: translateY(calc(var(--space-2) * -0.75));
  border-color: var(--color-accent);
}
.bp-card--measure .bp-btn { margin-top: auto; align-self: flex-start; }
.bp-measure-icon {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  width: var(--size-measure-icon); height: var(--size-measure-icon);
  border-radius: var(--radius-tile);
  border: var(--border-w) solid var(--teal-22);
  background: linear-gradient(180deg, var(--paper) 0%, var(--teal-light) 100%);
  color: var(--teal-deep);
}
.bp-measure-icon svg { width: var(--size-icon); height: var(--size-icon); }
.bp-card--measure--feature {
  background: linear-gradient(160deg, var(--teal-10), var(--paper));
  border-color: var(--teal-35);
}

/* --- Zahlen-Stat (E24, Chris 30.08.) — freischwebend statt Karte ----------
   Kennzahlen laufen NICHT mehr als bp-card--measure: kein Rahmen, kein
   Schatten, kein Icon. Zentriert; der Wert in Bebas (Hero-Familie) auf
   --text-stat, der Titel rückt dicht an die Zahl. Counter-Verhalten
   unverändert über [data-counter-target] (kit-pages.js). */
.bp-stat { display: flex; flex-direction: column; align-items: center; text-align: center; }
.bp-stat__value {
  font-family: var(--font-hero-upper);
  font-weight: var(--hero-title-wght);
  font-size: var(--text-stat);
  line-height: var(--stat-lh);
  letter-spacing: var(--stat-ls);
  color: var(--ink);
}
.bp-stat .bp-stat__value + * { margin-top: var(--space-3); }
.bp-stat .bp-t-base { margin-top: var(--space-6); }

/* --- Foto-CTA — dunkle Bildbühne mit Registrierungs-Aufruf -----------------
   Chris-Referenz (uploads, 29.08.): Foto in der Karte, durchgehende
   Hero-Veil-Ebene, Chip → H2 (weiß) → Sub (Weiß 70) → helle Pill.
   Komposition aus Bestands-Bausteinen; diese Klasse liefert nur Bühne
   und Stapelung. */
.bp-cta-photo {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-card);
  min-height: clamp(520px, 60vh, 680px); /* E21-Nachfass (Chris 30.08.): Bühne läuft großzügiger in der Höhe */
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  color: var(--color-text-inverse);
}
.bp-cta-photo > img {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover;
}
.bp-cta-photo::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--color-hero-veil);
  pointer-events: none;
}
.bp-cta-photo__inner {
  position: relative; z-index: 2;
  max-width: var(--measure-stage); /* E21: 720 lief zu schmal */
  padding: var(--section-pad) var(--container-pad);
  display: flex; flex-direction: column; align-items: center;
}
.bp-cta-photo__inner > .bp-chip + * { margin-top: var(--head-chip-gap); }
.bp-cta-photo__inner .bp-cta-photo__sub { margin-top: var(--head-sub-gap); color: var(--color-text-inverse-muted); max-width: var(--measure); }
.bp-cta-photo__inner .bp-btn { margin-top: var(--space-12); }

/* ============================================================================
   7b · BIKEPASS-SEKTIONEN, zweiter Schub (29.08.2026, Chris-Review):
   Funktionen-Bento, Payment-Icon-Pills, Night-CTA, App-Cluster-Finale,
   FAQ-Breite. Alles 1:1 vom effektiven Live-Stand übernommen und
   tokenisiert — wer sie einsetzt, gestaltet nicht neu.
   ========================================================================== */

/* --- Funktionen-Bento — DER Kanon für Funktions-Übersichten ----------------
   Live-Startseite #funktionen (effektiver Stand inkl. CSS-Overwrite):
   sechs gleiche flache Tiles im 3er-Raster, Bild-Bühne 4:3 oben,
   Titel bp-t-h6 + Copy bp-t-base. Funktionen werden IMMER so gezeigt. */
.bp-feature-bento {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--grid-gap);
}
@media (min-width: 768px)  { .bp-feature-bento { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .bp-feature-bento { grid-template-columns: repeat(3, 1fr); } }
.bp-feature-tile {
  display: flex; flex-direction: column;
  overflow: hidden;
  background: var(--bento-tile-bg);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-card);
  transition: transform var(--dur-fast) var(--ease);
}
.bp-feature-tile:hover { transform: scale(1.02); }
.bp-feature-tile__visual {
  position: relative; overflow: hidden;
  flex: 0 0 auto;
  aspect-ratio: var(--ratio-media);
  background: linear-gradient(135deg, var(--bento-visual-bg) 0%, var(--paper) 100%);
}
.bp-feature-tile__visual img {
  width: 100%; height: 100%; display: block;
  object-fit: cover;
  transition: transform var(--dur) var(--ease);
}
.bp-feature-tile:hover .bp-feature-tile__visual img { transform: scale(1.04); }
.bp-feature-tile__body { flex: 1 1 auto; padding: 2.2rem; }
.bp-feature-tile__body h3 { line-height: var(--bento-title-lh); text-wrap: balance; }
.bp-feature-tile__body p { margin-top: var(--space-4); text-wrap: pretty; }

/* --- Payment-Icon-Pills — Checkout-Optik für CTAs --------------------------
   Weiße Pills mit echten Marken-SVGs/Wortmarken (Live-Startseite = Checkout).
   Kanon für alle Kauf-CTAs; bp-pay-mono bleibt nur für ruhige Alt-Kontexte. */
.bp-pay-icons { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.bp-pay-icons .bp-pay-pill {
  display: inline-flex; align-items: center; justify-content: center;
  height: 30px; padding: 0 var(--space-4);
  border-radius: var(--radius-button);
  background: var(--paper);
  border: var(--border-w) solid var(--ink-10);
  box-shadow: var(--shadow-rail);
  font-family: var(--font-sans);
  font-weight: var(--strong-wght);
  font-size: var(--text-pay-pill);
  color: var(--brandmark-black);
  white-space: nowrap; line-height: var(--control-lh);
}
.bp-pay-pill .bp-paypal-text { font-style: italic; letter-spacing: var(--pay-paypal-ls); font-size: var(--text-pay-mark); }
.bp-pay-pill .bp-paypal-text .a { color: var(--brandmark-paypal-a); }
.bp-pay-pill .bp-paypal-text .b { color: var(--brandmark-paypal-b); }
.bp-pay-pill .bp-visa-text { color: var(--brandmark-visa); font-style: italic; font-weight: var(--pay-mark-wght); letter-spacing: var(--pay-visa-ls); font-size: var(--text-pay-mark); }
.bp-pay-pill .bp-gpay-text { color: var(--brandmark-gpay); font-weight: var(--pay-sub-wght); font-size: var(--text-pay-pill); margin-left: var(--space-2); }
.bp-pay-pill .bp-applepay-text { color: var(--brandmark-black); font-weight: var(--pay-sub-wght); font-size: var(--text-pay-pill); margin-left: 2px; }
@media (max-width: 767.98px) {
  .bp-pay-icons { flex-wrap: nowrap; gap: var(--space-2); overflow-x: auto; scrollbar-width: none; padding-bottom: var(--space-2); }
  .bp-pay-icons::-webkit-scrollbar { display: none; }
  .bp-pay-icons .bp-pay-pill { flex-shrink: 0; height: 26px; }
}

/* --- Night-CTA — der BikePass-ID-Kauf-CTA ----------------------------------
   Showcase-Variante „Night" (Chris-Entscheid 29.08.): reine Farb-Bühne auf
   Ink-Deep mit zwei Teal-Mesh-Radials, Produktbild links OHNE Rotation,
   rechts Titel → Copy → Preis+Button → Payment-Pills → Versandzeile.
   Randvoll (bp-bleed) und im normalen Sektionsrhythmus. */
.bp-cta-night {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-card);
  background:
    radial-gradient(ellipse 55% 70% at 18% 18%, var(--night-mesh-a), transparent 62%),
    radial-gradient(ellipse 45% 55% at 82% 86%, var(--night-mesh-b), transparent 60%),
    var(--ink-deep);
  color: var(--color-text-inverse);
}
.bp-cta-night__inner {
  position: relative; z-index: 2;
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: clamp(24px, 4vw, 60px);
  padding: var(--section-pad) var(--container-pad);
  max-width: var(--hero-inner-max);
  margin-inline: auto;
}
@media (min-width: 1024px) { .bp-cta-night__inner { grid-template-columns: 1.05fr 0.95fr; } }
.bp-cta-night__media img {
  max-width: 100%; height: auto; display: block;
  margin-inline: auto;
  border-radius: var(--radius-card-sm); /* E21: ohne Teal-Ring/Glow-Schatten */
}
.bp-cta-night__title { margin: 0; text-wrap: balance; }
.bp-cta-night__title .bp-cta-night__accent { color: var(--teal); }
.bp-cta-night__copy { margin: var(--head-sub-gap) 0 0; max-width: 34rem; color: var(--night-copy); }
/* E21: Button steht UNTER dem Preis, nicht daneben. */
.bp-cta-night__buy {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--space-6);
  margin-top: var(--space-12);
}
.bp-cta-night__price b { font-weight: var(--strong-wght); font-variation-settings: "opsz" 16, "wght" var(--strong-wght); } /* E11: Preis fett */
.bp-cta-night__price small { display: block; margin-top: var(--space-2); color: var(--night-fine); font-size: var(--text-xs); }
.bp-cta-night .bp-pay-icons { margin-top: var(--space-8); }
.bp-cta-night__note {
  display: flex; align-items: center; gap: var(--space-4);
  margin: var(--space-6) 0 0;
  color: var(--night-fine); font-size: var(--text-xs);
}
.bp-cta-night__dot {
  width: var(--space-3); height: var(--space-3); flex: 0 0 auto;
  border-radius: var(--radius-circle);
  background: var(--teal);
  box-shadow: 0 0 0 var(--space-2) var(--night-mesh-b);
}

/* --- Final-Cluster — helles Finale mit drei App-iPhones --------------------
   Live-Kanon bp-cta-final--cluster: Aurora-Schein auf Paper, Bebas-Statement
   in Hero-Größe, drei Statusbar-iPhones (bpg-Familie), Button, Trustzeile.
   Ersetzt die dunkle Video-Szene. Normaler Sektionsrhythmus. */
.bp-cta-cluster {
  position: relative;
  isolation: isolate;
  /* E21-Nachfass: nach oben mehr Luft (Chris 30.08.) */
  padding-block: calc(var(--section-pad) + var(--space-16)) var(--section-pad);
  text-align: center;
}
/* E21: Aurora/Mesh im Finale abgeschafft — das Cluster steht auf ruhigem Paper. */
.bp-cta-cluster__glow { display: none; }
.bp-cta-cluster__copy { max-width: var(--measure-stage); margin-inline: auto; }
.bp-cta-cluster__statement {
  margin: 0 auto;
  font-family: var(--font-hero-upper);
  font-weight: var(--statement-wght);
  font-size: var(--text-statement); /* E21-Nachfass: kleiner als die Hero-H1 */
  line-height: var(--statement-lh);
  letter-spacing: var(--statement-ls);
  text-transform: uppercase;
  color: var(--color-text);
  text-wrap: balance;
}
.bp-cta-cluster__sub { margin: var(--head-sub-gap) auto 0; max-width: var(--measure); text-wrap: pretty; }
.bp-cta-cluster__actions { display: flex; flex-direction: column; align-items: center; }
.bp-cta-cluster__actions .bp-page-hero__trust { margin-top: var(--hero-actions-gap); }

/* 3er-Phone-Fächer — --pw steuert alle Frame-Maße */
.bp-cluster-phones {
  display: flex; justify-content: center; align-items: center;
  --pw: clamp(190px, 20vw, 240px);
  margin: clamp(32px, 4vw, 50px) auto;
}
.bp-cluster-phone { flex: 0 0 auto; width: var(--pw); }
.bp-cluster-phone--c { z-index: 3; transform: scale(1.05); }
.bp-cluster-phone--l { z-index: 1; transform: rotate(-8deg) translateY(4%); margin-right: calc(var(--pw) * -0.24); filter: brightness(.96); }
.bp-cluster-phone--r { z-index: 1; transform: rotate(8deg) translateY(4%); margin-left: calc(var(--pw) * -0.24); filter: brightness(.96); }
@media (max-width: 767.98px) { .bp-cluster-phones { --pw: clamp(118px, 31vw, 165px); } }

/* iPhone-Frame (Double-Bezel) — Live-bpg-Familie, tokenisiert */
.bpg-phone {
  position: relative; width: var(--pw, 240px);
  padding: calc(var(--pw, 240px) * .038);
  border-radius: calc(var(--pw, 240px) * .168);
  background: linear-gradient(150deg, var(--phone-frame-a) 0%, var(--phone-frame-b) 34%, var(--phone-frame-c) 100%);
  box-shadow: var(--shadow-phone);
}
.bpg-screen {
  position: relative; overflow: hidden;
  border-radius: calc(var(--pw, 240px) * .135);
  background: var(--paper);
  display: flex; flex-direction: column;
  box-shadow: inset 0 0 0 var(--border-w) var(--phone-screen-line);
}
.bpg-statusbar {
  position: relative; z-index: 2;
  height: calc(var(--pw, 240px) * .125);
  background: var(--paper);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 calc(var(--pw, 240px) * .058);
  color: var(--ink);
}
.bpg-phone { --bpg-time-fs: calc(var(--pw, 240px) * .046); }
.bpg-time { font-weight: var(--strong-wght); font-size: var(--bpg-time-fs); font-variant-numeric: tabular-nums; }
.bpg-sb-right { display: flex; align-items: center; gap: calc(var(--pw, 240px) * .018); }
.bpg-sb-right svg { display: block; height: calc(var(--pw, 240px) * .042); width: calc(var(--pw, 240px) * .070); color: var(--ink); }
.bpg-sb-right svg:has(use[href="#bpg-wifi"]) { width: calc(var(--pw, 240px) * .058); }
.bpg-sb-right svg:has(use[href="#bpg-bat"]) { width: calc(var(--pw, 240px) * .088); }
.bpg-island {
  position: absolute; left: 50%; top: 22%; transform: translateX(-50%);
  width: calc(var(--pw, 240px) * .30); max-width: 100px; height: 56%;
  background: var(--phone-frame-c); border-radius: var(--radius-pill);
}
.bpg-shot { width: 100%; height: auto; display: block; }
.bpg-homebar {
  position: absolute; left: 50%; bottom: calc(var(--pw, 240px) * .026); transform: translateX(-50%);
  width: 34%; height: calc(var(--pw, 240px) * .014); min-height: 3px;
  border-radius: var(--radius-pill);
  background: var(--phone-homebar); z-index: 3; mix-blend-mode: multiply;
}
.bpg-screen::after {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  background: linear-gradient(128deg, var(--phone-gloss) 0%, transparent 26%);
  border-radius: calc(var(--pw, 240px) * .135);
}
[data-motion="paused"] .bp-feature-tile__visual img { transition: none; }

/* --- Schritt-Timeline „Zig-Zag" (E22, Chris-Wahl 30.08.) --------------------
   Schritt-Folgen laufen IMMER als Zick-Zack-Timeline: Teal-Mittellinie,
   Outline-Nummernkreise auf der Achse, Karten im Karten-Kanon wechseln die
   Seite. Als <ol> ausgezeichnet (die Reihenfolge IST der Inhalt); unter 900 px
   stapelt alles an einer Linie links. Geometrie-Konstanten (44er-Kreis,
   52er-Achsabstand, 74er-Badge-Versatz) sind gemessene Bauteil-Maße. */
.bp-steps {
  position: relative;
  display: flex; flex-direction: column;
  gap: var(--space-10);
  max-width: 960px;
  margin-inline: auto;
  text-align: left;
}
.bp-steps::before {
  content: ""; position: absolute; z-index: 0;
  left: 50%; top: 6px; bottom: 6px; width: 2px;
  transform: translateX(-50%);
  background: var(--teal-35);
}
.bp-steps__item { position: relative; width: calc(50% - 52px); }
.bp-steps__item:nth-child(odd)  { align-self: flex-start; }
.bp-steps__item:nth-child(even) { align-self: flex-end; }
.bp-steps__num {
  position: absolute; top: 14px; z-index: 1;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  background: var(--paper);
  color: var(--teal-deep);
  border: var(--border-w-strong) solid var(--teal);
  border-radius: var(--radius-circle);
  font-family: var(--font-display);
  font-size: var(--text-step-num);
  font-weight: var(--text-h2-wght);
  font-variation-settings: "opsz" 16, "wght" var(--text-h2-wght);
  line-height: var(--control-lh);
}
.bp-steps__item:nth-child(odd)  .bp-steps__num { right: -74px; }
.bp-steps__item:nth-child(even) .bp-steps__num { left: -74px; }
.bp-steps__card {
  display: flex; flex-direction: column;
  gap: var(--space-4);
  background: var(--card-bg);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-tile);
  padding: var(--space-8) var(--space-10);
  box-shadow: var(--shadow-card);
}
.bp-steps__card p { color: var(--color-text-muted); }
.bp-steps__card .bp-btn { margin-top: var(--space-4); align-self: flex-start; }
@media (max-width: 899.98px) {
  .bp-steps::before { left: 21px; transform: none; }
  .bp-steps__item,
  .bp-steps__item:nth-child(even) { width: auto; align-self: stretch; margin-left: 66px; }
  .bp-steps__item:nth-child(odd) .bp-steps__num,
  .bp-steps__item:nth-child(even) .bp-steps__num { left: -66px; right: auto; }
}

/* --- Trust-Strip — die Leiste unter JEDEM PageHero (E19) --------------------
   1:1 die Startseiten-Leiste (hero-strip, nachgemessen 29.08.): Avatar-Stack
   mit Kundenzeile links, Pill-Marquee in der Mitte (läuft über das
   Kit-[data-marquee]), EU-Flagge + „Made in Germany" rechts. Sie ersetzt die
   frühere __trust-Zeile IM Hero und ist nach jedem bp-page-hero Pflicht.
   Geometrie-Konstanten (38px-Avatare, 52×38-Flagge, 8px-Punkte, −10px-Lap,
   3px-Ring) sind Live-Messwerte. */
.bp-trust-strip {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-8);
  /* EINE Zeile wie auf der Startseite — der Marquee-Track darf die Zeile
     nicht sprengen (flex-basis 0 am __pills-Kind), gestapelt wird erst mobil. */
  flex-wrap: nowrap;
  margin-top: var(--space-6);
  /* Fullwidth (Chris 30.08.): der Strip läuft im bp-bleed über die volle
     Breite — der Innenrand kommt aus dem Container-Pad. */
  padding: var(--space-6) var(--container-pad);
}
.bp-trust-strip__customers { display: flex; align-items: center; gap: var(--space-6); flex: 0 0 auto; }
.bp-trust-strip__customers p { white-space: nowrap; }
.bp-trust-strip__avatars { display: inline-flex; }
.bp-trust-strip__avatars span {
  display: block;
  width: 38px; height: 38px;
  border-radius: var(--radius-circle);
  border: 3px solid var(--paper);
  margin-left: -10px;
  box-shadow: var(--shadow-rail);
  background-size: cover; background-position: center;
}
.bp-trust-strip__avatars span:first-child { margin-left: 0; }
.bp-trust-strip__customers p {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  line-height: var(--strip-lh);
  color: var(--color-text-muted);
}
.bp-trust-strip__customers strong { color: var(--color-text); font-weight: var(--strong-wght); }
.bp-trust-strip__pills { flex: 1 1 0%; min-width: 0; }
.bp-trust-strip__pill {
  display: inline-flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-6);
  background: var(--paper);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-pill);
  color: var(--color-text-muted);
  font-family: var(--font-sans);
  font-size: var(--text-table-head);
  font-weight: var(--btn-wght);
  white-space: nowrap;
  line-height: var(--control-lh);
}
.bp-trust-strip__pill svg { color: var(--color-text-muted); flex: 0 0 auto; }
/* Der Pill-Lauf nutzt das Kit-[data-marquee]; nur der Gap ist enger als der 64er-Ticker-Kanon. */
.bp-trust-strip__pills > * { gap: var(--space-4); }
.bp-trust-strip__made { display: flex; align-items: center; gap: var(--space-4); flex: 0 0 auto; }
.bp-trust-strip__flag { width: 52px; height: 38px; object-fit: cover; border-radius: var(--radius-button); }
.bp-trust-strip__dots { display: flex; flex-direction: column; gap: 5px; }
.bp-trust-strip__dots span { display: block; width: 8px; height: 8px; border-radius: var(--radius-circle); }
.bp-trust-strip__mig {
  font-family: var(--font-sans);
  font-size: var(--text-pay-pill);
  font-weight: var(--strong-wght);
  text-transform: uppercase;
  line-height: var(--xs-lh);
  color: var(--color-text);
}
@media (max-width: 1023.98px) { .bp-trust-strip__pills { display: none; } }
@media (max-width: 767.98px) {
  .bp-trust-strip { flex-direction: column; align-items: center; text-align: center; gap: var(--space-6); }
  .bp-trust-strip__customers { flex-direction: column; gap: var(--space-4); }
  .bp-trust-strip__customers p { white-space: normal; }
}

/* --- Bewertungs-Karte — Live-Kanon der review-card (E20) --------------------
   Kopfzeile: Initialen-Avatar + Name links, Amber-Sterne rechts; Text darunter.
   Im Marquee feste Breite (--size-review), sonst füllend. */
.bp-review-card {
  display: flex; flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-8);
  background: var(--card-bg);
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-tile);
  box-shadow: var(--shadow-card);
}
[data-marquee] .bp-review-card { flex: 0 0 auto; width: var(--size-review); }
.bp-review-card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-5); }
.bp-review-card__id { display: flex; align-items: center; gap: var(--space-5); min-width: 0; }
.bp-review-card__avatar {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  width: var(--size-social); height: var(--size-social);
  border-radius: var(--radius-circle);
  color: var(--paper);
  font-family: var(--font-sans);
  font-weight: var(--strong-wght);
  font-size: var(--text-pay-mark);
  line-height: var(--control-lh);
}
.bp-review-card__name {
  font-family: var(--font-sans);
  font-weight: var(--btn-wght);
  font-size: var(--text-xs);
  color: var(--color-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bp-review-card__stars {
  color: var(--star);
  font-size: var(--text-xs);
  letter-spacing: var(--star-ls);
  white-space: nowrap;
  line-height: var(--xs-lh);
}
.bp-review-card p { font-size: var(--text-btn); line-height: var(--copy-lh); color: var(--color-text-muted); }

/* --- Tabellen-Kanon „Zeilen-Karten" -----------------------------------------
   Chris-Wahl 29.08. (Stil A der drei Vorschläge, Highlight auf Teal):
   jede Zeile ist eine Karte im Karten-Kanon (Radius-Tile, Hairline,
   Karten-Schatten), die Kopfzeile schwebt als Uppercase-Label darüber.
   Die BikePass-Zeile (tr.us) bzw. -Zelle (td/th.us, Spalten-Highlight)
   liegt auf Teal — Text darauf in Ink (Regel 4). Ersetzt bp-compare auf
   den BikePass-Seiten; bp-compare bleibt App-Land-Erbe. */
.bp-table { width: 100%; max-width: var(--measure-table); margin-inline: auto; overflow-x: auto; }
.bp-table table { width: 100%; border-collapse: separate; border-spacing: 0 var(--space-4); min-width: var(--size-compare-min); }
.bp-table thead th {
  padding: var(--space-2) var(--space-8) var(--space-4);
  text-align: left;
  font-family: var(--font-sans);
  font-size: var(--text-table-head);
  font-weight: var(--pay-sub-wght);
  letter-spacing: var(--table-head-ls);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}
.bp-table td, .bp-table tbody th {
  padding: var(--space-6) var(--space-8);
  text-align: left;
  font-size: var(--text-base);
  background: var(--card-bg);
  border-top: var(--border-w) solid var(--color-border);
  border-bottom: var(--border-w) solid var(--color-border);
}
.bp-table tbody th {
  font-family: var(--font-sans);
  font-weight: var(--pay-sub-wght);
  color: var(--color-text);
  border-left: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-tile) 0 0 var(--radius-tile);
}
.bp-table td:last-child { border-right: var(--border-w) solid var(--color-border); border-radius: 0 var(--radius-tile) var(--radius-tile) 0; }
.bp-table tbody tr { box-shadow: var(--shadow-card); }
/* Highlight: ganze Zeile (tr.us) oder einzelne Zellen (Spalten-Highlight) auf Teal */
.bp-table tr.us td, .bp-table tr.us th,
.bp-table td.us, .bp-table tbody th.us {
  background: var(--teal-surface); /* heller — Ink bleibt gut lesbar (Chris 30.08.) */
  color: var(--ink);
  border-color: var(--teal-surface);
}
.bp-table thead th.us { color: var(--teal-deep); }
.bp-table__pill {
  display: inline-block;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: var(--paper);
  font-size: var(--text-xs);
  font-weight: var(--pay-sub-wght);
  line-height: var(--xs-lh);
}
@media (max-width: 1023.98px) {
  .bp-table {
    -webkit-mask-image: linear-gradient(to right, var(--mask) 0, var(--mask) 90%, transparent 100%);
            mask-image: linear-gradient(to right, var(--mask) 0, var(--mask) 90%, transparent 100%);
  }
}

/* --- FAQ-Modul: Zweispalter mit Sticky-Kopf ---------------------------------
   E12 (Chris 29.08., Referenz Live-EBD v2.46.0): Kopf links und sticky,
   Fragen rechts — Verhältnis 1fr/1.4fr ab 900 px, darunter gestapelt.
   Der Kopf braucht im Markup .bp-section__head--left. Ersetzt die
   --measure-faq-Zentrierung aus v2.2 (Token bleibt für Alt-Kontexte). */
.bp-faq { display: grid; gap: var(--space-10); }
.bp-faq .bp-section__head + * { margin-top: 0; } /* der Grid-Gap trägt den Abstand */
/* Runde 10 (Chris): einspaltig (mobil/Tablet) läuft der FAQ-Kopf ZENTRIERT —
   die Linksbündigkeit des Zweispalters gehört zur Sticky-Spalte ab 1024. */
@media (max-width: 1023.98px) {
  .bp-faq__head { text-align: center; }
  .bp-faq__head .bp-section__sub { margin-inline: auto; }
}
@media (min-width: 900px) {
  .bp-faq { grid-template-columns: 1fr 1.4fr; gap: var(--space-16); align-items: start; }
  .bp-faq__head { position: sticky; top: calc(var(--header-h, 80px) + var(--space-10)); }
}


/* --- Showcase-Finale (E23, Chris 30.08.) --------------------------------
   Portierung der Standalone „3D Parallax Unfurling Gallery"
   (dev/parallax-gallery, 21st.dev id 20039, MIT) nach Vanilla — Theme
   Light. Scroll-Dramaturgie (kit-pages.js, data-showcase): die 4-spaltige
   App-Matrix füllt die Bühne von Beginn an vollflächig (Kacheln docken oben
   und unten an — das Banner-Karten-Intro ist abgeschafft, Chris 30.08.) und
   dreht aus tiefer 3D-Pose in fast frontal + Spalten-Parallax (0–55 %), dimmt ab
   (55–75 %), Finale-Text staffelt ein (64–86 %), fotoreales iPhone dockt
   von unten an (80–96 %). Ersetzt bp-cta-cluster als letzte Section vor
   dem Footer. Ohne JS und bei reduced-motion: statische Endpose, Text
   sichtbar, CTA klickbar. */
.bp-showcase { position: relative; height: 100vh; background: var(--color-surface); }
.js .bp-showcase { height: 600vh; }
/* Mobil 20 % kürzere Scroll-Strecke (Chris, 31.08.2026): die Keyframe-Fenster
   sind Prozentwerte und skalieren mit — nur die Pin-Höhe ändert sich. Die
   Inline-JS-Kopien der Renderer (Ratgeber/Händler) führen dieselbe Weiche. */
@media (max-width: 640px) { .js .bp-showcase { height: 480vh; } }
.bp-showcase__sticky {
  position: sticky; top: var(--header-h, 0px); height: calc(100vh - var(--header-h, 0px));
  display: flex; justify-content: center; align-items: center;
  overflow: hidden;
}
.bp-showcase__box {
  position: relative; overflow: hidden;
  width: 100vw; height: 100%; max-width: 1920px;
  background: var(--paper);
}
.bp-showcase__persp {
  position: absolute; inset: 0;
  display: flex; justify-content: center; align-items: center;
  perspective: 1000px;
  pointer-events: none;
}
.bp-showcase__mask { position: absolute; inset: 0; z-index: 20; pointer-events: none; }
/* Runde 9 (Chris 30.08.): OBEN KEIN Weißverlauf mehr — die Kacheln docken
   hart an der Bühnenkante an (E23-Kanon); nur unten bleibt der weiche
   Auslauf zum Finale. (Der Runde-8-Versuch mit tiefer Obermaske wirkte
   als milchiger Schleier über den iPhones.) */
.bp-showcase__mask--y { box-shadow: inset 0 -100px 150px -50px var(--paper); }
.bp-showcase__mask--x { box-shadow: inset 150px 0 150px -50px var(--paper), inset -150px 0 150px -50px var(--paper); }
.bp-showcase__matrix {
  display: flex; gap: 24px; justify-content: center; align-items: center;
  width: 120vw; height: 150vh;
  transform-style: preserve-3d;
  transform-origin: center;
  will-change: transform, opacity, filter;
  /* Endpose als No-JS-/reduced-Fallback — JS überschreibt inline */
  transform: translateX(-2vw) rotateX(4deg) rotateY(-8deg) rotateZ(2deg) scale(0.96);
  opacity: 0.22;
}
.bp-showcase__col { display: flex; flex-direction: column; gap: 24px; width: 22vw; min-width: 200px; will-change: transform; }
.bp-showcase__tile { width: 100%; height: clamp(300px, 42vh, 560px); flex-shrink: 0; }
.bp-showcase__tile img {
  width: 100%; height: 100%; object-fit: contain;
  filter: drop-shadow(0 30px 60px var(--showcase-phone-shadow));
}
.bp-showcase__veil {
  position: absolute; inset: 0; z-index: 25;
  background: var(--paper); opacity: 0.35; pointer-events: none;
}
.bp-showcase__phone {
  position: absolute; bottom: 0; left: 50%; z-index: 28;
  max-height: 30vh; width: auto; max-width: 86vw;
  transform: translate(-50%, 0); pointer-events: none; will-change: transform, opacity;
}
.bp-showcase__final {
  position: absolute; inset: 0; z-index: 30;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 0 var(--container-pad) 18vh;
  pointer-events: none;
}
.bp-showcase__title {
  margin: 0;
  font-family: var(--font-hero-upper);
  font-weight: var(--hero-title-wght);
  font-size: var(--text-hero-page);
  line-height: var(--hero-title-lh);
  letter-spacing: var(--hero-title-ls);
  -webkit-text-stroke: var(--hero-title-stroke) currentColor; /* E13c: halbfett */
  text-transform: uppercase;
  color: var(--ink);
  max-width: 26ch; text-wrap: balance;
}
.bp-showcase__sub {
  margin: var(--head-sub-gap) 0 0;
  color: var(--color-text-muted);
  max-width: 672px; text-wrap: pretty;
}
.bp-showcase__cta { margin-top: 28px; pointer-events: auto; }
.bp-showcase__final .bp-page-hero__trust { margin-top: 26px; }
/* E23-Nachfass (Chris 30.08.): das Finale dockt bündig an den Footer an —
   der 32px-Footer-Abstand des Seiten-Chromes entfällt nach dem Showcase. */
main:has(.bp-showcase:last-of-type) + footer,
main:has(.bp-showcase:last-of-type) + .footer-wrap { margin-top: 0; }
@media (max-width: 640px) {
  .bp-showcase__matrix, .bp-showcase__col { gap: 16px; }
  .bp-showcase__final { padding-bottom: 14vh; }
  .bp-showcase__phone { max-height: 20vh; }
}


/* --- Produkt-CTA mit Werbevideo (E25, Chris-Wahl 30.08.) ------------------
   Ersetzt den Night-CTA (E11) auf den Kit-Seiten: dunkle ink-deep-Bühne,
   links der vertikal zentrierte Copy-Stack (Titel OHNE ID-Highlight, Copy
   in night-copy, Produktfoto klein und OHNE Box, Preis + Button, Pay-Icons,
   Versandzeile), rechts das frontale bpg-iPhone mit dem Werbevideo
   (bikepass-werbung.mp4, stumm, Schleife, IO-Autoplay in kit-pages.js) —
   GROSS und unten aus der Bühne angeschnitten wie die Solo-Heros. */
.bp-cta-video {
  position: relative; overflow: hidden;
  border-radius: var(--radius-card);
  /* E25-Nachfass: ganz dezenter Teal-Mesh, damit die Night-Fläche nicht kippt */
  background:
    radial-gradient(58% 82% at 16% 18%, var(--cta-video-mesh-a), transparent 62%),
    radial-gradient(52% 74% at 86% 78%, var(--cta-video-mesh-b), transparent 66%),
    var(--ink-deep);
  color: var(--night-copy);
}
.bp-cta-video__inner {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  align-items: start; gap: clamp(32px, 4vw, 64px); /* Runde 8: beide Spalten schlagen oben an — Phone bündig mit dem Titel */
  max-width: 1400px; margin-inline: auto;
  /* E25-Nachfass 4: KEINE viewport-getriebene min-height mehr — die Bühne
     folgt dem Phone (Stage-Box = 1.72·--pw − Schnittkante). Die alte
     82vh/900-Bühne riss auf hohen Fenstern ~270 px Leere unter der Copy auf
     und ließ das Phone auf 1280×1024 frei über dem Boden enden. */
  padding: clamp(40px, 5vh, 64px) clamp(24px, 5vw, 72px) 0;
}
.bp-cta-video__content { align-self: center; padding-bottom: 0; } /* E25-Nachfass 5 (Chris 30.08.): Copy mittig in der Phone-hohen Zeile — das alte padding-bottom stammte aus der End-Ausrichtung und würde die Mitte verfälschen. Titel bleibt bewusst Sans (Chris: Bebas gehört den Unterseiten-Heros). */
.bp-cta-video__title { margin: 0; color: var(--color-text-inverse); font-size: var(--text-hero-page); line-height: var(--hero-title-lh); } /* E25-Nachfass 2: Hero-Titel-Größe */
.bp-cta-video__subtitle { margin: 10px 0 0; font-family: var(--font-sans); font-size: var(--text-lead); font-weight: var(--btn-wght); color: var(--color-text-inverse); }
.bp-cta-video__copy { margin: 14px 0 0; max-width: 58ch; color: var(--night-copy); }
.bp-cta-video__row { display: flex; align-items: center; gap: 28px; margin-top: 28px; }
.bp-cta-video__product { flex: 0 0 auto; width: 150px; }
.bp-cta-video__product img { display: block; width: 100%; height: auto; }
.bp-cta-video__price { margin: 0; display: flex; align-items: baseline; gap: 10px; font-family: var(--font-sans); color: var(--color-text-inverse); }
.bp-cta-video__price b { font-size: var(--text-h4); font-weight: var(--strong-wght); }
.bp-cta-video__price small { font-size: var(--text-xs); color: var(--night-copy); }
.bp-cta-video__buy .bp-btn { margin-top: 14px; }
.bp-cta-video .bp-pay-icons { margin-top: 26px; }
.bp-cta-video__note { display: flex; align-items: center; gap: 8px; margin: 14px 0 0; font-family: var(--font-sans); font-size: var(--text-xs); color: var(--night-copy); }
.bp-cta-video__note::before { content: ""; width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--teal); }
/* E25-Nachfass 3 (Runde 8): Phone-Oberkante bündig mit dem Titel (align-start
   im Grid), der Anschnitt wandert komplett nach unten. Dahinter ein ganz
   dezenter Teal-Lichtkegel — sonst verschwimmt der dunkle Rahmen im Night-Grund. */
.bp-cta-video__stage { position: relative; display: flex; justify-content: center; --pw: clamp(320px, 29vw, 440px); } /* Runde 10: Phone etwas kleiner — die ausgedünnte Copy (ohne Produktbild/Pay/Note) trägt keine 500er-Bühne mehr */
.bp-cta-video__stage::before {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  left: 50%; bottom: calc(var(--pw) * -0.4); transform: translateX(-50%); /* kalibriert auf die Stage-Box (1.72·--pw − 150) — Kegel-Mitte hinter der unteren Phone-Hälfte */
  width: calc(var(--pw) * 2.1); height: calc(var(--pw) * 2.1);
  background: radial-gradient(closest-side, var(--cta-video-glow), transparent 74%);
}
.bp-cta-video__stage .bpg-phone { position: relative; z-index: 1; margin-bottom: -150px; } /* Phone = 1.72·--pw hoch (gemessen); die fixe Kind-Margin definiert den Bodenanschnitt: die Grid-Zeile (= Stage, sofern die Copy nicht höher ist) endet 150 px vor der Phone-Unterkante — viewport-unabhängig */
.bp-cta-video__island {
  position: absolute; left: 50%; top: calc(var(--pw, 240px) * .028); transform: translateX(-50%);
  width: calc(var(--pw, 240px) * .30); max-width: 130px; height: calc(var(--pw, 240px) * .075);
  background: var(--phone-frame-c); border-radius: var(--radius-pill); z-index: 3;
}
@media (max-width: 899px) {
  /* minmax(0,…) wie am Desktop: ohne den 0-Floor treibt die nicht
     umbrechende Preis-Row die min-content-Breite über den Viewport
     und die Copy läuft rechts aus der Karte (Runde 8). */
  .bp-cta-video__inner { grid-template-columns: minmax(0, 1fr); }
  .bp-cta-video__content { padding-bottom: 0; }
  /* Runde 9 (Chris): Button mobil volle Breite, Preis größer. */
  .bp-cta-video__row { flex-direction: column; align-items: stretch; gap: 18px; }
  .bp-cta-video__buy .bp-btn { width: 100%; justify-content: space-between; }
  .bp-cta-video__price b { font-size: var(--text-h2-sm); }
  .bp-cta-video__stage { margin-top: 8px; }
  .bp-cta-video__stage { --pw: clamp(220px, 56vw, 290px); }
  .bp-cta-video__stage .bpg-phone { margin-bottom: calc(var(--pw) * -0.4); }
}

/* ============================================================================
   7c · WELLE 1 — LESE-/RECHTSSEITEN (30.08.2026, Kit-Migration Welle 1):
   Typo-Kopf, Fließtext-Kanon und Sprungmarken für impressum, agb,
   datenschutz, widerrufsbelehrung und faqs. Read-Mode: Struktur dient dem
   Verständnis, die Bühne bleibt ruhig.
   ========================================================================== */

/* E26 — PageHero-Variante „plain": Titel + Standzeile zentriert auf der
   hellen Bühne, ohne Solo-Motiv und ohne Split, kompakteres Padding. Der
   alte dunkle Foto-page-hero der Rechtsseiten (BP_HERO_BG) entfällt. */
.bp-page-hero--plain { padding-block: var(--space-16); }
/* v2.60.0 (Chris 31.08.): die __inner-min-height 400 (Finaljustage für die
   Split-Heroes) erzeugte auf den motivlosen plain-Heroes ~200px Leerraum
   UNTER dem Titel (display:block hebt das Zentrieren auf) — hier zurücknehmen. */
.bp-page-hero--plain .bp-page-hero__inner { display: block; text-align: center; min-height: 0; }
.bp-page-hero--plain .bp-page-hero__title { margin-inline: auto; font-size: var(--text-hero-page-sm); }
.bp-page-hero--plain .bp-page-hero__sub { margin-inline: auto; }

/* E27 — bp-prose: Fließtext-Kanon für lange Lesetexte. Headings laufen in
   der Raveo-Staffel der Typoklassen, Copy im Body-Kanon, alles im
   Lese-Maß. Ersetzt die alte .prose (Geist-Ära) auf den Rechtsseiten —
   die Texte selbst bleiben wortgleich. */
.bp-prose {
  max-width: var(--measure);
  margin-inline: auto;
  color: var(--color-text);
}
.bp-prose > * + * { margin-top: var(--space-6); }
.bp-prose h2,
.bp-prose h3,
.bp-prose h4 {
  font-family: var(--font-display);
  line-height: var(--display-lh);
  letter-spacing: var(--display-ls);
  color: var(--color-text);
  text-wrap: balance;
}
.bp-prose h2 {
  margin-top: var(--space-16);
  font-size: var(--text-h4-sm);
  font-weight: var(--text-h4-sm-wght);
  font-variation-settings: "opsz" 16, "wght" var(--text-h4-sm-wght);
}
.bp-prose h3 {
  margin-top: var(--space-12);
  font-size: var(--text-h6);
  font-weight: var(--text-h6-wght);
  font-variation-settings: "opsz" 16, "wght" var(--text-h6-wght);
}
.bp-prose h4 {
  margin-top: var(--space-10);
  font-size: var(--text-lg);
  font-weight: var(--text-h6-wght);
  font-variation-settings: "opsz" 16, "wght" var(--text-h6-wght);
}
.bp-prose > h2:first-child { margin-top: 0; }
.bp-prose strong { font-weight: var(--strong-wght); color: var(--color-text); }
.bp-prose a { color: var(--teal-deep); text-decoration: underline; text-underline-offset: 0.15em; }
.bp-prose a:hover { color: var(--color-text); }
.bp-prose ul, .bp-prose ol { padding-left: 1.25em; }
.bp-prose ul { list-style: disc; }
.bp-prose ol { list-style: decimal; }
.bp-prose li { margin-block: 0.35em; }
.bp-prose li::marker { color: var(--teal-deep); }
.bp-prose hr { border: 0; border-top: 1px solid var(--color-border); margin-block: var(--space-12); }
.bp-prose table { width: 100%; border-collapse: collapse; font-size: var(--text-lg); }
.bp-prose th, .bp-prose td { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--color-border); text-align: left; vertical-align: top; }
.bp-prose th { font-weight: var(--strong-wght); }
/* Hervorgehobener Block (z. B. Muster-Widerrufsformular): ruhige
   Sunken-Karte im Lesefluss. */
.bp-prose__box {
  margin-top: var(--space-12);
  padding: var(--card-pad);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-card-sm);
}
.bp-prose__box > :first-child { margin-top: 0; }

/* E28 — bp-toc: Sprungmarken der langen Rechtsseiten — schlanke
   Sunken-Karte im Lese-Maß, vor dem ersten Prose-Block. */
.bp-toc {
  max-width: var(--measure);
  margin: 0 auto var(--space-16);
  padding: var(--card-pad);
  background: var(--color-surface-sunken);
  border-radius: var(--radius-card-sm);
}
.bp-toc p {
  margin: 0 0 var(--space-4);
  font-family: var(--font-display);
  font-size: var(--text-h6);
  font-weight: var(--text-h6-wght);
  font-variation-settings: "opsz" 16, "wght" var(--text-h6-wght);
  line-height: var(--display-lh);
}
.bp-toc ol { margin: 0; padding-left: 1.25em; list-style: decimal; }
.bp-toc li { margin-block: 0.3em; }
.bp-toc li::marker { color: var(--teal-deep); }
.bp-toc a { color: var(--color-text); text-decoration: none; }
.bp-toc a:hover { color: var(--teal-deep); text-decoration: underline; text-underline-offset: 0.15em; }

/* E28-Zusatz — Standalone-FAQ-Seite: das Akkordeon läuft einspaltig im
   FAQ-Maß. Bewusste Ausnahme vom Zweispalter-Kanon der Themenseiten —
   der Seitenkopf ist hier bereits der Hero. */
.bp-accordion--page { max-width: var(--measure-faq); margin-inline: auto; }

/* ============================================================================
   8 — E34 · BP-BUYBOX (Produkt-Kaufbühne, 31.08.2026)
   ----------------------------------------------------------------------------
   Der Seiteneinstieg der Produktseiten (Chris-Entscheid 31.08.: die Buybox IST
   der Hero — kein vorgeschalteter Marketing-PageHero). Bühne = exakt die
   E13d-Studio-Anatomie (randvoll via .bp-bleed, --hero-surface, radius-card,
   10px Luft zum Header). Split: Galerie links, Kaufspalte rechts; unter
   1000 px einspaltig mit Galerie zuerst. Metriken der Kaufspalte sind der
   Chris-justierte Live-Kanon v2.29/v2.32 (Titel, Preis, Streichpreis-Rot,
   Ampel-Punkt) — hier nur systematisiert. Galerie-Hauptfläche ist eine
   bp-media-frame; Zahlarten laufen als bp-pay-icons (Regel 12).
   ========================================================================== */

.bp-buybox {
  margin-top: 10px; /* wie bp-page-hero: Luft zum Header */
  position: relative;
  overflow: hidden;
  padding-block: var(--space-16);
  border-radius: var(--radius-card);
  background: var(--hero-surface);
  color: var(--color-text);
}
.bp-buybox__inner {
  position: relative;
  margin-inline: auto;
  max-width: var(--hero-inner-max); /* Live-Deckel 80rem — wie die alte .v-inner der Buybox */
  display: grid;
  /* Spaltenteilung + Gap = 1:1 der Live-Buybox (.bp-order-grid, /bestellen/-Parität) */
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  align-items: start;
  gap: clamp(24px, 4.5vw, 72px);
  padding: 0 clamp(24px, 5vw, 72px);
}

/* --- Galerie: 1:1 der Live-Buybox (/bestellen/-Struktur) ------------------
   Hauptbild quadratisch und randlos auf der Bühne (kein Paper-Rahmen),
   Funnel-Radius 14/12 (Chris v2.28.1), Thumbs quadratisch im 4er-Raster,
   nicht sticky. */
.bp-buybox__gallery .bp-media-frame {
  border-radius: var(--radius-funnel);
  aspect-ratio: 1 / 1;
  background: transparent;
}
.bp-buybox__thumbs {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  padding: 0;
  margin: var(--space-4) 0 0;
}
.bp-buybox__thumb {
  display: block;
  width: 100%;
  padding: 0;
  overflow: hidden;
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-funnel-sm);
  background: var(--paper);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.bp-buybox__thumb img { display: block; width: 100%; height: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.bp-buybox__thumb:hover { border-color: var(--color-border-strong); }
.bp-buybox__thumb:active { transform: scale(var(--press-scale)); transition-duration: var(--dur-press); }
.bp-buybox__thumb.is-active { border-color: var(--teal-deep); }

/* --- Kaufspalte ----------------------------------------------------------- */
.bp-buybox__title {
  margin: 0;
  font-family: var(--font-hero-upper);
  font-weight: var(--hero-title-wght);
  font-size: var(--text-buybox-title);
  line-height: var(--buybox-title-lh);
  letter-spacing: var(--hero-title-ls);
  -webkit-text-stroke: var(--hero-title-stroke) currentColor;
}
.bp-buybox__rating {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
  color: var(--color-text);
  text-decoration: none;
  font-size: var(--text-xs);
  font-weight: var(--strong-wght);
}
.bp-buybox__rating:hover .bp-buybox__rating-value { text-decoration: underline; text-underline-offset: 0.15em; }
.bp-buybox__stars { display: inline-flex; color: var(--star); letter-spacing: var(--star-ls); }
.bp-buybox__rating .bp-avatar-stack { margin-left: var(--space-2); }
.bp-buybox__sub { margin: var(--space-5) 0 0; max-width: var(--measure); }

/* USP-Checkliste: zwei Spalten, Teal-Check im runden Chip */
.bp-buybox__usps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4) var(--space-6);
  padding: 0;
  margin: var(--space-6) 0 0;
}
.bp-buybox__usps li { display: flex; align-items: flex-start; gap: var(--space-4); font-size: var(--text-xs); line-height: var(--xs-lh); }
.bp-buybox__usps li.is-wide { grid-column: 1 / -1; }
.bp-buybox__usps strong { display: block; font-weight: var(--strong-wght); }
.bp-buybox__usps .sub { display: block; margin-top: 2px; color: var(--color-text-muted); }
.bp-buybox__check {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--size-icon-sm);
  height: var(--size-icon-sm);
  margin-top: 1px; /* optische Fluchtlinie zur ersten Textzeile */
  border-radius: var(--radius-circle);
  background: var(--teal-10);
  color: var(--teal-deep);
}

/* Variantenwahl: Eingabe-Kacheln (radius-tile), aktive Karte in Teal */
.bp-buybox__variants { margin: var(--space-8) 0 0; padding: 0; border: 0; }
.bp-buybox__variants-legend {
  padding: 0;
  margin-bottom: var(--space-4);
  font-size: var(--text-xs);
  font-weight: var(--strong-wght);
}
.bp-buybox__variant-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); }
.bp-buybox__variant {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-3);
  text-align: center;
  border: var(--border-w) solid var(--color-border);
  border-radius: var(--radius-tile);
  background: var(--paper);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.bp-buybox__variant input { position: absolute; opacity: 0; pointer-events: none; }
.bp-buybox__variant:hover { border-color: var(--color-border-strong); }
.bp-buybox__variant:active { transform: scale(var(--press-scale)); transition-duration: var(--dur-press); }
.bp-buybox__variant.is-active { border-color: var(--teal-deep); background: var(--teal-10); }
.bp-buybox__variant:focus-within { outline: 2px solid var(--color-focus); outline-offset: var(--focus-offset); }
.bp-buybox__variant-name { font-size: var(--text-xs); line-height: var(--xs-lh); font-weight: var(--strong-wght); }
.bp-buybox__variant-price { font-size: var(--text-xs); color: var(--color-text-muted); }
.bp-buybox__variant-badge {
  position: absolute;
  top: calc(var(--space-3) * -1);
  right: var(--space-3);
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--teal-deep);
  color: var(--paper);
  font-size: var(--text-pay-pill);
  font-weight: var(--strong-wght);
  line-height: var(--control-lh);
}
.bp-buybox__variant-desc { margin: var(--space-4) 0 0; font-size: var(--text-xs); color: var(--color-text-muted); }

/* Preiszeile: Verkaufspreis + roter Streichpreis, rechts MwSt/Lager */
.bp-buybox__price-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
  margin-top: var(--space-8);
}
.bp-buybox__price-block { display: flex; align-items: baseline; gap: var(--space-4); }
.bp-buybox__price {
  font-size: var(--text-price);
  font-weight: var(--text-price-wght);
  letter-spacing: var(--price-ls);
  font-variant-numeric: tabular-nums;
  line-height: var(--control-lh);
  color: var(--color-text);
}
.bp-buybox__price-reg { font-size: var(--text-base); color: var(--price-cut); text-decoration: line-through; }
.bp-buybox__price-meta { text-align: right; font-size: var(--text-hero-trust); color: var(--color-text-muted); }
.bp-buybox__stock { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-3); margin: 2px 0 0; }
.bp-buybox__stock-dot {
  flex: 0 0 auto;
  width: 10px; height: 10px; /* Live-Kanon des Lager-Punkts */
  border-radius: var(--radius-circle);
  background: var(--ok);
  box-shadow: 0 0 0 4px var(--ok-ring);
  animation: bp-stock-pulse var(--dur-pulse) var(--ease) infinite;
}
@keyframes bp-stock-pulse {
  0%, 100% { box-shadow: 0 0 0 4px var(--ok-ring); }
  50%      { box-shadow: 0 0 0 6px var(--ok-ring-soft); }
}
@media (prefers-reduced-motion: reduce) { .bp-buybox__stock-dot { animation: none; } }

/* Kauf-CTA: der bp-btn-Kanon in voller Spaltenbreite, danach bp-pay-icons */
.bp-buybox__buy { margin-top: var(--space-6); }
.bp-buybox__buy .bp-btn { display: flex; width: 100%; justify-content: space-between; }
.bp-buybox .bp-pay-icons { margin-top: var(--space-5); justify-content: center; }

/* Trust-Trio unter der Kaufstrecke — still, --text-xs, Ink-Icons */
.bp-buybox__trust {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  padding: var(--space-6) 0 0;
  margin: var(--space-6) 0 0;
  border-top: var(--border-w) solid var(--color-border);
}
.bp-buybox__trust li {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-xs);
  line-height: var(--xs-lh);
  font-weight: var(--strong-wght);
}
.bp-buybox__trust svg { flex: 0 0 auto; color: var(--teal-deep); }

/* --- Mobil: einspaltig ab 900 (Live-Breakpoint der alten .bp-order-grid),
   Galerie zuerst, Varianten im Zweierraster --------------------------------- */
@media (max-width: 900px) {
  .bp-buybox__inner { grid-template-columns: 1fr; gap: var(--space-8); }
  .bp-buybox__variant-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bp-buybox__price-row { align-items: flex-start; flex-direction: column; }
  .bp-buybox__price-meta { text-align: left; }
  .bp-buybox__stock { justify-content: flex-start; }
  /* Pay-Icons werden unter 768 zum Kit-nowrap-Scroller — zentriert wäre dessen
     linker Rand unerreichbar (centered-overflow), deshalb mobil linksbündig. */
  .bp-buybox .bp-pay-icons { justify-content: flex-start; }
}
@media (max-width: 560px) {
  /* Live-Kanon: Hauptbild links, Thumbs als 64px-Spalte rechts daneben */
  .bp-buybox__gallery { display: grid; grid-template-columns: minmax(0, 1fr) 64px; gap: var(--space-4); align-items: start; }
  .bp-buybox__thumbs { grid-template-columns: 1fr; margin: 0; }
  .bp-buybox__usps { grid-template-columns: 1fr; }
  .bp-buybox__trust { grid-template-columns: 1fr; }
}
