/* Adventure Park — gemeinsame Design-Schicht fuer ALLE Landingpages.
   Aenderungen hier gelten fuer /, /quad und spaeter /paintball.
   Seiten-spezifisches bleibt im <style> der jeweiligen Seite.
   Quelle: aus index.html extrahiert am 25.08.2026. */


/* Barlow und Barlow Condensed selbst gehostet — gezogen von Google Fonts am
   27.08.2026, nur das latin-Subset (deckt Deutsch samt „ " — € · ab).
   Grund: die zwei fremden Hosts fonts.googleapis.com und fonts.gstatic.com
   kosteten je einen DNS- und TLS-Handschlag auf dem kritischen Pfad
   (zusammen ~110 ms) und 7 Anfragen. Nebeneffekt: der Datenschutz-Punkt
   "Google Fonts laedt IP-Adressen zu Google" faellt damit weg.
   font-display:swap bleibt; die Fallback-Metriken weiter unten in dieser Datei
   fangen den Reflow beim Tausch ab. */

@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/barlow-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-condensed-700-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-condensed-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-condensed-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-condensed-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

  * { margin:0; padding:0; box-sizing:border-box; }

  /* ---------- Gegen-Reset: das SYN-Buchungsbundle bringt normalize.css mit ----------
     `booking-form.bundle.css` wird erst nachgeladen, wenn #buchen naeher kommt, und
     ist NICHT auf das Widget gescoped: seine nackten Element-Regeln (Spezifitaet
     0,0,1) schlagen unser `*` (0,0,0) und aendern MITTEN IM SCROLLEN das Layout.
     Nachgewiesen am 27.08. mit einem Seiten-Diff mit/ohne Bundle:
       figure   margin 0 -> 1em 40px   (jede Stimmen-Karte 80px schmaler, Grid +66px)
       h1       margin 0 -> .67em 0    (Hero-Headline springt ~74px nach unten)
       button   font sans-serif/100%/1.15 statt geerbt (Play-Knopf, .btn-Hoehen 1px)
     Deshalb dieselben Werte hier mit drei Element-Selektoren (0,0,3): schlaegt
     normalize unabhaengig von der Ladereihenfolge, bleibt aber unter jeder
     eigenen Klassenregel (0,1,0). Im Widget-Baum #rb-slot gilt normalize weiter —
     dort ist das Bundle zustaendig, nicht wir. */
  html body figure,
  html body h1,
  html body button,
  html body input,
  html body select,
  html body textarea { margin:0; }
  html body button,
  html body input,
  html body select,
  html body textarea { font-family:inherit; font-size:inherit; line-height:inherit; }
  #rb-slot button, #rb-slot input, #rb-slot select, #rb-slot textarea {
    font-family:sans-serif; font-size:100%; line-height:1.15;
  }
  :root {
    /* Vertikale Dichte aller Section-Abstaende. 1 = Originalwerte,
       0.9 = 10% kompakter (Rosty 25.08.), 0.75 = 25% kompakter (Rosty 01.09.:
       "alle Sections auf allen Seiten haben ein bisschen zu viel Abstand, oben
       vor der orangen Ueberschrift"). Die px-Werte in den Regeln bleiben als
       Originalmass stehen, damit man sieht wovon skaliert wird.
       Wirkung auf 1440px: .act 70 -> 59px, .maps 79 -> 66px, .voices 67 -> 56px. */
    --sy:0.75;

    --ink:#161513; --ink2:#4d4a45; --muted:#6f6a63;
    --bg:#ffffff; --bg-alt:#f4f2ee; --line:#e7e3dc;
    --orange:#d66001; --orange-deep:#a94c00; --tint:#fbf0e4; --tint-line:#f0d9bd;
    --wa:#177f3d;
    --r:18px;
  }
  html { scroll-behavior:smooth; scroll-padding-top:81px; }

  /* ---------- Fallback-Metriken fuer Barlow (gegen Reflow beim Font-Swap) ----------
     DIES war die echte Ursache hinter "Stimmen-Section aendert Formatierung
     kurz nach dem Scrollen" (27.08.): nicht .voices selbst, sondern .price
     (Barlow Condensed, 44px/700) direkt darueber in .kcard/.pack. Barlow/
     Barlow Condensed laden mit font-display:swap (<link> im <head> jeder
     Seite); bis das Webfont da ist, rendert der Browser mit der System-
     Schrift. .price steht mit .price-old in einer Flex-Reihe — im (viel
     breiteren) Fallback bricht die Reihe zweizeilig um, mit Barlow Condensed
     (nicht condensed in der Fallback-Schrift!) passt sie einzeilig. Beim
     Font-Swap faellt .price-row dadurch von 80px auf 45px, das schiebt die
     ganze Karte und alles darunter — inklusive .voices — 35px nach oben.
     Nachgewiesen mit der Layout-Instability-API (.voices taucht als Shift-
     Quelle auf) und mit gezielt per Playwright verzoegerten Font-Requests
     (Karten-Hoehe vor/nach Swap gemessen, kein Screenshot-Raten). size-adjust
     gleicht die Fallback-Breite an Barlow an: Barlow Condensed 700 ist
     ~68-70% der Arial-Breite, normales Barlow 400/500 ~96%, 600/700 ~91-92%
     (Canvas measureText, nicht geschaetzt) —
     daher zwei Font-Faces mit eigenem font-weight-Bereich statt einem
     Mittelwert. Das behebt den .price-row-Umbruch vollstaendig (geprueft:
     Karten-Hoehe vor/nach Swap nur noch ±1px statt 35px). Es ist KEINE
     Garantie gegen jeden denkbaren Zeilenumbruch — size-adjust skaliert
     gleichmaessig, echtes Kerning tut das nicht: eine einzelne lange
     Mischtext-Zeile ("4 Stunden Spielzeit auf 15 Themenfeldern" in
     .stack li) bricht auf /paintball weiterhin unterschiedlich, weil Barlow
     dafuer laut Canvas-Messung sogar MEHR Platz braucht als unadjustiertes
     Arial — kein size-adjust-Wert zwischen 80-100% loest das (durchgetestet).
     Das ist ein Copy-/Breitenproblem, kein Font-Metrik-Problem, und bewusst
     nicht angefasst (Content ist nicht meine Entscheidung). local() zuerst —
     ohne passende lokale Schrift greift die Kette einfach weiter zu
     -apple-system/system-ui/sans-serif wie bisher. */
  @font-face {
    font-family:'Barlow Fallback';
    src:local('Arial');
    font-weight:400 500;
    size-adjust:96%;
  }
  @font-face {
    font-family:'Barlow Fallback';
    src:local('Arial');
    font-weight:600 700;
    size-adjust:92%;
  }
  @font-face {
    font-family:'Barlow Condensed Fallback';
    src:local('Arial');
    size-adjust:68%;
  }
  body {
    font-family:'Barlow','Barlow Fallback',-apple-system,system-ui,sans-serif;
    color:var(--ink); background:var(--bg);
    -webkit-font-smoothing:antialiased; line-height:1.55; font-size:16.5px;
    -webkit-tap-highlight-color:transparent;
    overscroll-behavior-y:contain;
  }
  img { max-width:100%; display:block; }
  a { color:inherit; text-decoration:none; }
  button, a { touch-action:manipulation; }
  .wrap { max-width:1140px; margin:0 auto; padding:0 20px; }

  
/* ---------- Grain (statisches Korn, self-contained SVG-Data-URI, ~0 Kosten) ---------- */
  #grain {
    position:fixed; inset:0; z-index:90; pointer-events:none; opacity:0.05;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  
/* ---------- Type ---------- */
  .disp {
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-weight:700; font-style:italic;
    letter-spacing:0; line-height:0.98;
  }
  .tag {
    display:inline-block; background:var(--orange); color:#fff;
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-weight:700; font-size:19px;
    text-transform:uppercase; letter-spacing:0.03em;
    padding:4px 12px 5px; border-radius:5px; transform:skewX(-8deg);
    margin-bottom:16px;
  }
  .tag > span { display:inline-block; transform:skewX(8deg); }
  .boxed {
    display:inline-block; background:var(--orange); color:#fff;
    padding:0 14px 3px; border-radius:6px; transform:skewX(-6deg) rotate(-0.5deg);
  }
  .boxed > span { display:inline-block; transform:skewX(6deg); }
  .nb { white-space:nowrap; }
  /* Unter 390 px darf die Kastenzeile umbrechen und die Headline wird kleiner —
     sonst steht "Zwölf Abenteuer." bei 320 px 52 px ueber den Rand und die
     Seite laesst sich seitlich wegwischen (Falle 18). .has-video, damit die
     Regel die Seiten-Ueberschreibungen im <style> schlaegt. */
  @media(max-width:389px){
    .head-sec.has-video h1 .nb { white-space:normal; }
    .head-sec.has-video h1 { font-size:clamp(42px,13.5vw,54px); }
  }
  /* Wundertuete: gezeichnete Marke statt Icon-Kachel. Zugedreht — man sieht
     nicht hinein, und genau das soll neugierig machen. */
  .gift { display:block; width:104px; margin:0 auto 12px; }
  .gift img { width:100%; height:auto; display:block; }
  .wa-row .gift { width:124px; margin-bottom:18px; }

  
  /* Zielgruppen-Decals: gleiche Handschrift wie .tag/.boxed (Skew, Condensed,
     Versalien, harte Kante), aber Tint-Flaeche statt Orange — vier vollflaechig
     orange Marken wuerden neben der .boxed-Headline um dieselbe Aufmerksamkeit
     kaempfen. Rotation variiert pro Chip, sonst liest sich die Reihe wieder
     wie ein UI-Element statt wie aufgeklebt. */
  .chips { display:flex; flex-wrap:wrap; gap:9px; }
  .chip {
    display:inline-block; background:var(--tint); color:var(--orange-deep);
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-weight:700; font-size:17px;
    text-transform:uppercase; letter-spacing:0.03em;
    padding:4px 12px 5px; border-radius:5px; transform:skewX(-6deg) rotate(-0.9deg);
  }
  .chip > span { display:inline-block; transform:skewX(6deg); }
  .chip:nth-child(2) { transform:skewX(-6deg) rotate(0.7deg); }
  .chip:nth-child(3) { transform:skewX(-6deg) rotate(-0.4deg); }
  .chip:nth-child(4) { transform:skewX(-6deg) rotate(1.1deg); }
  .uline { position:relative; display:inline-block; }
  .uline svg {
    position:absolute; left:0; width:100%; height:clamp(6px,0.17em,14px); bottom:-0.1em;
    color:var(--orange); overflow:visible;
  }
/* ---------- Buttons ---------- */
  .btn {
    display:inline-flex; align-items:center; gap:12px;
    background:var(--ink); color:#fff; border:none; cursor:pointer;
    font-family:'Barlow','Barlow Fallback',sans-serif; font-size:14.5px; font-weight:700; letter-spacing:0.04em; text-transform:uppercase;
    padding:9px 9px 9px 24px; border-radius:999px; transition:box-shadow .15s ease;
    position:relative;
  }
  .btn:hover { transform:translateY(-1px); box-shadow:0 8px 22px rgba(0,0,0,0.18); }
  .btn .arr {
    width:34px; height:34px; border-radius:50%; background:var(--orange);
    display:flex; align-items:center; justify-content:center; flex-shrink:0;
  }
  .btn .arr svg { width:15px; height:15px; }
  .btn.wa { background:var(--wa); }
  .btn.wa .arr { background:rgba(255,255,255,0.22); }
  .btn.light { background:#fff; color:var(--ink); }
  .btn.ghost { background:transparent; border:1.5px solid var(--line); color:var(--ink); padding:12px 24px; }
  .btn.ghost:hover { border-color:var(--ink); box-shadow:none; }

  
/* ---------- Nav ---------- */
  #nav {
    position:fixed; top:0; left:0; right:0; z-index:50;
    background:rgba(255,255,255,0.96);
    border-bottom:1px solid transparent; transition:border-color .2s, box-shadow .2s;
  }
  #nav.scrolled { border-bottom-color:var(--line); box-shadow:0 2px 14px rgba(0,0,0,0.05); }
  /* Kein zusaetzliches scroll-margin hier: html{scroll-padding-top:81px} oben
     erledigt das bereits; beides zusammen addiert sich und schiebt zu weit. */
  .nav-inner { display:flex; align-items:center; justify-content:space-between; height:66px; }
  .nav-logo img { height:44px; width:auto; }
  .nav-cta { padding:7px 7px 7px 18px; font-size:13px; }
  .nav-cta .arr { width:30px; height:30px; }

  
/* ---------- Hero mit Video-Hintergrund (Luc 07.09.) ----------
   hero.mp4 ist 1080x1920, also hochkant. Im alten 16:9-Kasten (.video-sec,
   entfernt) schnitt object-fit:cover oben und unten je rund ein Drittel weg.
   Als Hero-Hintergrund traegt das Video sein eigenes Format, auf dem Handy
   formatfuellend.
   Der Text liegt darauf, also braucht er einen Verlauf darunter: unten deckt
   er am staerksten, weil dort Kicker, Headline und Fliesstext sitzen. Oben
   bleibt er duenn, damit vom Bild etwas zu sehen ist — der Header ist ohnehin
   weiss und deckt die oberen Pixel ab. */
  .head-sec.has-video {
    position:relative; isolation:isolate;
    min-height:min(92svh, 860px);
    display:flex; flex-direction:column; justify-content:space-between;
    padding-bottom:calc(30px * var(--sy));
    color:#fff;
  }
  /* Kopf oben, Merkmale unten am Bildrand, dazwischen laeuft das Bild (Luc
     07.09.). Vorher stand alles als Block unten und deckte die untere Haelfte. */
  .head-sec.has-video .hero-fuss { margin-top:auto; }
  /* overflow gehoert an den Hintergrund, nicht an die Section: lag es oben,
     schnitt es bei knapper Bauhoehe die letzte Chip-Zeile ab (gesehen auf
     390x844). So waechst der Hero stattdessen mit seinem Inhalt. */
  .hero-bg { position:absolute; inset:0; z-index:0; overflow:hidden; background:#0d0c0b; }
  .hero-bg video {
    width:100%; height:100%; object-fit:cover; object-position:center 42%; display:block;
    /* Gedimmt statt voll: das Video ist Hintergrund, nicht Inhalt (Rosty 08.09.).
       Je Seite ueber --hero-vid-o gesetzt, gemessen gegen den hellsten Frame. */
    opacity:var(--hero-vid-o, 1);
  }
  .hero-scrim {
    position:absolute; inset:0; display:block;
    /* Zwei Zonen statt einer: Text steht oben, die Merkmale unten, das Bild
       laeuft in der Mitte durch. Seit 08.09. haben alle drei Seiten die
       Ein-Satz-Unterzeile (Text endet bei ~44 %), also gilt ueberall der
       kurze Verlauf, den Luc am 07.09. fuer /paintball gemessen hat. Dazu
       liegt das Video selbst gedimmt (--hero-vid-o, je Seite gemessen mit
       tools/hero-kontrast.py) — der Verlauf ist deshalb oben von 0.84 auf 0.74
       zurueckgenommen: Video 0.62 x Rest 0.26 = dieselbe Sichtbarkeit wie vorher
       1.0 x 0.16, nur dass jetzt auch die freie Mitte gedimmt ist. Gemessen gegen
       den hellsten Frame: Kicker/Unterzeile >= 11:1, bei opacity 1.0 noch >= 7,6:1.
       ⚠ /paintball spiegelt den Verlauf am Handy (Text unten links, 17.09.) —
       Override im <style> der Seite, gemessen 12:1 / 13:1. */
    background:linear-gradient(to bottom,
      rgba(8,7,6,0.78) 0%, rgba(8,7,6,0.74) 20%, rgba(8,7,6,0.66) 42%,
      rgba(8,7,6,0.20) 50%, rgba(8,7,6,0.14) 84%, rgba(8,7,6,0.18) 100%);
  }
  .head-sec.has-video .wrap { position:relative; z-index:1; width:100%; }
  .head-sec.has-video h1 { color:#fff; }
  .head-sec.has-video .pin-row { color:rgba(255,255,255,0.90); }
  /* Orange auf dem dunklen Verlauf kaeme nur auf rund 3,4:1 — als Strichicon
     zulaessig, aber hier steht es neben hellem Text. Aufgehellt auf #ffb066,
     damit Zeile und Icon dieselbe Helligkeit halten. */
  .head-sec.has-video .pin-row svg { color:#ffb066; }
  .head-sec.has-video .head-sub { color:rgba(255,255,255,0.92); }
  /* Chips und die orange Box bringen ihren eigenen Hintergrund mit und bleiben
     damit unveraendert lesbar — nicht anfassen. */

  .hero-pause {
    position:absolute; right:14px; bottom:14px; z-index:2;
    width:38px; height:38px; border-radius:999px; border:none; cursor:pointer;
    background:rgba(10,9,8,0.55); -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
    color:#fff; display:grid; place-items:center; padding:0;
  }
  .hero-pause svg { width:16px; height:16px; }
  .hero-pause:hover { background:rgba(10,9,8,0.78); }

  @media(min-width:920px){
    .head-sec.has-video { min-height:min(86svh, 800px); }
  }
  /* Wer Bewegung abbestellt hat, bekommt das Standbild. */
  @media (prefers-reduced-motion: reduce) {
    .hero-bg video { display:none; }
    /* Poster kommt je Seite als Variable am <section> (--hero-poster-tall/-wide).
       ⚠ Der Pfad darin muss absolut sein (/assets/...): Chrome loest url() in
       einer Custom Property relativ zu DIESER Datei auf, nicht zum HTML —
       ein relatives assets/... wurde zu assets/assets/... (404, Sweep 08.09.). */
    .hero-bg { background:#0d0c0b var(--hero-poster-tall) center 42%/cover no-repeat; }
    @media(min-width:920px){ .hero-bg { background-image:var(--hero-poster-wide); } }
    .hero-pause { display:none; }
  }


/* ---------- Hero-Ausrichtung ----------
   Mobil linksbuendig (Lesefluss), ab Tablet mittig: der Player darunter ist
   ohnehin zentriert, eine linke Headline daneben kippt die Seite. (Rosty 27.08.) */
  @media(min-width:920px){
    .head-sec .wrap { text-align:center; }
    .head-sec .pin-row { justify-content:center; }
    .head-sec h1 { margin-left:auto; margin-right:auto; }
    .head-sec .head-sub { margin-left:auto; margin-right:auto; }
    .head-sec .chips { justify-content:center; }
  }
  

/* ---------- Hero ----------
   Oben strukturell: haelt den Hero unter der fixierten Kopfzeile frei.
   --nav-h wird per JS aus der echten Hoehe gesetzt (67 px ohne JS; die
   Fortschrittsleiste ist seit 29.09.2026 weg). Unten skaliert normal mit --sy. */
  .head-sec { padding:calc(var(--nav-h, 67px) + 14px) 0 calc(30px * var(--sy)); }
  .pin-row { display:flex; align-items:center; gap:8px; font-size:16px; font-weight:600; color:var(--ink2); margin-bottom:14px; }
  .pin-row svg { width:17px; height:17px; color:var(--orange); flex-shrink:0; }
  .head-sec h1 { font-size:clamp(54px,10vw,110px); margin-bottom:16px; }
  .head-sec h1 .l1 { display:block; }
  /* SplitText legt um jedes Wort eine Maske mit inline `overflow:clip`, genau
     so hoch wie die Zeile. Bei line-height 0.98 haengt die Unterlaenge von
     g/j/y/p darunter und wurde abgeschnitten („gewinnt", Rosty 27.08.).
     Die Maske bekommt unten Luft, der negative Margin nimmt den Zuwachs fuer
     das Layout wieder raus — Zeilenabstand bleibt also unveraendert.
     Padding statt overflow:visible, weil die Maske sonst ihren Zweck verliert;
     0.12em ist klein genug, dass das Wort im Startzustand (yPercent 120)
     immer noch komplett unter der Kante steht. */
  .head-sec h1 .l1 > div { padding-bottom:0.12em; margin-bottom:-0.12em; }
  .head-sec h1 .l2 { display:inline-block; margin-top:6px; }
  .head-sub { font-size:clamp(17px,2.4vw,20px); font-weight:500; max-width:54ch; color:var(--ink2); margin-bottom:20px; }


/* ---------- WhatsApp-Section (Variante B: im Fluss) ---------- */
  .wa-row { text-align:center; padding:calc(74px * var(--sy)) 0 calc(68px * var(--sy)); }
  .wa-row h2 { font-size:clamp(30px,4.6vw,44px); margin-bottom:18px; }
  .wa-row .btn { font-size:15.5px; padding:12px 12px 12px 28px; }
  .wa-row .btn .arr { width:40px; height:40px; }
  .wa-row .btn .arr svg { width:19px; height:19px; }
  .wa-sub { font-size:14.5px; color:var(--muted); margin-top:12px; }

/* ---------- Uebergang Hero -> Zahlenband (Luc 07.09.) ----------
   Vorher standen in vierzig Pixeln drei Zustaende uebereinander: dunkles
   Video, weisser Spalt (margin-top am .stats), oranges Band. Genau der
   weisse Streifen dazwischen machte den Schnitt hart.
   Jetzt drei Schritte, die ineinander laufen: das Video wird nach unten
   ausmaskiert und verschwindet in der dunklen Grundflaeche des Heros, der
   Spalt entfaellt, und das Orange entsteht aus derselben Dunkelheit heraus.
   Der Verlauf sitzt im Zahlenband, nicht im Hero — sonst faerbte er die
   Chips an, die unten im Hero stehen. */
  .head-sec.has-video ~ .stats { margin-top:0; position:relative; isolation:isolate; }

  /* Das Video selbst blendet aus, nicht nur der Scrim darueber. Ab 58 % der
     Hoehe, also deutlich unterhalb der Headline. */
  .hero-bg video {
    -webkit-mask-image:linear-gradient(to bottom, #000 84%, rgba(0,0,0,0.55) 94%, rgba(0,0,0,0) 100%);
            mask-image:linear-gradient(to bottom, #000 84%, rgba(0,0,0,0.55) 94%, rgba(0,0,0,0) 100%);
  }

  .head-sec.has-video ~ .stats::before {
    content:''; position:absolute; left:0; right:0; top:0; height:140px; z-index:0;
    background:linear-gradient(to bottom,
      rgba(8,7,6,0.96) 0%, rgba(8,7,6,0.78) 26%, rgba(8,7,6,0.44) 56%, rgba(8,7,6,0) 100%);
    pointer-events:none;
  }
  /* Die Zahlen liegen ueber dem Verlauf und bekommen oben Luft, damit sie
     nicht in der dunklen Zone stehen. */
  .head-sec.has-video ~ .stats .stats-grid {
    position:relative; z-index:1; padding-top:calc(72px * var(--sy));
  }


/* ---------- Stats (orange) ---------- */
  .stats { background:var(--orange); color:#fff; margin-top:calc(40px * var(--sy)); }
  .stats-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:36px 16px; padding:calc(44px * var(--sy)) 0; }
  @media(min-width:800px){ .stats-grid { grid-template-columns:repeat(4,1fr); } }
  .stat { text-align:center; }
  .stat .num { font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-style:italic; font-weight:700; font-size:clamp(34px,4.6vw,50px); line-height:1; }
  .num-row { display:flex; align-items:baseline; justify-content:center; gap:8px; }
  .num-suffix { font-size:clamp(22px,2.9vw,31px); line-height:1; }
  /* 19px liessen "5-Sterne-Bewertungen" unter 430 px Breite umbrechen — die
     eine Zelle wurde dadurch hoeher als die anderen, und die Reihe darunter
     verrutschte (Luc 07.09.: "bischen gequetscht"). Gemessen passt die
     laengste Beschriftung ab 15px in eine Zeile, bei 172px Zellenbreite auf
     dem kleinsten geprueften Geraet. Am Desktop bleibt es bei 19px. */
  /* Zweite Runde (Luc 07.09., "sieht noch gequetscht aus, Subtexte kleiner"):
     die erste Stufe auf 15-19 px reichte ihm nicht. Jetzt 13-15 px und
     halbfett statt fett — die Zahl soll tragen, die Zeile darunter nur
     erklaeren. Dazu mehr Luft zwischen Zahl und Zeile und zwischen den
     Reihen. */
  .stat .lbl {
    font-size:clamp(13px, 3.4vw, 15px); font-weight:600; color:rgba(255,255,255,0.92);
    margin-top:8px; line-height:1.3; letter-spacing:0.01em;
  }

  

  /* ---------- Stimmen (Trust nach der Buchung) ----------
     Decal-Sprache wie .chip/.tag. Sterne GELB nach .claude/rules/brand.md
     (#f2b01e Fuellung, #b8860b Kontur) - bewusst nicht Orange, sonst liest
     sich die Bewertung als Markenelement statt als Urteil. */
  .voices { padding:calc(74px * var(--sy)) 0; background:var(--bg-alt); }
  .voices-head { text-align:center; margin-bottom:30px; }
  .voices-head h2 { font-size:clamp(30px,4.6vw,44px); margin-bottom:10px; }
  .voices-head .sub { color:var(--ink2); font-size:15.5px; }
  /* ---- Wisch-Leiste statt Raster (Rosty 01.09.: "nicht aufeinander gestapelt,
     sondern zum Wischen, so nebeneinander") ----
     Vorher ein 2-spaltiges Grid, auf dem Handy untereinander. Jetzt eine
     horizontale Leiste mit Scroll-Snap. Kein Karussell-JS und keine Library:
     scroll-snap-type macht das Rasten, die Pfeile scrollen nur um eine
     Kartenbreite weiter (app.js). Faellt JS aus, bleibt die Leiste wischbar.
     Feste Kartenbreite statt 1fr ist Absicht — bei 1fr wuerden vier Karten
     brav in die Zeile passen und es gaebe nichts zu wischen. */
  .vgrid {
    display:flex; gap:14px; align-items:stretch;
    overflow-x:auto; overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;
    scrollbar-width:none; -ms-overflow-style:none;
    padding-block:2px;   /* sonst kappt der Scroller den Kartenrand */
  }
  .vgrid::-webkit-scrollbar { display:none; }
  .vcard { flex:0 0 340px; scroll-snap-align:start; }
  /* Auf dem Handy laeuft die Leiste bis an den Bildschirmrand und die naechste
     Karte steht angeschnitten da — das ist der einzige zuverlaessige Hinweis,
     dass es ueberhaupt weitergeht. .wrap hat 20px Innenabstand, die holt sich
     die Leiste per negativem Rand zurueck und gibt sie als Scroll-Polster aus. */
  @media(max-width:759px){
    .vgrid { margin-inline:-20px; padding-inline:20px; scroll-padding-inline:20px; }
    .vcard { flex-basis:min(78vw, 320px); }
  }
  .vnav { display:flex; justify-content:center; gap:10px; margin-top:18px; }
  .varrow {
    width:40px; height:40px; border-radius:50%; cursor:pointer; flex-shrink:0;
    background:#fff; border:1px solid var(--line); color:var(--ink);
    display:flex; align-items:center; justify-content:center;
    transition:transform .15s ease, opacity .15s ease;
  }
  .varrow svg { width:17px; height:17px; }
  .varrow:hover:not([disabled]) { transform:scale(1.07); }
  .varrow[disabled] { opacity:0.32; cursor:default; transform:none; }
  .vcard {
    background:#fff; border:1px solid var(--line); border-radius:14px;
    padding:22px 22px 20px; display:flex; flex-direction:column; gap:12px;
  }
  .vstars { display:flex; gap:3px; }
  .vstars svg { width:17px; height:17px; fill:#f2b01e; stroke:#b8860b; stroke-width:1.1; }
  .vcard blockquote { margin:0; font-size:16px; line-height:1.55; color:var(--ink); }
  .vmeta { margin-top:auto; font-size:13.5px; color:var(--muted); }
  /* Karten ohne Foto stehen in derselben Reihe wie die mit Foto und werden auf
     deren Hoehe gestreckt — ein kurzes Zitat hinterliess dadurch ein Loch.
     Statt die Reihe ragged zu machen (unruhig) wird der Platz zur Absicht:
     groesserer Schriftgrad wie bei einem Pull-Quote, und das Zitat zentriert
     sich zwischen Sternen und Quellenzeile. Nur fuer Karten OHNE .has-photo —
     bei den Fotokarten fuellt das Bild die Hoehe ohnehin. */
  .vcard:not(.has-photo) blockquote { font-size:18.5px; line-height:1.5; margin-block:auto; }
  .vmeta strong { color:var(--ink2); font-weight:600; }
  /* ---- Stimmen mit Gesicht ----
     Das Zitat allein ist Text; erst das Foto macht daraus jemanden, der da war.
     Optional: Karten ohne .vphoto bleiben unveraendert, sonst braeuchte jede
     Seite auf einen Schlag Bildmaterial fuer alle vier Zitate. Auf der
     Allgemein-Seite traegt jedes Foto zusaetzlich sein Aktivitaets-Etikett,
     weil dort Quad, Paintball und Kids nebeneinanderstehen. */
  .vcard.has-photo { padding:0; overflow:hidden; gap:0; }
  .vphoto { position:relative; aspect-ratio:4/3; overflow:hidden; background:var(--bg-alt); }
  .vphoto img { width:100%; height:100%; object-fit:cover; }
  /* Verlauf nach unten, damit das Etikett auf jedem Motiv lesbar bleibt —
     ohne ihn verschwindet weisse Schrift im hellen Himmel dieser Fotos. */
  .vphoto::after {
    content:''; position:absolute; inset:auto 0 0 0; height:42%; pointer-events:none;
    background:linear-gradient(to top, rgba(18,16,14,0.62), rgba(18,16,14,0));
  }
  .vtag {
    position:absolute; left:13px; bottom:12px; z-index:2;
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-weight:700; font-size:15px;
    text-transform:uppercase; letter-spacing:0.04em; color:#fff;
    background:var(--orange); padding:3px 11px 4px; border-radius:5px;
    transform:skewX(-6deg);
  }
  .vtag > span { display:inline-block; transform:skewX(6deg); }
  /* ---- KI-Kennzeichnung am Bild (Rosty 01.09.: "die KI-Disclaimer sehe ich
     nicht auf allen Seiten") ----
     Es gab bis heute KEINEN einzigen KI-Hinweis auf den drei Seiten — die
     .vsource-Zeile behandelt ein anderes Thema (Person != Zitatgeber).
     Eine Fussnote allein reicht hier auch nicht: das Bild zeigt Menschen, die
     es nicht gibt, und wer scrollt liest keine Quellenzeile. Deshalb Etikett
     AM Bild plus Satz in .vsource.
     Bewusst neutral-dunkel statt orange: .vtag ist ein Marken-Etikett, das hier
     ist eine Kennzeichnung — die beiden duerfen nicht gleich aussehen.
     Kein backdrop-filter: blur kostet im IG-WebView Frames (siehe Constraints). */
  .aitag {
    position:absolute; right:10px; top:8px; z-index:2;
    font-family:'Barlow','Barlow Fallback',sans-serif; font-weight:600; font-size:10.5px;
    letter-spacing:0.05em; color:rgba(255,255,255,0.7);
    /* Rosty 01.09.: soll da sein, aber kaum auffallen — nur "KI", weisser Text,
       keine Platte, kein Schatten, keine Kontur. Der Hinweis in .vsource traegt
       die eigentliche Erklaerung. */
  }
  .vcard.has-photo .vbody { padding:20px 22px 22px; display:flex; flex-direction:column; gap:11px; flex:1; }

  .vsource { margin-top:22px; text-align:center; font-size:12.5px; color:var(--muted); }
  .vsource a { color:var(--muted); }


/* ---------- Aktivitaets-Sections ---------- */
  .act { padding:calc(78px * var(--sy)) 0; }
  .act.alt { background:var(--bg-alt); }
  .act-head { max-width:760px; margin-bottom:38px; }
  .act-head h2 { font-size:clamp(44px,6.4vw,68px); margin-bottom:12px; }
  .act-head p { color:var(--ink2); font-size:17px; }
  .act-grid { display:grid; gap:28px; align-items:stretch; }
  @media(min-width:920px){
    .act-grid { grid-template-columns:1fr 1fr; gap:44px; }
    .act-grid.flip .act-photo { order:2; }
  }
  .act-photo { position:relative; border-radius:var(--r); overflow:hidden; min-height:300px; }
  .act-photo img { width:100%; height:100%; object-fit:cover; position:absolute; inset:0; }
  .act-photo img.pos-top { object-position:center 22%; }
  .age {
    position:absolute; top:14px; left:14px; z-index:2;
    background:#161513; color:#fff; font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif;
    font-size:15px; font-weight:700; text-transform:uppercase; letter-spacing:0.03em;
    padding:6px 13px; border-radius:999px;
  }
  @media(max-width:919px){ .act-photo { min-height:260px; } }

  /* ---------- Paket-Karten (Rosty 01.09., Vorbild mastersofdirt.world) ----------
     Bild, Beschreibung und Button in EINEM Block statt zwei ganzer Sections.
     Bei MoD misst das Kartenbild 432x330 = 1,31, praktisch 4:3 — dasselbe Format,
     in dem die Platten generiert werden. Das ist kein Zufall, es ist der Grund,
     warum hier nichts mehr beschnitten wird. */
  .pcards { display:grid; gap:22px; }
  .pcard {
    background:#fff; border:1px solid var(--line); border-radius:var(--r);
    display:grid;
    /* KEIN overflow:hidden — der freigestellte Spieler ragt oben aus der Karte. */
  }
  /* Ein Paket pro Section (Rosty 01.09.: Paintball und Kids bleiben getrennt).
     Damit die einzelne Karte die Breite traegt, liegen Bild und Text nebeneinander
     — dieselbe Anordnung wie im "Geburtstage & Events"-Block bei mastersofdirt. */
  @media(min-width:900px){
    .pcard { grid-template-columns:minmax(0,46%) 1fr; align-items:center; }
    /* Wechselseitig, damit zwei Paketkarten untereinander nicht gleich stehen —
       dieselbe Rhythmik, die .act-grid.flip vorher hatte. */
    .pcard.flip { grid-template-columns:1fr minmax(0,46%); }
    .pcard.flip .pmedia { order:2; }
  }
  /* Der Ueberstand braucht Platz, sonst waechst die Figur in die Section darueber.
     Vorbild ist die Creator-Club-Section auf auramedia.at: dort liegt das
     freigestellte PNG schlicht ueber seiner Flaeche, und kein Vorfahre clippt. */
  /* --pad ist der Ueberstand nach oben. Die kleineren Karten (.kcard, .cat-card)
     fahren denselben Bildplatz mit weniger Vorlauf — deshalb eine Variable und
     keine feste Zahl. --ph ist die Hoehe des Freistellers in Prozent des
     Bildplatzes: schmale Figuren tragen 100 % und ragen heraus, breite Fahrzeuge
     brauchen weniger, sonst fuellen sie die Platte von Kante zu Kante. */
  .pmedia { --pad:56px; --padx:14px; --ph:100%; --pz:1.2; --po:50% 62%;
            position:relative; padding:var(--pad) var(--padx) 0;
            /* Seitlich klemmen, oben und unten offen lassen: der Freisteller SOLL
               ueber die Platte hinausragen, aber nicht aus der Karte heraus in
               den Nachbarn laufen. overflow:hidden kann das nicht — es wuerde
               beide Achsen kappen, clip-path mit negativen Werten schon. */
            clip-path:inset(-18% 0 -14% 0);
            /* clip-path versteckt den seitlichen Ueberstand nur optisch — er
               zaehlt weiter in document.scrollWidth, die Seite war wischbar
               (Falle 18, /quad bei 834 px um 66 px). overflow:clip nimmt ihn
               aus der Rechnung, ohne einen Scroll-Container zu bauen; die
               y-Achse bleibt offen, damit die Figur weiter herausragen darf. */
            overflow-x:clip; overflow-y:visible; }
  .pplate {
    position:relative; border-radius:14px; overflow:hidden;
    aspect-ratio:4/3; background:var(--tint);
  }
  .pplate img { width:100%; height:100%; object-fit:cover; display:block; }
  /* bottom:0 sitzt auf der Unterkante der Platte (das Padding liegt oben),
     height:100% ist Platte + Ueberstand — die Figur endet also exakt am
     Plattenboden und ragt oben genau um das Padding hinaus. */
  /* Nicht mittig: genau dort steht der Torbogen am Ende der Gasse, und der soll
     sichtbar bleiben (Rosty 01.09.). Aus der Mitte nach links versetzt. */
  /* Der Freisteller ist KEIN eigenes Motiv, sondern dasselbe Foto mit
     freigestelltem Hauptobjekt — deckungsgleich ueber die Platte gelegt und um
     --pz vergroessert. Weil Vorder- und Hintergrund aus einer Datei stammen,
     stimmen Licht, Farbe und Perspektive zwangslaeufig, und eine unsaubere
     Maskenkante faellt nicht auf: darunter liegt exakt dasselbe Bild.
     --po ist der Schwerpunkt der Maske. Skaliert wird um ihn, damit die
     groessere Kopie die kleinere im Hintergrund vollstaendig verdeckt.
     Der Ueberstand entsteht von selbst: was ueber die Platte hinauswaechst,
     ragt heraus, weil kein Vorfahre clippt. */
  /* ⚠ inset allein streckt ein <img> NICHT — bei width/height:auto gewinnt die
     Intrinsic-Groesse und right/bottom werden verworfen. Deshalb die Masse
     ausrechnen. Prozente beziehen sich auf die PADDING-Box von .pmedia, die
     Platte ist also 100% minus Innenabstand. */
  .phero {
    position:absolute; top:var(--pad); left:var(--padx);
    width:calc(100% - var(--padx) * 2); height:calc(100% - var(--pad));
    max-width:none; object-fit:contain; display:block; pointer-events:none;
    transform:scale(var(--pz)); transform-origin:var(--po);
  }
  /* Zwei-Dateien-Variante: Freisteller aus einem ANDEREN Foto als die Platte —
     auf /paintball steht der Spieler aus dem Shipment-Bild vor der Gasse auf
     Fallujah. Der wird nicht ueberlagert, sondern gestellt, also eigene
     Positionierung: unten buendig, --px als Standort, --ph als Hoehe. */
  .pmedia.solo .phero {
    top:auto; bottom:0; left:var(--px,40%);
    width:auto; height:var(--ph); max-width:112%;
    transform:translateX(-50%); transform-origin:50% 100%;
  }
  .pmedia .age { position:absolute; left:26px; top:calc(var(--pad) + 12px); z-index:2; }
  /* ---- Karte mit Video statt Foto + Freisteller (Rosty 30.09.: „im Verteiler machen wir doch Videos") ----
     Kein Ueberstand, also kein Vorlauf und kein clip-path: die Platte ist ein ruhiger Rahmen mit
     gleichem Rand ringsum. Grundformat 4:5; die Videos sind 720x1080 (2:3) mit dem Motiv oben. Genutzt vom Verteiler auf / (dort als .welt mit Text darauf). Poster als <img> darunter, das Video
     liegt unsichtbar darueber, bis es wirklich spielt (.has-frame) — iOS zeigt sonst Schwarz
     zwischen Quelle-setzen und erstem Bild (Falle 39). Steuerung: .activity-video in app.js. */
  .pmedia.pvideo { --pad:14px; clip-path:none; overflow:visible; padding-bottom:0; }
  .pvideo .pplate { aspect-ratio:4/5; background:#161513; }
  .pv-lage { position:absolute; inset:0; }
  .pv-lage img, .pv-lage video { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
  .pv-lage video { opacity:0; transition:opacity .25s ease; }
  .pv-lage video.has-frame { opacity:1; }
  .pvideo .activity-play {
    position:absolute; right:12px; bottom:12px; z-index:2; width:40px; height:40px; border-radius:50%;
    border:1px solid #ffffff66; color:#fff; background:#161513b8; display:grid; place-items:center; cursor:pointer;
  }
  .pvideo .activity-play[hidden] { display:none; }
  .pvideo .activity-play svg { width:18px; height:18px; grid-area:1/1; }
  .pvideo .activity-pause-icon, .pvideo .activity-play.is-playing .activity-play-icon { display:none; }
  .pvideo .activity-play.is-playing .activity-pause-icon { display:block; }
  @media(max-width:899px){ .pmedia.pvideo { --pad:12px; } }
  .pbody { padding:20px 22px 24px; display:flex; flex-direction:column; gap:10px; }
  @media(min-width:900px){
    .pbody { padding:26px 30px 28px 10px; }
    .pcard.flip .pbody { padding:26px 10px 28px 30px; }
  }
  .pbody h3 {
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif;
    font-style:italic; font-weight:700; font-size:clamp(28px,3.4vw,38px);
    line-height:1.02; color:var(--ink); margin:0;
  }
  .pkick {
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-weight:700;
    text-transform:uppercase; letter-spacing:0.04em; font-size:15px;
    color:var(--orange-deep); margin-top:-4px;
  }
  .pbody > p { color:var(--ink2); font-size:15.5px; line-height:1.55; }
  /* Preis und Button sitzen unten buendig, auch wenn die Texte verschieden lang
     sind — sonst tanzen die beiden Karten nebeneinander. */
  .pbody .stack { margin:2px 0 4px; }
  .pbody .price-row { margin-top:auto; padding-top:14px; border-top:1px solid var(--line); }
  .pbody .book-btn { width:100%; justify-content:center; }
  @media(min-width:900px){ .pbody .book-btn { width:auto; align-self:start; } }
  @media(max-width:899px){
    .pmedia { --pad:44px; padding:var(--pad) 12px 0; }
    .pmedia .age { left:22px; }
  }

  /* Package card */
  .pack {
    background:#fff; border:1px solid var(--line); border-radius:var(--r);
    padding:28px 26px; display:flex; flex-direction:column;
    box-shadow:0 10px 34px rgba(35,25,10,0.06);
  }
  .act.alt .pack { border-color:#e2ddd3; }
  .pack h3 { font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-style:italic; font-weight:700; font-size:32px; margin-bottom:6px; }
  .pack .dream { color:var(--ink2); font-size:15.5px; margin-bottom:18px; }
  .stack { list-style:none; display:flex; flex-direction:column; gap:10px; margin-bottom:18px; }
  .stack li { display:flex; gap:10px; font-size:15px; color:var(--ink2); }
  .stack li strong { color:var(--ink); font-weight:600; }
  .stack .ck { width:19px; height:19px; border-radius:50%; background:var(--tint); flex-shrink:0; display:flex; align-items:center; justify-content:center; margin-top:2px; }
  .stack .ck svg { width:11px; height:11px; color:var(--orange-deep); }
  .bonus {
    display:flex; gap:10px; align-items:flex-start; background:var(--tint); border:1px dashed var(--orange);
    border-radius:12px; padding:12px 14px; font-size:14px; color:var(--ink2); margin-bottom:20px;
  }
  .bonus svg { width:17px; height:17px; color:var(--orange-deep); flex-shrink:0; margin-top:1px; }
  .bonus strong { color:var(--ink); }
  .price-row { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-bottom:6px; }
  .price-old { font-size:15.5px; color:var(--muted); text-decoration:line-through; }
  .price {
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-style:italic; font-weight:700;
    font-size:44px; color:var(--orange); line-height:1;
  }
  .price small { font-size:16px; font-weight:600; color:var(--ink2); font-style:normal; font-family:'Barlow','Barlow Fallback',sans-serif; }
  .price-note { font-size:13px; color:var(--muted); margin-bottom:20px; }
  .pack .btn { align-self:flex-start; margin-top:auto; }


/* ---------- Kids cards ---------- */
  .kcards { display:grid; gap:26px; }
  @media(min-width:820px){ .kcards { grid-template-columns:1fr 1fr; gap:34px; } }
  /* Seit 01.09. tragen auch die Kids-Karten den Bildplatz aus den Paketkarten:
     echtes Feldfoto als Platte, Freisteller darueber. KEIN overflow:hidden mehr
     — der Freisteller ragt oben aus der Karte, und ein clippender Vorfahre
     schneidet ihn wortlos ab. Die Rundung sitzt jetzt an .pplate. */
  .kcard {
    background:#fff; border:1px solid var(--line); border-radius:var(--r);
    display:flex; flex-direction:column; box-shadow:0 10px 34px rgba(35,25,10,0.06);
  }
  .kcard .pmedia { --pad:40px; }
  @media(max-width:819px){ .kcard .pmedia { --pad:34px; } }
  /* Karte mit einem fertigen Foto statt Platte + Freisteller (Kids auf /quad seit 30.09.): nichts ragt
     heraus, also kein Vorlauf oben — gleicher Rand ringsum wie bei den Video-Kacheln (.pvideo). */
  .kcard .pmedia.pfoto { --pad:14px; clip-path:none; overflow:visible; }
  .kcard .kbody { padding:24px 24px 26px; display:flex; flex-direction:column; flex:1; }
  .kcard h3 { font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-style:italic; font-weight:700; font-size:30px; margin-bottom:8px; }
  .kcard p { color:var(--ink2); font-size:15px; margin-bottom:16px; }
  .kcard .price-row { margin-top:auto; }
  .kcard .btn { align-self:flex-start; margin-top:14px; }


/* ---------- Paketflaeche mit Video: Paketinhalt liegt auf dem Medium ----------
   Seit 09.09. auf /quad (Arena, Waldtour), seit 30.09. auch das Paintball-Paket auf /paintball
   (Rosty: „Text aufs Video drauf"). Bis dahin stand der Block im <style> von quad.html.
   Poster als <picture> darunter, Video unsichtbar bis es spielt (.has-frame), Verlauf, darauf
   Ueberschrift und Stichpunkte; Preis und Knopf stehen darunter (.activity-booking). */
  .activity-card { display:block; overflow:hidden; }
  .activity-media { position:relative; isolation:isolate; width:100%; min-width:0; aspect-ratio:9/10; background:#161513; color:#fff; display:flex; align-items:flex-end; }
  .activity-media picture, .activity-media picture img, .activity-media .activity-video { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
  .activity-media picture { z-index:-3; }
  /* Auf .activity-media begrenzt: die Video-Kacheln im Verteiler (.pv-lage) tragen dieselbe Klasse,
     dort liegt das Poster als <img> ohne z-index — mit -2 spielte das Video unsichtbar dahinter (30.09.). */
  .activity-media .activity-video { z-index:-2; opacity:0; }
  .activity-media .activity-video.has-frame { opacity:1; }
  .activity-media::after { content:''; position:absolute; inset:0; z-index:-1; background:linear-gradient(to bottom,rgba(22,21,19,.1) 20%,rgba(22,21,19,.24) 38%,rgba(22,21,19,.90) 63%,#161513 100%); pointer-events:none; }
  .activity-media .age { position:absolute; top:18px; left:18px; z-index:1; }
  .activity-play { position:absolute; right:16px; top:16px; width:44px; height:44px; border:1px solid #ffffff80; border-radius:50%; color:#fff; background:#161513dc; display:grid; place-items:center; cursor:pointer; }
  .activity-play[hidden] { display:none; }
  .activity-play svg { width:20px; height:20px; grid-area:1/1; }
  .activity-pause-icon, .activity-play.is-playing .activity-play-icon { display:none; }
  .activity-play.is-playing .activity-pause-icon { display:block; }
  .activity-package { width:100%; padding:26px 24px; }
  .activity-package h3 { font:italic 700 36px/1.02 'Barlow Condensed',sans-serif; margin-bottom:16px; }
  .activity-package .stack { margin:0; gap:12px; }
  .activity-package .stack li { color:#fff; font-size:16px; line-height:1.35; }
  .activity-package .stack li strong { color:#fff; }
  .activity-package .ck { background:#ff8a2b; color:#161513; flex-shrink:0; }
  .activity-package .ck svg { color:#161513; }
  .activity-booking.pbody { padding:24px; gap:12px; }
  .activity-booking.pbody .price-row { padding:0; border:0; margin:0; }
  /* Hochkant-Quelle 2:3 (Paintball-Paket): am Handy im eigenen Format — die Stichpunkte belegen die
     untere Haelfte, das Motiv braucht die obere. */
  @media(max-width:699px){
    .activity-media.hoch { aspect-ratio:2/3; }
    /* Der Textblock bringt seinen eigenen Grund mit: je schmaler das Handy, desto hoeher laeuft die Liste
       und desto weiter oben steht die Ueberschrift — dort ist der Flaechen-Verlauf noch hell
       (gemessen bei 360 px: 2,1:1 auf dem hellsten Frame). So haengt der Kontrast nicht an der Textlaenge. */
    .activity-media.hoch .activity-package {
      padding-top:60px;
      background:linear-gradient(to bottom, rgba(22,21,19,0) 0, rgba(22,21,19,0.74) 60px, rgba(22,21,19,0.74) 100%);
    }
  }
  @media(min-width:700px){
    .activity-media { aspect-ratio:16/9; min-height:480px; }
    .activity-package { padding:32px; }
    .activity-package .stack { display:grid; grid-template-columns:1fr 1fr; gap:14px 32px; }
    .activity-package .stack li { font-size:18px; }
    .activity-booking.pbody { display:grid; grid-template-columns:1fr auto; align-items:center; padding:26px 32px; }
    .activity-booking .price-note { grid-column:1; grid-row:2; }
    .activity-booking.pbody .book-btn { grid-column:2; grid-row:1/3; width:auto; }
  }
  @media(max-width:359px){
    .activity-package { padding:24px 18px; }
    .activity-package .stack li { font-size:15px; }
    .activity-booking.pbody { padding:20px 18px; }
  }


/* ---------- Dunkle Kids-Section (/quad seit 09.09., /paintball seit 30.09.) ---------- */
  .kids-area { --ink:#fff; --ink2:#e0d9d0; --muted:#c2b9ad; --line:#504b43; --orange-deep:#ff8a2b; background:#161513; color:#fff; }
  .kids-area .kcard, .kids-area .pcard { background:#24221e; border-color:#504b43; }
  .kids-area .price { color:#ff8a2b; }
  .kids-area .book-btn { background:#fff; color:#161513; }
  .kids-area .pcard .stack .ck { background:#ff8a2b; }
  .kids-area .pcard .stack .ck svg { color:#161513; }
  .kids-area.act.alt { background:#161513; }

/* ---------- Buchung ---------- */
  .booking { padding:calc(74px * var(--sy)) 0; background:var(--bg-alt); }
  .book-card {
    position:relative; max-width:660px; margin:0 auto; background:#fff; border:1px solid var(--line);
    border-radius:22px; padding:30px 26px; box-shadow:0 18px 50px rgba(35,25,10,0.08);
  }
  /* Ab 1100 px Fensterbreite schaltet SYN von Monatskalender auf Wochenansicht (Bundle: md=1100,
     isDesktop = Breite >= md). Die Woche ist 7 × 146 = 1022 px breit und scrollt nicht seitlich —
     in 660 px fielen Sa/So einfach weg (Rosty 17.10.2026). Die Karte behält ihren Rand für
     Schritte und Chips, nur der Kalender greift 18 px in den Rand: bei 1100 px (mit Scrollbalken
     ~1045 px im .wrap) bleiben so 1027 px für die Woche. */
  @media (min-width:1100px) {
    .book-card { max-width:1100px; }
    .book-card .rb-wrap { margin-left:-18px; margin-right:-18px; }
  }
  .bk-step { font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-size:19px; font-weight:700; color:var(--ink); margin:24px 0 10px; }
  .bk-step:first-of-type { margin-top:0; }
  .bk-step span { color:var(--orange); }
  .bk-group { font-size:12.5px; font-weight:700; letter-spacing:0.06em; text-transform:uppercase; color:var(--muted); margin:14px 0 8px; }
  .bk-group:first-of-type { margin-top:0; }
  .bk-chips { display:flex; flex-wrap:wrap; gap:8px; }
  .bk-chip {
    border:1.5px solid var(--line); background:#fff; border-radius:999px; padding:10px 18px;
    display:inline-flex; align-items:center; min-height:44px;
    font-size:14.5px; font-weight:600; color:var(--ink2); cursor:pointer; transition:border-color .15s, background .15s, color .15s;
    font-family:'Barlow','Barlow Fallback',sans-serif;
  }
  .bk-chip.sel { background:var(--ink); border-color:var(--ink); color:#fff; }
  .rb-wrap { min-height:560px; position:relative; }
  #rb-skeleton { padding:32px 16px; text-align:center; color:var(--muted); background:var(--bg-alt); border-radius:var(--r); }
  #rb-fallback { padding:32px 16px; text-align:center; background:var(--tint); border:1px solid var(--tint-line); border-radius:var(--r); }
  #rb-fallback p { margin:0 0 16px; }


/* ---------- Felder — eine Kachel je Feld, seitlich wischen (Luc 07.09.) ----------
   Ersetzt den Reiter-Schaukasten darunter (bleibt vorerst als Code stehen, bis
   die Richtung bestaetigt ist). Grundsatz: das Bild muss erkennbar bleiben —
   der Verlauf deckt nur das untere Drittel, wo Name und Satz stehen, und
   ausser diesen beiden Zeilen liegt nichts auf dem Bild. */
  .felder { background:#161513; color:#fff; padding:calc(64px * var(--sy)) 0 calc(56px * var(--sy)); }
  .felder-kopf { margin-bottom:26px; }
  .felder-kopf h2 { font-size:clamp(34px,5.4vw,52px); margin-bottom:12px; }
  .felder-kopf p { font-size:17px; color:rgba(255,255,255,0.62); max-width:46ch; }

  /* Der Strom: volle Breite, Kacheln rasten ein. Auf dem Handy ist eine Kachel
     etwas schmaler als der Schirm, damit die naechste am Rand sichtbar ist —
     das ist der Hinweis zum Wischen, ohne ein Wort dafuer zu brauchen. */
  .felder-strom {
    display:flex; gap:12px; overflow-x:auto; padding:0 20px;
    scroll-snap-type:x mandatory; scroll-padding:0 20px;
    scrollbar-width:none; -webkit-overflow-scrolling:touch;
  }
  .felder-strom::-webkit-scrollbar { display:none; }
  .feld {
    position:relative; flex:0 0 min(84vw, 460px); aspect-ratio:4/5;
    border-radius:18px; overflow:hidden; background:#0d0c0b;
    scroll-snap-align:start; isolation:isolate;
    /* Safari: eigene Ebene fuer das Abrunden, sonst zeichnet es an der
       Unterkante eine Haarlinie zwischen Video-Ebene und Rundung. */
    transform:translateZ(0); -webkit-mask-image:-webkit-radial-gradient(#fff, #000);
  }
  /* Das Video laeuft einen Pixel ueber die Kachel hinaus. Die Kachel hat durch
     aspect-ratio eine Subpixel-Hoehe (409,48 px auf dem iPhone); sonst bleibt
     am Rand eine halbe Zeile Hintergrund sichtbar (Luc 07.09.). Dasselbe gilt
     fuer den Verlauf: endet er genau bei bottom:0, bleibt unter ihm eine halbe
     Zeile Video ungedeckt — bei hellen Clips als heller Strich sichtbar. */
  .feld video, .feld .feld-bild { position:absolute; inset:-1px; width:calc(100% + 2px); height:calc(100% + 2px); object-fit:cover; display:block; }
  /* Poster als eigenes <img> UNTER dem Video (Rosty 29.09.: schwarzer Kasten beim Scrollen am
     Handy). iOS verwirft das poster-Attribut, sobald das Video eine Quelle bekommt, und zeigt
     Schwarz, bis das erste Bild geladen ist. Das Bild bleibt liegen, das Video ist unsichtbar,
     bis es wirklich spielt (.spielt aus app.js), und blendet dann ein — dasselbe Muster wie
     .activity-video auf /quad. */
  .feld video { opacity:0; transition:opacity .3s ease; }
  .feld video.spielt { opacity:1; }
  /* Nur noch der Satz — der Feldname steht seit 18.09. allein in der Leiste
     darunter (Rosty). Verlauf deshalb flacher als mit Ueberschrift. */
  .feld-text {
    position:absolute; left:0; right:0; bottom:-1px; z-index:1;
    padding:72px 20px 20px;
    /* Gemessen gegen das hellste Bild des Clips: der Satz lag bei 4,10:1,
       Ziel 4,5. Nur die unterste Stufe zieht an — oben bleibt der Verlauf
       offen, das Bild soll erkennbar bleiben. */
    background:linear-gradient(to top, rgba(6,5,4,0.88) 0%, rgba(6,5,4,0.60) 40%, rgba(6,5,4,0) 100%);
  }
  /* Reines Weiss statt 88 %: hebt den Satz von 4,16 auf ueber 5:1, ohne den
     Verlauf weiter zuzuziehen — das Bild bleibt, wie es ist. */
  .feld-text p { font-size:15px; line-height:1.4; color:#fff; margin:0; max-width:34ch; }

  /* Namensleiste (Rosty 18.09., ersetzt die Marken): die Feldnamen als zweiter
     Streifen unter den Kacheln, der beim Wischen stufenlos mitlaeuft — der
     aktive Name steht links buendig mit der Kachel, die anderen blenden nach
     Abstand ab. Verschiebung und Deckkraft setzt app.js aus der Scrollposition;
     ohne JS stehen die Namen still und der erste ist hell. Antippen springt. */
  .felder-namen { display:flex; align-items:center; gap:16px; margin-top:20px; padding:0 20px; }
  /* Das Fenster greift 20 px in den Rand davor: dort liegt der Ausblendverlauf,
     sonst verschluckt er die Nummer des aktiven Namens. */
  .fn-fenster {
    flex:1; min-width:0; overflow:hidden; margin-left:-20px; padding-left:20px;
    -webkit-mask-image:linear-gradient(to right, transparent 0, #000 14px, #000 78%, transparent 100%);
            mask-image:linear-gradient(to right, transparent 0, #000 14px, #000 78%, transparent 100%);
  }
  .fn-spur { display:flex; gap:28px; width:max-content; will-change:transform; }
  .fn {
    display:inline-flex; align-items:baseline; gap:8px; flex:none;
    background:none; border:none; padding:6px 0; cursor:pointer; white-space:nowrap;
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-style:italic; font-weight:700;
    font-size:clamp(28px,6.6vw,40px); line-height:1; color:#fff; opacity:0.3;
  }
  .fn.sel { opacity:1; }
  .fn .mnum { font-size:0.42em; color:rgba(255,255,255,0.6); }
  .fn.sel .mnum { color:var(--orange); }
  .fn:focus-visible { outline:2px solid var(--orange); outline-offset:4px; border-radius:4px; }

  /* Pfeile nur am Desktop: das Mausrad scrollt nicht seitlich, am Handy wischt man. */
  .fn-pfeile { display:none; gap:10px; flex:none; }
  .fn-pfeil {
    width:46px; height:46px; border-radius:50%; display:grid; place-items:center; cursor:pointer;
    background:none; color:#fff; border:1px solid rgba(255,255,255,0.28);
    transition:background .18s ease, border-color .18s ease, opacity .18s ease;
  }
  .fn-pfeil svg { width:20px; height:20px; }
  .fn-pfeil:hover:not(:disabled) { background:rgba(255,255,255,0.08); border-color:rgba(255,255,255,0.5); }
  .fn-pfeil:disabled { opacity:0.3; cursor:default; }
  .fn-pfeil:focus-visible { outline:2px solid var(--orange); outline-offset:3px; }

  /* Desktop: derselbe Streifen, links buendig mit .wrap, rechts bis an den Rand —
     drei Kacheln ganz, die vierte lugt hervor. Acht Kacheln im Raster waren drei
     Reihen (Rosty: "nimmt zu viel Platz ein"). */
  @media(min-width:920px){
    .felder { --felder-rand:max(20px, calc((100% - 1140px) / 2 + 20px)); }
    .felder-strom { gap:18px; padding:0 20px 0 var(--felder-rand); scroll-padding:0 0 0 var(--felder-rand); }
    .feld { flex:0 0 clamp(300px, 28vw, 360px); }
    .felder-namen { margin-top:26px; padding:0 var(--felder-rand); }
    .fn-pfeile { display:flex; }
  }
  @media (prefers-reduced-motion: reduce) { .fn-pfeil { transition:none; } }

/* ---------- "+12"-Zeile unter den Felder-Kacheln ----------
   Stammt aus dem alten Schaukasten (Reiter/Pfeile, am 07.09. durch .felder
   abgeloest); die Zeile selbst wird weiter benutzt, der Rest ist raus. */
  /* Hinweis auf die Felder, die nicht ausgestellt sind. Sitzt unter dem
     Schaukasten und nimmt die Zahlen-Typo der Tabs auf: Condensed, kursiv, orange.
     --orange auf #14120f kommt auf 4,5:1 — als grosse Ziffer (>=34px) reicht das,
     als Fliesstext waere es zu wenig, deshalb steht der Text in Weiss. */
  .maps-more {
    display:flex; align-items:center; gap:18px;
    margin-top:34px; padding-top:26px;
    border-top:1px solid rgba(255,255,255,0.14);
  }
  .maps-more .mm-num {
    flex:0 0 auto;
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif;
    font-style:italic; font-weight:700; font-size:clamp(34px,4.4vw,48px);
    line-height:1; color:var(--orange);
  }
  .maps-more b { display:block; color:#fff; font-size:17px; margin-bottom:4px; }
  .maps-more p { color:rgba(255,255,255,0.62); font-size:15.5px; max-width:44ch; }

/* ---------- Anfahrt-Zeilen in FAQ-Antworten ----------
   Standen bis 27.08. in einer eigenen Was/Wann/Wo-Section. Die ist aufgeloest,
   der Inhalt liegt jetzt als Fragen in der FAQ — die Bausteine (Icon-Zeile,
   Pfeil-Link) bleiben, nur nicht mehr unter .www. */
  .fq-a .link { color:var(--orange-deep); font-weight:600; font-size:15px; display:inline-flex; align-items:center; gap:6px; min-height:44px; }
  .fq-a .link svg { width:14px; height:14px; }
  .icon-row { display:flex; align-items:center; gap:9px; font-size:15px; color:var(--ink2); margin-bottom:9px; }
  .icon-row svg { width:16px; height:16px; color:var(--orange); flex-shrink:0; }

  
/* ---------- FAQ ----------
   Klassischer Klappmechanismus auf <details>: die Semantik traegt der Browser,
   ohne JS steht der Text trotzdem da. Die Hoehe wird in app.js von Hand
   animiert — auf display gibt es keinen Uebergang. */
  .faq { padding:calc(76px * var(--sy)) 0 calc(70px * var(--sy)); background:var(--bg-alt); }
  .faq-head { max-width:760px; margin-bottom:24px; }
  .faq-head h2 { font-size:clamp(38px,5.4vw,58px); margin-bottom:10px; }
  .faq-head p { color:var(--ink2); font-size:16.5px; max-width:50ch; }
  .faq-list { max-width:840px; border-top:1px solid var(--line); }
  .fq { border-bottom:1px solid var(--line); }
  .fq > summary {
    list-style:none; cursor:pointer; display:flex; align-items:flex-start; gap:18px;
    padding:19px 2px; min-height:44px;
    font-size:17.5px; font-weight:600; line-height:1.4; color:var(--ink);
    transition:color .15s ease;
  }
  .fq > summary::-webkit-details-marker { display:none; }
  .fq > summary:hover { color:var(--orange-deep); }
  .fq-q { flex:1; }
  /* Plus, das beim Aufklappen zum Minus wird — der Balken dreht weg, statt zu
     verschwinden. Kein SVG noetig, dreht sauber ohne Kantenflimmern. */
  .fq-ic {
    position:relative; flex-shrink:0; width:28px; height:28px; margin-top:1px;
    border-radius:50%; background:var(--tint); border:1px solid var(--tint-line);
  }
  .fq-ic::before, .fq-ic::after {
    content:''; position:absolute; left:50%; top:50%; width:11px; height:2px;
    border-radius:2px; background:var(--orange-deep);
    transform:translate(-50%,-50%);
  }
  .fq-ic::after { transform:translate(-50%,-50%) rotate(90deg); transition:transform .3s ease; }
  .fq[open] .fq-ic::after { transform:translate(-50%,-50%) rotate(0deg); }
  /* Zugeklappt wird HIER entschieden, nicht vom Browser. Chrome versteckt den
     Inhalt eines geschlossenen <details> je nach Version ueber display:none ODER
     ueber ::details-content — im zweiten Fall stand die komplette Antwort offen
     da (gemessen 27.08., alle sieben Zeilen ausgeklappt). Eigene Hoehe 0 gilt in
     beiden Modellen, und ohne JS klappt [open] auf height:auto ganz normal auf. */
  .fq-a { height:0; overflow:hidden; transition:height .32s cubic-bezier(.4,0,.2,1); }
  .fq[open] .fq-a { height:auto; }
  .fq::details-content { content-visibility:visible; block-size:auto; }
  .fq-a > div { padding:0 46px 22px 0; color:var(--ink2); font-size:16px; }
  .fq-a p + p { margin-top:11px; }
  .fq-a strong { color:var(--ink); font-weight:600; }
  .fq-a .fq-rows { list-style:none; display:grid; gap:7px; margin:12px 0 0; }
  .fq-a .fq-rows li { display:flex; flex-wrap:wrap; gap:4px 10px; font-size:15.5px; }
  .fq-a .fq-rows b { color:var(--ink); font-weight:600; min-width:190px; }
  .fq-a .fq-steps { list-style:none; counter-reset:s; display:grid; gap:8px; margin:12px 0 0; }
  .fq-a .fq-steps li { counter-increment:s; display:flex; gap:11px; font-size:15.5px; }
  .fq-a .fq-steps li::before {
    content:counter(s); flex-shrink:0; width:21px; height:21px; border-radius:50%;
    background:var(--tint); color:var(--orange-deep);
    font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-weight:700; font-size:14px;
    display:flex; align-items:center; justify-content:center; margin-top:1px;
  }
  .faq-more {
    max-width:840px; margin-top:26px; display:flex; flex-wrap:wrap; align-items:center; gap:14px;
    font-size:15.5px; color:var(--ink2);
  }
  @media (prefers-reduced-motion: reduce) { .fq-a { transition:none; } }
  @media(min-width:920px){
    .fq > summary { font-size:19px; padding:22px 2px; }
    .fq-a > div { font-size:16.5px; }
  }

  
/* ---------- Final CTA ---------- */
  .final { background:var(--ink); color:#fff; padding:calc(84px * var(--sy)) 0 calc(110px * var(--sy)); text-align:center; }
  .final h2 { font-size:clamp(44px,7vw,76px); max-width:18ch; margin:0 auto 14px; }
  .final p { color:rgba(255,255,255,0.7); max-width:46ch; margin:0 auto 30px; font-size:17px; }
  .final .btns { display:flex; flex-wrap:wrap; gap:12px; justify-content:center; }

  
/* ---------- Footer ---------- */
  footer { background:#0e0d0c; color:rgba(255,255,255,0.55); padding:calc(38px * var(--sy)) 0 calc(90px * var(--sy)); font-size:14px; }
  .foot { display:flex; flex-wrap:wrap; gap:20px; align-items:center; justify-content:space-between; }
  .foot img { height:52px; }
  .foot-links { display:flex; gap:22px; }
  .foot-links a { display:inline-flex; align-items:center; min-height:44px; }
  .foot-links a:hover { color:#fff; }
  .foot .credit { width:100%; font-size:12px; color:rgba(255,255,255,0.58); }

  
/* ---------- Einwilligungs-Dialog (nur ohne Cookiebot, siehe app.js) ----------
   Seit 14.09. ein blockierender Dialog in der Mitte statt einer Leiste am
   unteren Rand: die Leiste blieb bei 73 % der Besuche unbeantwortet, und
   ohne Antwort sieht Meta keinen einzigen Klick. Scrim ueber allem (z 130,
   ueber dem Rabatt-Popup mit 120), Seite gesperrt (html.consent-offen).
   Die beiden Knoepfe teilen sich EINE Klasse und haben absichtlich keinen
   Modifier: "Akzeptieren" darf optisch nicht bevorzugt werden (VwGH
   Ra 2024/04/0424) — gleiche Farbe, Groesse, Position, gleich viele Klicks.
   Wer hier einen Primaerknopf einbaut, macht die Einwilligung angreifbar.
   Kein X, kein Klick auf den Scrim: "weg damit" ohne Antwort ist genau das
   Ignorieren, das der Dialog beenden soll.
   Seit 15.09. (Rosty): kompakte Karte UNTEN, leichter Scrim ohne Blur —
   Headline und der Grossteil des Hero-Videos bleiben sichtbar, weiter
   geht es trotzdem nur ueber eine Antwort. Knopftexte "Ablehnen" / "Alle
   akzeptieren", weiterhin gleichwertig — "Nur notwendige" (ORF) war kurz
   drin, klingt aber nach der vernuenftigen Wahl und zieht Klicks (Rosty).
   Fokusring neutral statt Orange: Orange auf dem Ablehnen-Knopf las sich
   wie eine Warnung und schob die Leute zum Ablehnen. */
  html.consent-offen, html.consent-offen body { overflow:hidden; }
  #consent {
    position:fixed; inset:0; z-index:130;
    display:flex; align-items:flex-end; justify-content:center;
    padding:16px calc(12px + env(safe-area-inset-right)) calc(12px + env(safe-area-inset-bottom)) calc(12px + env(safe-area-inset-left));
    background:rgba(13,12,11,0.22);
    touch-action:none; overscroll-behavior:contain;
    animation:cs-in .25s ease both;
  }
  @keyframes cs-in { from { opacity:0; } to { opacity:1; } }
  .cs-card {
    display:flex; flex-direction:column; gap:14px;
    width:100%; max-width:460px;
    padding:18px 18px 16px; border-radius:var(--r);
    background:var(--bg); box-shadow:0 18px 50px rgba(0,0,0,0.32);
  }
  .cs-card:focus { outline:none; }
  .cs-txt { display:flex; flex-direction:column; gap:4px; }
  .cs-card .cs-t { font-size:16px; line-height:1.45; font-weight:600; color:var(--ink); }
  .cs-card .cs-k { font-size:13px; line-height:1.45; color:var(--ink2); }
  .cs-card a { color:var(--orange-deep); text-decoration:underline; text-underline-offset:3px; }
  .cs-btns { display:flex; gap:10px; }
  .cs-b {
    flex:1 1 0; min-height:48px;
    font-family:'Barlow','Barlow Fallback',sans-serif; font-size:14px; font-weight:700;
    letter-spacing:0.03em; text-transform:uppercase;
    padding:12px 8px; border-radius:999px; cursor:pointer;
    background:var(--ink); color:#fff; border:none;
  }
  .cs-b:hover { box-shadow:0 8px 22px rgba(0,0,0,0.18); }
  .cs-b:focus-visible { outline:3px solid var(--ink); outline-offset:3px; }
  @media (prefers-reduced-motion: reduce) { #consent { animation:none; } }


/* ---------- Buchungskalender, solange die Einwilligungs-Leiste offen ist ----------
   Der Knopf oeffnet den Kalender (ausdrueckliche Anfrage, wie der Tipp auf eine
   Aktivitaet). Er beantwortet die Leiste NICHT — sonst gaebe es einen zweiten Weg
   zu "Akzeptieren" ohne gleichwertiges "Ablehnen" daneben. */
  .rb-wait { max-width:420px; margin:0 auto; }
  .rb-wait strong {
    display:block; font-family:'Barlow Condensed','Barlow',sans-serif;
    font-size:26px; font-style:italic; font-weight:700; color:var(--ink);
    line-height:1.1; margin-bottom:8px;
  }
  .rb-wait p { font-size:14.5px; line-height:1.55; color:var(--ink2); margin-bottom:16px; }
  .rb-wait p b { color:var(--ink); }
  .rb-wait-b {
    font-family:'Barlow','Barlow Fallback',sans-serif; font-size:14px; font-weight:700;
    letter-spacing:0.04em; text-transform:uppercase;
    padding:12px 26px; border-radius:999px; cursor:pointer;
    background:var(--ink); color:#fff; border:none;
  }
  .rb-wait-b:hover { box-shadow:0 8px 22px rgba(0,0,0,0.18); }
  .rb-wait-alt {
    display:block; margin-top:14px; font-size:13px;
    color:var(--ink2); text-decoration:underline; text-underline-offset:3px;
  }


/* ---------- Freistehender CTA nach jeder Section (Call Luc 17.10.2026) ----------
   Ein Text auf der ganzen Seite, viel Luft oben und unten: "je gequetschter, desto mehr fliegt
   das Auge drueber". Die Section darunter animiert spaeter ein (app.js, at()), damit kurz nur
   der Knopf zu sehen ist. Statt eines Popup-Timers glueht der Knopf beim ersten Sichtbarwerden
   dreimal auf. Kein GSAP-Pre-State: der Knopf ist auch ohne Animation sofort da. */
  .cta-frei { padding:calc(96px * var(--sy)) 0; text-align:center; background:var(--bg); }
  .cta-frei .btn.wa {
    font-size:15.5px; padding:12px 12px 12px 26px; max-width:100%;
    text-align:left; line-height:1.25; box-shadow:0 0 0 0 rgba(23,127,61,0.45);
  }
  .cta-frei .btn .arr { width:40px; height:40px; }
  .cta-frei .btn .arr svg { width:19px; height:19px; }
  .cta-frei .cta-zeile { margin:14px auto 0; max-width:34ch; font-size:15.5px; line-height:1.45; color:var(--ink2); }
  .cta-frei.an .btn.wa { animation:cta-gluehen 2.2s ease-out 0.25s 3; }
  @keyframes cta-gluehen {
    0%   { box-shadow:0 0 0 0 rgba(23,127,61,0.45); }
    70%  { box-shadow:0 0 0 16px rgba(23,127,61,0); }
    100% { box-shadow:0 0 0 0 rgba(23,127,61,0); }
  }
  @media (prefers-reduced-motion: reduce) { .cta-frei.an .btn.wa { animation:none; } }
  /* Kopfzeile: am Handy nur "Rabatt sichern" (der volle Satz passt neben dem Logo nicht). */
  .nav-lang { display:none; }
  @media(min-width:760px){ .nav-lang { display:inline; } }


/* ---------- Hinweis nach dem WhatsApp-Klick (18.10.) ----------
   Ueber der Sticky-Leiste, nicht davor: die Leiste bleibt bedienbar. */
  #wa-hinweis {
    position:fixed; left:12px; right:12px; bottom:calc(84px + env(safe-area-inset-bottom)); z-index:70;
    max-width:440px; margin:0 auto; padding:16px 44px 16px 18px; border-radius:16px;
    background:#fff; color:var(--ink); box-shadow:0 14px 40px rgba(0,0,0,0.22);
    display:flex; flex-direction:column; gap:12px; align-items:flex-start;
    animation:hinweis-rein .3s ease-out;
  }
  #wa-hinweis p { margin:0; font-size:15px; line-height:1.45; color:var(--ink2); }
  #wa-hinweis p b { color:var(--ink); }
  #wa-hinweis .btn { padding:11px 22px; }
  #wa-hinweis .x { position:absolute; top:8px; right:8px; width:32px; height:32px; border:none; background:none; font-size:22px; color:var(--muted); cursor:pointer; }
  @media(min-width:900px){ #wa-hinweis { bottom:calc(90px + env(safe-area-inset-bottom)); right:18px; left:auto; } }
  @keyframes hinweis-rein { from { opacity:0; transform:translateY(12px); } to { opacity:1; transform:none; } }
  @media (prefers-reduced-motion: reduce) { #wa-hinweis { animation:none; } }


/* ---------- Sticky-Bottom-CTA-Bar (Daumenzone, nur Mobile) ---------- */
  #bar {
    /* Bis 14.09. rueckte die Bar um die Hoehe der Einwilligungs-Leiste hoch
       (Falle 19). Der Dialog liegt jetzt als Scrim ueber allem, die Bar
       bleibt am Rand. */
    position:fixed; left:0; right:0; bottom:0; z-index:60;
    display:flex; gap:10px; align-items:center; justify-content:center;
    padding:10px 14px calc(10px + env(safe-area-inset-bottom) + 6px);
    background:rgba(255,255,255,0.96);
    border-top:1px solid var(--line); box-shadow:0 -6px 24px rgba(0,0,0,0.08);
    transform:translateY(110%); transition:transform .3s ease;
  }
  #bar.show { transform:none; }
  #bar .btn { flex:1; max-width:340px; justify-content:center; padding:12px 9px 12px 20px; }
  /* Seit 17.10.2026 nur noch WhatsApp/Rabatt (vorher "Termin wählen" + WhatsApp-Mini-Knopf). */
  #bar .btn .arr svg { width:18px; height:18px; }
  @media(min-width:900px){ #bar { display:none; } }

  
/* ---------- FAB (nur Desktop — mobil uebernimmt die Bar) ---------- */
  #fab {
    position:fixed; right:18px; bottom:calc(18px + env(safe-area-inset-bottom)); z-index:60;
    width:56px; height:56px; border-radius:50%; background:var(--wa);
    display:none; align-items:center; justify-content:center;
    box-shadow:0 10px 26px rgba(22,21,19,0.28);
    border:none; cursor:pointer;
    opacity:0; pointer-events:none; transform:scale(0.8); transition:all .25s ease;
  }
  #fab svg { width:28px; height:28px; color:#fff; }
  @media(min-width:900px){
    #fab { display:flex; }
    #fab.show { opacity:1; pointer-events:auto; transform:none; }
  }


  
/* ---------- WhatsApp-Popup (Wundertuete vor der Buchung) ---------- */
  #wa-pop {
    /* Unter dem Einwilligungs-Dialog (130), ueber allem anderen. Bis 14.09.
       lag das Popup ueber der Leiste (120 gegen 110), damit ein bewusster
       WhatsApp-Klick es auch bei offener Leiste oeffnen konnte; der Dialog
       ist jetzt beantwortet, bevor irgendwer klicken kann. */
    position:fixed; inset:0; z-index:120; display:flex;
    align-items:center; justify-content:center; padding:22px;
    visibility:hidden; pointer-events:none; transition:visibility 0s .4s;
  }
  #wa-pop.open { visibility:visible; pointer-events:auto; transition:visibility 0s; }

  /* ---------- Scroll-Sperre, solange die Wunderttuete offen ist ----------
     Ohne das scrollt die Seite unter dem Popup weiter — das Popup steht dann
     ueber einer Section, die gar nicht mehr die ist, bei der es aufging.
     `overflow:hidden` auf <html> statt `position:fixed` auf <body>: die
     Fixed-Variante setzt scrollY auf 0 und stellt es beim Schliessen wieder her,
     und jede dieser Bewegungen feuert saemtliche ScrollTrigger dieser Seite neu.
     Mit overflow bleibt die Scrollposition, wo sie ist.
     --sbw ist die Breite der Scrollleiste, die durch das Ausblenden frei wird.
     Ohne Ausgleich springt das Layout auf Windows und Linux um ~15px nach rechts
     (macOS hat ueberlagernde Leisten, dort ist --sbw 0 und nichts passiert).
     Die drei fixierten Elemente brauchen den Ausgleich separat: sie haengen an
     der Viewport-Kante, und die wandert mit. */
  html.wa-offen { overflow:hidden; }
  html.wa-offen body,
  html.wa-offen #nav,
  html.wa-offen #bar { padding-right:calc(var(--sbw, 0px)); }
  html.wa-offen #fab { margin-right:var(--sbw, 0px); }
  #wa-pop .ov { position:absolute; inset:0; background:rgba(13,12,11,0.6); opacity:0; transition:opacity .32s ease; }
  #wa-pop.open .ov { opacity:1; }
  #wa-pop .card {
    position:relative; max-width:420px; width:100%; background:#fff; border-radius:22px;
    padding:34px 26px 30px; text-align:center; box-shadow:0 30px 80px rgba(0,0,0,0.35);
    opacity:0; transform:translateY(30px) scale(0.95);
    transition:transform .42s cubic-bezier(.34,1.45,.64,1), opacity .26s ease;
  }
  #wa-pop.open .card { opacity:1; transform:none; }
  #wa-pop h3 { font-family:'Barlow Condensed','Barlow Condensed Fallback',sans-serif; font-style:italic; font-weight:700; font-size:32px; margin-bottom:10px; }
  #wa-pop h3 .hl { color:var(--orange); }
  #wa-pop p { color:var(--ink2); font-size:15px; margin-bottom:18px; }
  #wa-pop p .fine { display:block; margin-top:6px; font-size:13.5px; color:var(--muted); }
  #wa-pop .btn { font-size:15px; }
  #wa-pop .x {
    position:absolute; top:8px; right:8px; width:44px; height:44px; border:none; background:none;
    cursor:pointer; color:var(--muted); font-size:22px; line-height:1;
  }
  
/* ---------- A11y ---------- */
  :focus-visible { outline:3px solid var(--orange-deep); outline-offset:3px; border-radius:4px; }
  .stats :focus-visible, .final :focus-visible, footer :focus-visible,
  .hero-pause:focus-visible, #fab:focus-visible { outline-color:#fff; }
  .sr-only {
    position:absolute; width:1px; height:1px; padding:0; margin:-1px;
    overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
  }

  
/* ---------- Reveal-Fallback (ohne GSAP) ---------- */
  .reveal { opacity:0; transform:translateY(22px); transition:opacity .6s ease, transform .6s ease; }
  .reveal.in { opacity:1; transform:none; }
  @media (prefers-reduced-motion: reduce) {
    .reveal { opacity:1; transform:none; transition:none; }
    html { scroll-behavior:auto; }
  }

  
/* ---------- Motion-Pre-States (nur mit GSAP aktiv) ---------- */
  html.ganim .reveal { transition:none; }
  html.ganim .pin-row,
  html.ganim .head-sub,
  html.ganim .chip,
  html.ganim .head-sec .book-btn,
  html.ganim .wa-row h2,
  html.ganim #wa-btn,
  html.ganim .wa-sub,
  html.ganim .stat,
  html.ganim .stack-head h2,
  html.ganim .stack-head p,
  html.ganim .final h2,
  html.ganim .final p,
  html.ganim .final .btns { opacity:0; }
  html.ganim .voices-head,
  html.ganim .vcard { opacity:0; }
  html.ganim .head-sec h1 .l1 { visibility:hidden; }
  /* Das Band wischte frueher von links herein (clip-path). Beim weichen
     Uebergang muss die Flaeche von Anfang an stehen, sonst reisst genau
     dort ein Loch, wo das Video ausblendet. Jetzt bewegen sich nur die
     Zahlen (.stat), das Band selbst nicht. */
  html.ganim .boxed { clip-path:inset(0% 100% 0% 0%); }
  html.ganim .stack-head .tag { clip-path:inset(0% 100% 0% 0%); }
  html.ganim .cat-card { opacity:0; }
  html.ganim .cat-card .pplate img { clip-path:polygon(0 0, 0 0, -14% 100%, -14% 100%); }

/* ---------- Motion-Pre-States der Aktivitaets-Sections ---------- */
  html.ganim .act-head h2,
  html.ganim .act-head p,
  html.ganim .stack li,
  html.ganim .pack .price-row,
  html.ganim .pack .price-note,
  html.ganim .pack .book-btn { opacity:0; }
  html.ganim .act-head .tag { clip-path:inset(0% 100% 0% 0%); }
  html.ganim .pcard { opacity:0; }
  html.ganim .maps-head h2, html.ganim .maps-head p, html.ganim .maps-hinweis,
  html.ganim .maps-tabs, html.ganim .mpanel { opacity:0; }
  html.ganim .felder-kopf h2, html.ganim .felder-kopf p, html.ganim .felder-strom, html.ganim .felder-namen { opacity:0; }

/* ---------- Motion-Pre-States FAQ ---------- */
  html.ganim .faq-head h2,
  html.ganim .faq-head p,
  html.ganim .fq { opacity:0; }
