/* ==========================================================================
   SCHRIFTEN — lokal ausgeliefert
   Vorher kamen sie von fonts.googleapis.com. Damit ging bei jedem Seitenaufruf
   die IP-Adresse des Besuchers an Google, ohne dass er gefragt wurde. Ein
   Cookie-Banner löst das nicht: Ein <link rel="stylesheet"> setzt keine Cookies,
   ein Cookie-Blocker greift dort also nicht — die Anfrage geht trotzdem raus.
   Lokal ausgeliefert entfällt die Übertragung ganz, und zwei fremde Domains
   fallen aus dem kritischen Ladepfad.

   Archivo ist ein variabler Schriftschnitt mit zwei Achsen: Gewicht 100–900 und
   Breite 62–125 %. Die Breitenachse trägt die gestauchte Anmutung der
   Überschriften (font-variation-settings 'wdth' im Rest der Datei) — mit festen
   Einzelschnitten statt der variablen Datei ginge genau das verloren.
   Josefin Sans ebenfalls variabel, 300–700: eine Datei statt fünf fester
   Schnitte spart 244 KB auf 52 KB.

   Kein vietnamesischer Zeichensatz — für eine deutschsprachige Seite ohne Nutzen.
   ========================================================================== */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('/fonts/archivo-latin-100-900.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: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('/fonts/archivo-latin-100-900-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: 'Josefin Sans';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/josefin-sans-latin-var.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: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('/fonts/archivo-latin-ext-100-900.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

@font-face {
  font-family: 'Archivo';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('/fonts/archivo-latin-ext-100-900-italic.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

@font-face {
  font-family: 'Josefin Sans';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/josefin-sans-latin-ext-var.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ==========================================================================
   TANZ NÜRNBERG — Yulia Avdonina · Tanzschule & TanzBühne
   Design v4: Kino-Foto. Die Fotografie ist das Design.
   Tinte auf Elfenbein · ein tiefblauer Akzent · Archivo (variable, wdth)
   Keine Karten-Grids, keine Pillen, kein Deko-Rauschen.
   Vanilla CSS · siehe DESIGN.md
   ========================================================================== */

:root {
  --ivory: #F7F4EE;
  --paper: #FFFFFF;
  --ink: #16181D;
  --ink-soft: #5F5B52;
  --line: #DCD6C9;
  --line-dark: rgba(22, 24, 29, .85);

  --blue: #1F3A5F;
  --blue-dark: #172C4A;

  --wa: #1FAF54;
  --wa-dark: #178F44;

  --font: 'Josefin Sans', 'Helvetica Neue', Arial, sans-serif;
  --font-heading: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --ease: cubic-bezier(.16, 1, .3, 1);
  --wrap: 1280px;
  --gutter: clamp(20px, 4vw, 56px);
}

/* ---------- Palette „Lebendig" — abgestimmt auf das Hero-Foto ----------
   (rosa/lila Tutus, warmes Licht). Gilt für Startseite & Kurse
   (body.palette-lively); die Raumvermietung behält Tinte/Blau. */
body.palette-lively {
  /* Aus dem Hero-Foto gezogen: violettes Bühnenlicht, Magenta-Rosa,
     warmes Holz, tiefe Pflaumen-Schatten */
  --ivory: #FAF3F2;                     /* warmes Weiß mit Rosé-Hauch */
  --paper: #FFFFFF;
  --ink: #251B2C;                       /* Pflaume-Schwarz (Bühnenschatten) */
  --ink-soft: #6E5F6F;
  --line: #E9DAE2;
  --line-dark: rgba(37, 27, 44, .85);
  --blue: #BE3D8B;                      /* Bühnen-Magenta als Akzent (Var-Name historisch) */
  --blue-dark: #9C2F72;
  --lilac: #6E4FB5;                     /* Bühnen-Violett als Zweitklang */
  --stage: #241A2E;                     /* dunkle Bühnen-Fläche */
}
body.palette-lively .cta-final {
  background: linear-gradient(140deg, var(--lilac) 0%, var(--blue) 78%);
}
body.palette-lively .cta-final .btn-ghost:hover { color: var(--blue); }
body.palette-lively .statement p strong { color: var(--blue); }
body.palette-lively ::selection { background: #F0D5E8; }
/* Platzhalter in Foto-Tonlage des Heros (Violett/Magenta, warmes Licht) */
body.palette-lively .ph:not(.ph--dark) {
  background:
    radial-gradient(circle at 25% 20%, rgba(255,244,230,.6) 0%, transparent 45%),
    radial-gradient(circle at 80% 78%, rgba(155,110,200,.4) 0%, transparent 50%),
    linear-gradient(150deg, #F2D3E4 0%, #D9B0D8 55%, #A98BD1 100%);
  color: #6E4470;
  /* WICHTIG: Longhands nach dem Shorthand, sonst kacheln
     inline eingesetzte Fotos (background-image) wieder */
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* Flip-Rückseite: Bühnen-Violett statt Tintenblau */
body.palette-lively .flip-back .veil { background: rgba(46, 28, 62, .88); }

/* ---------- Palette „Terra" — Raumvermietung ----------
   Creme, warmes Braun, frisches Salbei-Grün. */
body.palette-terra {
  --ivory: #F7F3EA;                     /* Creme */
  --paper: #FFFFFF;
  --ink: #2E2419;                       /* tiefes Braun */
  --ink-soft: #7A6B58;
  --line: #E3DAC8;
  --line-dark: rgba(46, 36, 25, .85);
  --blue: #6E8F4E;                      /* Salbei-Grün als Akzent (Var-Name historisch) */
  --blue-dark: #58753C;
  --lilac: #4A3A26;                     /* warmes Braun als Zweitklang (CTA-Gradient) */
}
body.palette-terra ::selection { background: #DFE8CB; }
body.palette-terra .cta-final {
  background: linear-gradient(140deg, var(--lilac) 0%, var(--blue) 82%);
}
body.palette-terra .ph:not(.ph--dark) {
  background:
    radial-gradient(circle at 25% 20%, rgba(255,252,240,.6) 0%, transparent 45%),
    radial-gradient(circle at 80% 78%, rgba(140,160,100,.35) 0%, transparent 50%),
    linear-gradient(150deg, #EFE6D2 0%, #DCD0B4 55%, #B9BE93 100%);
  color: #6B5C40;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: hidden; }

body {
  font-family: var(--font);
  font-variation-settings: 'wdth' 100;
  background: var(--ivory);
  color: var(--ink);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;   /* Fallback */
  overflow-x: clip;     /* bricht position:sticky nicht */
}

img, svg, video, iframe { max-width: 100%; display: block; }
a { color: var(--ink); text-decoration: none; }
ul { list-style: none; }
:focus-visible { outline: 3px solid var(--blue); outline-offset: 3px; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); position: relative; }

/* ---------- Typografie: Josefin Sans (Text) + Archivo (Überschriften) ---------- */
h1, h2, h3 {
  font-family: var(--font-heading);
  font-weight: 800;
  font-variation-settings: 'wdth' 118;
  font-style: italic;
  line-height: .98;
  letter-spacing: -.015em;
  text-transform: uppercase;
  color: var(--ink);
}
/* Umbruch INNERHALB eines Wortes nur dort, wo lange Komposita sonst aus
   dem Layout laufen (z.B. „Datenschutzerklärung", „Verbraucher­streit­
   beilegung"). Bewusst nicht global auf allen Überschriften: In den
   großen Hero-Titeln zerreißt es sonst Wörter wie „Kindergeburtstag"
   mitten im Wort — dort wird stattdessen die Schriftgröße begrenzt. */
.page-hero h1,
.legal-body h2,
.legal-body h3 { overflow-wrap: break-word; }

/* Silbentrennung für Abschnitts-Überschriften. Deutsche Komposita sprengen
   schmale Displays: Gemessen bei 320px Breite ragte „Erwachsenenkursen"
   172px, „Kindergeburtstag" 119px und „Raumvermietung" 82px über den rechten
   Rand hinaus (unsichtbar, weil html overflow-x: hidden trägt).
   hyphens trennt an den Silbengrenzen — das <html lang="de"> liefert dem
   Browser das Trennmuster —, greift aber nur, wenn die Zeile sonst nicht
   passt. Bei genug Platz bleibt der Umbruch also unverändert. overflow-wrap
   ist der Notnagel für Wörter ohne Trennmuster.
   H1 bleibt bewusst außen vor: Die großen Hero-Titel sind über die
   Schriftgröße gelöst, dort soll kein Wort getrennt werden.
   Nur bis 560px: hyphens:auto trennt nicht bloß im Notfall, sondern auch,
   wenn es der Zeilenaufteilung guttut — gemessen änderte es den Umbruch noch
   bei 1024px und 1440px, wo reichlich Platz ist. Auf großen Bildschirmen
   bliebe die Typografie also nicht so, wie sie gestaltet wurde. Über den
   rechten Rand liefen die Wörter dagegen nur bis 480px. */
@media (max-width: 560px) {
  h2, h3, .usage p {
    -webkit-hyphens: auto;
    hyphens: auto;
  }
  h2 em, h3 em { overflow-wrap: break-word; }
}
h1 { font-size: clamp(2.6rem, 7.5vw, 6.2rem); }
h2 { font-size: clamp(2rem, 4.6vw, 3.6rem); }
h3 { font-size: clamp(1.15rem, 1.8vw, 1.5rem); line-height: 1.15; }
h1 em, h2 em { color: var(--blue); }

/* Funktionales Mikro-Label (sparsam einsetzen) */
.label {
  display: block;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 18px;
}

.lead { font-size: clamp(1.05rem, 1.5vw, 1.25rem); line-height: 1.65; color: var(--ink-soft); max-width: 560px; }

section { padding: clamp(72px, 10vw, 140px) 0; position: relative; }

/* Linien als Struktur */
.rule { border: 0; border-top: 1px solid var(--line); }

/* ==========================================================================
   Buttons — rechteckig, entschieden
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 18px 30px;
  border: 1px solid var(--ink);
  border-radius: 2px;
  background: transparent;
  color: var(--ink);
  font-family: var(--font);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  transition: background .25s ease, color .25s ease, border-color .25s ease, transform .25s var(--ease);
}
.btn svg { width: 17px; height: 17px; flex: none; }
.btn:hover { transform: translateY(-2px); }

.btn-ink { background: var(--ink); color: var(--ivory); border-color: var(--ink); }
.btn-ink:hover { background: var(--blue); border-color: var(--blue); color: #fff; }

.btn-blue { background: var(--blue); color: #fff; border-color: var(--blue); }
.btn-blue:hover { background: var(--blue-dark); border-color: var(--blue-dark); }

.btn-wa { background: var(--wa); color: #fff; border-color: var(--wa); }
.btn-wa:hover { background: var(--wa-dark); border-color: var(--wa-dark); }

.btn-ghost { border-color: var(--ink); background: transparent; color: var(--ink); }
.btn-ghost:hover { background: var(--ink); color: var(--ivory); }

/* auf dunklen Fotos */
.on-photo .btn-ghost { border-color: #fff; color: #fff; }
.on-photo .btn-ghost:hover { background: #fff; color: var(--ink); }

.cta-note {
  display: flex; align-items: center; gap: 8px;
  margin-top: 14px;
  font-size: .82rem;
  color: var(--ink-soft);
}
.cta-note svg { width: 14px; height: 14px; color: var(--wa); flex: none; }
.on-photo .cta-note { color: rgba(255,255,255,.75); }

/* ==========================================================================
   Header — schmal, still
   ========================================================================== */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  background: transparent;
  transition: background .35s ease, box-shadow .35s ease;
}
.site-header.scrolled {
  background: rgba(247, 244, 238, .92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 1px 0 var(--line);
}
.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  height: 72px;
}
.brand { display: flex; align-items: center; gap: 10px; }
.brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.brand-icon { height: 40px; width: auto; display: block; }
/* Auf transparentem Foto-Header verschwindet das schwarze "A" im Icon
   gegen dunkle Hero-Fotos — Icon erst zeigen, sobald der Header (gleicher
   Moment wie der Text-Farbwechsel) einen hellen, blickdichten Hintergrund hat. */
.header-on-photo .site-header:not(.scrolled) .brand-icon { display: none; }
.brand-name {
  font-weight: 700;
  font-variation-settings: 'wdth' 118;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: 1.05rem;
  color: var(--ink);
}
.brand-sub { font-size: .62rem; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-soft); }

/* Header über dunklem Hero: helle Schrift bis zum Scrollen */
.header-on-photo .site-header:not(.scrolled) .brand-name,
.header-on-photo .site-header:not(.scrolled) .main-nav a { color: #fff; }
.header-on-photo .site-header:not(.scrolled) .brand-sub { color: rgba(255,255,255,.7); }
.header-on-photo .site-header:not(.scrolled) .main-nav a.btn { color: #fff; }
.header-on-photo .site-header:not(.scrolled) .nav-toggle span { background: #fff; }

/* Menü offen: Das seitliche Panel deckt die Kopfzeile nur rechts ab —
   links (Markenname) blieb bislang durchsichtig/im Foto-Zustand weiß
   auf hellem Grund kaum lesbar. Bei offenem Menü Kopfzeile immer
   deckend und Text immer dunkel, unabhängig von Scroll-/Foto-Status. */
body.nav-open .site-header {
  background: var(--ivory) !important;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 1px 0 var(--line);
}
body.nav-open.header-on-photo .site-header:not(.scrolled) .brand-name,
body.nav-open.header-on-photo .site-header:not(.scrolled) .main-nav a {
  color: var(--ink);
}
body.nav-open.header-on-photo .site-header:not(.scrolled) .brand-sub { color: var(--ink-soft); }

/* Fünf Menüpunkte plus CTA-Button: Mit den ursprünglichen Werten füllte
   die Navigation die Inhaltsbreite (max. 1168px) exakt aus und stieß
   direkt an den ausgeschriebenen Schulnamen. Abstand, Schriftgröße und
   Laufweite bleiben deshalb etwas kompakter. */
/* Gemessen: Marke 358px + Navigation 801px bei 1168px Inhaltsbreite — die
   Reihe war praktisch randvoll, zwischen Schulname und erstem Menüpunkt
   blieben je nach Breite 0 bis 14px. Bei 1181–1220px berührten sie sich,
   darunter wurde die Navigation zusätzlich gestaucht (gemessen 22px zu
   schmal). Abstände und Innenabstand des Buttons sind deshalb knapper — und
   das waagerechte Menü beginnt erst bei 1240px, wo gemessen 27px Luft
   bleiben. Darunter übernimmt das Burger-Panel, das den Platz nicht braucht. */
.main-nav { display: flex; align-items: center; gap: clamp(16px, 1.5vw, 21px); }
.main-nav a {
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--ink);
  position: relative;
  padding: 4px 0;
}
.main-nav a::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 0; height: 1.5px; background: currentColor;
  transition: width .25s var(--ease);
}
.main-nav a:hover::after, .main-nav a.active::after { width: 100%; }

/* ==========================================================================
   NAVIGATION: Untermenü unter „Kurse"
   Desktop (ab 1240px) klappt es als Flyout beim Hover auf, im Burger-Panel
   darunter als aufklappbare Liste per Pfeil-Button. Der Elternpunkt bleibt
   in beiden Fällen ein normaler Link auf die Übersichtsseite.
   ========================================================================== */
.nav-item { position: relative; display: flex; align-items: center; gap: 2px; }
.nav-sub-toggle {
  background: none; border: 0; padding: 6px 2px;
  display: inline-flex; align-items: center;
  color: inherit; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.nav-arrow { width: 11px; height: 11px; transition: transform .25s var(--ease); }
.nav-has-sub.open .nav-arrow { transform: rotate(180deg); }
.header-on-photo .site-header:not(.scrolled) .nav-sub-toggle { color: #fff; }

.main-nav a.btn { padding: 12px 16px; font-size: .72rem; }
.main-nav a.btn::after { display: none; }
.main-nav a.btn, .main-nav a.btn:hover { color: #fff; }

/* Flyout nur im horizontalen Menü — unterhalb übernimmt das Burger-Panel */
@media (min-width: 1240px) {
  /* Der ausgeschriebene Schulname ist der Markenkern und darf nicht
     gestaucht werden, wenn die waagerechte Navigation eng wird — dort gab
     die Marke sonst als erste nach. Bewusst nur hier: Im Burger-Bereich
     muss sie schrumpfen dürfen, sonst schiebt sie auf 320px-Displays den
     Menü-Knopf über den rechten Rand hinaus (gemessen 84px). */
  .brand { flex-shrink: 0; }
  .nav-sub {
    position: absolute; top: calc(100% + 16px); left: -12px;
    min-width: 264px;
    padding: 8px;
    display: grid; gap: 2px;
    background: var(--ivory);
    border: 1px solid var(--line);
    box-shadow: 0 20px 48px rgba(22, 24, 29, .18);
    opacity: 0; visibility: hidden; transform: translateY(-6px);
    transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
    z-index: 9100;
  }
  .nav-has-sub:hover .nav-sub,
  .nav-has-sub:focus-within .nav-sub,
  .nav-has-sub.open .nav-sub { opacity: 1; visibility: visible; transform: none; }
  /* Über Foto-Heros sind die Menülinks weiß — im hellen Flyout brauchen
     sie wieder die dunkle Textfarbe. */
  .main-nav .nav-sub a {
    color: var(--ink) !important;
    padding: 11px 12px;
    font-size: .7rem;
    line-height: 1.35;
  }
  .main-nav .nav-sub a::after { display: none; }
  .main-nav .nav-sub a:hover { background: var(--paper); color: var(--blue) !important; }
  .nav-sub .sub-note {
    display: block; margin-top: 3px;
    font-size: .64rem; letter-spacing: .1em;
    color: var(--ink-soft); text-transform: none;
  }
}

.nav-toggle { display: none; background: none; border: 0; cursor: pointer; width: 44px; height: 44px; position: relative; z-index: 9500; }
.nav-toggle span {
  display: block; width: 26px; height: 2px; margin: 6px auto;
  background: var(--ink); transition: .3s ease;
}
.nav-toggle.open span { background: var(--ink); }
.nav-toggle.open span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* ==========================================================================
   Foto-Platzhalter — neutral, kinoreif (werden durch Kundenfotos ersetzt)
   ========================================================================== */
.ph {
  position: relative;
  width: 100%;
  min-height: 100%;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: linear-gradient(150deg, #C9C2B4 0%, #A79E8D 55%, #857C6B 100%);
  /* Für echte Fotos (per Inline-style background-image eingesetzt):
     immer formatfüllend, zentriert, NIE gekachelt */
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* Fotos als <img> eingesetzt: ebenfalls formatfüllend */
.ph > img,
.ph > picture > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Kurzvideos (Kurs-Kolonnen): gleiche Ausfüll-Logik wie <img> */
.ph > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
/* dunkle Kino-Variante für Text-Overlays */
.ph--dark {
  background:
    radial-gradient(ellipse 80% 60% at 50% 20%, rgba(255,255,255,.12) 0%, transparent 60%),
    linear-gradient(165deg, #3B382F 0%, #23211C 100%);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* In den Kurs-Kolonnen: Fokus etwas höher, damit beim Aufklappen
   Gesichter statt Bäuche im Bild bleiben (hohe Spezifität nötig,
   um die palette-lively-Regel zu schlagen) */
.h-scroll .panel-media .ph img { object-position: center 22%; }
.h-scroll .panel-media .ph.has-video video { object-position: center 22%; }

/* langsamer Ken-Burns-Zoom auf Hero-Fotos */
.kenburns .ph { animation: kenburns 26s ease-in-out infinite alternate; }
@keyframes kenburns {
  from { transform: scale(1); }
  to   { transform: scale(1.08); }
}
@media (prefers-reduced-motion: reduce) { .kenburns .ph { animation: none; } }

/* ==========================================================================
   HERO — Vollbild-Foto, Text unten links
   Auf Seiten mit .sheet: Hero klebt fest, der Inhalt schiebt sich
   mit halbrunder Oberkante darüber (Bogen flacht beim Scrollen ab).
   ========================================================================== */
.hero-cine {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  padding: 0;
  /* Harte Untergrenze für den bodenbündigen Text: reicht der Platz auf
     kurzen/schmalen Screens nicht (H1 + Lead + CTAs + Fakten höher als
     100svh), wächst die Box über min-height hinaus — ohne diesen Abstand
     würde der Inhalt dann ganz oben beginnen, direkt unter/hinter der
     fixen Kopfzeile (72px hoch). */
  padding-top: 72px;
}
body.has-sheet .hero-cine { position: sticky; top: 0; z-index: 0; }
/* Startseite: Hero bleibt NICHT gepinnt — bei viel Hero-Inhalt (H1 + Lead +
   CTAs + Fakten) schiebt sich der bodenbündige Text sonst auf kurzen
   Viewports unter die fixe Kopfzeile. Scrollt hier stattdessen normal weg,
   der Bogen-Reveal-Effekt der .sheet-Kante bleibt trotzdem erhalten. */
body.hero-unpinned .hero-cine { position: relative; }

/* Start: flache Kante, kein Bogen. Beim Scrollen schiebt sich der Inhalt
   über den fixierten Hero und wölbt sich dabei zunehmend zum Halbkreis. */
.sheet {
  --arc-max: 160px;
  --arc-h: 0.001px;
  position: relative;
  z-index: 2;
  background: var(--ivory);
  border-radius: 50% 50% 0 0 / var(--arc-h) var(--arc-h) 0 0;
  will-change: border-radius;
}
@media (max-width: 820px) {
  .sheet { --arc-max: 90px; }
  /* Sticky-Pin bleibt (Bogen-Effekt beim Reinscrollen soll auch mobil
     sichtbar sein) — stattdessen genug Extra-Höhe reservieren, damit
     der bodenbündige Inhalt nicht mit der fixen Kopfzeile kollidiert. */
  .hero-cine { min-height: calc(100svh + 72px); }
  .hero-cine .wrap { padding-bottom: clamp(36px, 7vh, 64px); }
  .hero-facts { gap: 24px 32px; margin-top: 28px; padding-top: 20px; }
}
@media (max-width: 480px) {
  h1 { font-size: clamp(2.1rem, 10vw, 6.2rem); }
}
.hero-cine .media { position: absolute; inset: 0; }
.hero-cine .scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(15,16,20,.35) 0%, rgba(15,16,20,0) 30%),
    linear-gradient(0deg, rgba(15,16,20,.78) 0%, rgba(15,16,20,.25) 45%, rgba(15,16,20,0) 70%);
}
/* Tanzraum-mieten-Hero: Das Weitwinkelfoto des leeren Saals ist durchgehend
   hell — helles Parkett, weiße Wände, Spiegelwand. Gemessen liegt die
   Textzone je nach Bildausschnitt bei 147–180 von 255, weißer Text braucht
   darauf die kräftigste Abdunkelung der Seite. Die Palette terra nutzt nur
   diese Seite, die Regel greift also nirgends sonst.
   Der Verlauf deckt die volle Höhe ab statt nur den unteren Rand: Gemessen
   reicht der Textblock (H1, Lead, Buttons, Fakten) von 5 % bis 83 % der
   Hero-Höhe — ein Verlauf, der bei 70 % ausläuft, lässt die H1-Oberkante
   ungeschützt. Oben bleibt Restdeckkraft .3, damit die Holzdecke sichtbar
   bleibt und die weißen Kopfzeilen-Links Kontrast behalten. */
body.palette-terra .hero-cine .scrim {
  background: linear-gradient(0deg,
    rgba(15,16,20,.9) 0%,
    rgba(15,16,20,.78) 30%,
    rgba(15,16,20,.6) 62%,
    rgba(15,16,20,.42) 86%,
    rgba(15,16,20,.3) 100%);
}
/* Kindergeburtstags-Hero: dasselbe Problem wie oben, nur ohne eigene
   Palette als Aufhänger (die Seite nutzt palette-lively wie die
   Startseite, deren dunkles Bühnenfoto die Verstärkung nicht braucht).
   Das Standbild aus dem Geburtstagsvideo ist durchgehend hell — heller
   Parkett, Spiegelwand, weiße Wände —, weißer Text braucht darauf eine
   deutlich kräftigere Abdunkelung. */
.hero-cine--bright .scrim {
  background:
    linear-gradient(180deg, rgba(15,16,20,.42) 0%, rgba(15,16,20,0) 32%),
    linear-gradient(0deg, rgba(15,16,20,.88) 0%, rgba(15,16,20,.58) 44%, rgba(15,16,20,.18) 74%);
}
.hero-cine .wrap { position: relative; z-index: 2; padding-bottom: clamp(48px, 8vh, 96px); width: 100%; }
.hero-cine h1 { color: #fff; max-width: 15ch; text-shadow: 0 2px 18px rgba(0,0,0,.35); }
/* Hero-Titel mit langem Kompositum („Kindergeburtstag" ist rund 13em
   breit): Die Standard-Begrenzung von 15ch entspricht nur gut 11em — das
   Wort passt dort grundsätzlich in keiner Schriftgröße hinein und würde
   entweder mitten im Wort umbrechen oder aus dem Layout ragen. Deshalb
   ohne Breitenlimit und mit einer Größe, die das längste Wort auf jeder
   Viewport-Breite in eine Zeile bringt. */
.hero-cine h1.hero-title--compound {
  max-width: none;
  font-size: clamp(1.3rem, 6.6vw, 5.4rem);
}
.hero-cine .lead { color: rgba(255,255,255,.82); margin: 22px 0 34px; text-shadow: 0 1px 12px rgba(0,0,0,.3); }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* Zahlenzeile am Hero-Fuß */
.hero-facts {
  display: flex; flex-wrap: wrap;
  gap: clamp(28px, 5vw, 72px);
  margin-top: clamp(36px, 6vh, 64px);
  padding-top: 26px;
  border-top: 1px solid rgba(255,255,255,.28);
}
.hero-facts .fact { color: #fff; }
.hero-facts .num {
  font-size: clamp(1.5rem, 2.6vw, 2.2rem);
  font-weight: 700;
  font-variation-settings: 'wdth' 118;
  line-height: 1;
}
.hero-facts .lbl { font-size: .72rem; letter-spacing: .18em; text-transform: uppercase; color: rgba(255,255,255,.65); margin-top: 6px; }

/* ==========================================================================
   Editorial-Statement
   ========================================================================== */
.statement { padding: clamp(88px, 12vw, 160px) 0; }
.statement .inner { max-width: 980px; }
.statement p {
  font-size: clamp(1.5rem, 3.2vw, 2.6rem);
  line-height: 1.25;
  font-weight: 500;
  letter-spacing: -.01em;
  text-wrap: balance;
}
.statement p strong { color: var(--blue); font-weight: 700; }
.statement .label { margin-bottom: 28px; }

/* ==========================================================================
   Kurs-Kolonnen — bildschirmhoher Akkordeon aus schrägen Foto-Kolonnen.
   Eine Kolonne ist offen (Großteil des Bildschirms), die übrigen sind
   schmale Streifen, deren Text parallel zu den Diagonalkanten läuft.
   Vertikaler Scroll schiebt den Fokus nach rechts. Mobile: Wisch-Bahn.
   ========================================================================== */
.h-scroll { padding: 0; }
.h-scroll .pin { display: flex; align-items: stretch; }
.h-scroll.jack .pin {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}

.h-track { display: flex; width: 100%; }

/* --- Panel-Grundlagen --- */
.panel {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--line);
}
.panel-media { position: absolute; inset: -8px -70px; }
.panel-media .ph { transition: transform .65s var(--ease); }
.panel::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(15,16,20,.72) 0%, rgba(15,16,20,.1) 45%, transparent 65%);
  pointer-events: none;
}
/* Abdunkelung für eingeklappte Streifen */
.panel::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(15, 16, 20, .45);
  opacity: 0;
  transition: opacity .5s ease;
  pointer-events: none;
  z-index: 1;
}

/* Horizontale Bildunterschrift (nur offene Kolonne) */
.panel-cap {
  position: absolute;
  left: 34px; right: 24px; bottom: 26px;
  z-index: 2;
  color: #fff;
}
.panel-cap .pname {
  display: block;
  font-weight: 700;
  font-variation-settings: 'wdth' 114;
  text-transform: uppercase;
  font-size: clamp(1.2rem, 2.2vw, 2rem);
  line-height: 1.02;
  letter-spacing: -.01em;
}
.panel-cap .page { display: block; margin-top: 10px; font-size: .72rem; letter-spacing: .18em; text-transform: uppercase; color: rgba(255,255,255,.72); }

/* Vertikale Beschriftung (nur eingeklappte Streifen):
   rotierter Text im geschrägten Panel läuft automatisch
   parallel zur Diagonalkante */
.v-cap {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%) rotate(-90deg);
  z-index: 2;
  white-space: nowrap;
  color: #fff;
  font-weight: 700;
  font-variation-settings: 'wdth' 112;
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: clamp(1rem, 1.2vw, 1.3rem);
}

/* Gruppen-Abschlusskolonne: schließt den Kinder- bzw. Erwachsenenblock ab
   und führt auf die jeweilige Kursseite. Dunkle Bühnenfläche statt Foto,
   damit sie klar als Blockgrenze gelesen wird und nicht als weiterer Kurs. */
.panel--group { background: var(--stage, var(--ink)); }
.panel--group::after, .panel--group::before { display: none; }
.panel--group .panel-cap { text-align: left; }
.panel--group .pname { color: #fff; }
.panel--group .arr-big { display: block; font-size: 2.2rem; margin-top: 12px; font-weight: 300; color: rgba(255,255,255,.75); }
.panel--group .v-cap { color: rgba(255,255,255,.62); }
.panel--group:hover { background: var(--lilac, var(--blue)); }
/* Eigener Ton für den Erwachsenenblock. Im Desktop-Akkordeon fällt die
   Drehpunkt-Kolonne zwischen den beiden Gruppenkarten weg, sie stoßen dort
   direkt aneinander — zwei gleich dunkle Flächen ohne Trennlinie würden zu
   einer einzigen breiten Fläche verschmelzen. */
.panel--group-erw { background: var(--lilac, var(--ink)); }
.panel--group-erw:hover { background: var(--blue); }

/* CTA-Kolonne */
.panel--cta { background: var(--blue); }
.panel--cta::after, .panel--cta::before { display: none; }
.panel--cta .panel-cap { text-align: left; }
.panel--cta .arr-big { display: block; font-size: 2.6rem; margin-top: 14px; font-weight: 300; color: #fff; }
.panel--cta:hover { background: var(--blue-dark); }

/* Wisch-Hinweise: nur im mobilen Karussell sichtbar (siehe unten). Im
   Desktop-Akkordeon gibt es kein Wischen, dort bleiben sie ausgeblendet. */
.swipe-hint { display: none; }

/* --- Akkordeon-Modus (Desktop, JS setzt .jack) ---
   Panels sind ungeschrägte Rechtecke; die Diagonalen entstehen per
   clip-path und die Nachbarn überlappen sich exakt um den Schrägungs-
   versatz --g. Erste Kolonne: linke Kante gerade, letzte: rechte Kante
   gerade — kein offener Hintergrund an den Bildschirmrändern. */
.h-scroll.jack {
  --g: 10.5svh;
  /* Breite der offenen Kolonne: gedeckelt, damit das Foto nicht
     ins Extrem-Querformat gezerrt wird */
  --open: min(52vw, 880px);
  /* Zahl der eingeklappten Streifen = Kolonnen minus die offene. Wird von
     main.js aus der tatsächlichen Kolonnenzahl gesetzt; der Wert hier ist
     nur der Rückfall. Vorher stand hier fest 9 — nach jeder neuen Kolonne
     wurde die Reihe dadurch breiter als der Bildschirm und die letzten
     Kurse rutschten aus dem Bild. */
  --strips: 11;
}
.h-scroll.jack .h-track { width: 100%; height: 100%; }
/* Drehpunkt-Kolonne: existiert nur fürs mobile Karussell */
.h-scroll.jack .panel--loop { display: none; }
.h-scroll.jack .panel {
  flex: none;
  /* Die Streifen teilen sich exakt den Rest neben der offenen Kolonne:
     open + strips × ((100vw − open)/strips + g) − strips × g = 100vw */
  width: calc((100vw - var(--open)) / var(--strips) + var(--g));
  height: 100%;
  margin-left: calc(-1 * var(--g));
  clip-path: polygon(var(--g) 0, 100% 0, calc(100% - var(--g)) 100%, 0 100%);
  transition: width .7s var(--ease);
  cursor: pointer;
}
.h-scroll.jack .panel:first-child {
  margin-left: 0;
  clip-path: polygon(0 0, 100% 0, calc(100% - var(--g)) 100%, 0 100%);
}
.h-scroll.jack .panel:last-child {
  clip-path: polygon(var(--g) 0, 100% 0, 100% 100%, 0 100%);
  /* elastisch: fängt Breiten-Drift während laufender Transitions ab,
     damit die rechte Kante nie vom Bildschirmrand ablöst */
  flex: 1 1 auto;
  min-width: calc((100vw - var(--open)) / var(--strips) / 2 + var(--g));
}
.h-scroll.jack .panel.open { width: var(--open); }
.h-scroll.jack .panel-media { transform: none; inset: 0; }
.h-scroll.jack .panel-cap {
  left: calc(var(--g) * .35 + 24px);
  opacity: 0;
  translate: 0 14px;
  transition: opacity .45s ease .2s, translate .45s var(--ease) .2s;
}
.h-scroll.jack .panel.open .panel-cap { opacity: 1; translate: 0 0; }
.h-scroll.jack .panel:not(.open)::before { opacity: 1; }
.h-scroll.jack .panel:not(.open):hover::before { opacity: .55; }
/* Vertikaltext: um -6° geschert = parallel zu den Diagonalkanten */
.h-scroll.jack .v-cap {
  transform: translate(-50%, -50%) skewX(-6deg) rotate(-90deg);
  opacity: 1;
  transition: opacity .3s ease;
}
.h-scroll.jack .panel.open .v-cap { opacity: 0; }

/* --- Mobile: 3D-Karussell statt Wisch-Bahn ---
   Karten stehen im Halbkreis (perspective + rotateY + translateZ),
   ein Swipe dreht das Karussell weiter. Ein einzelner Tap auf eine
   Karte — egal ob zentral oder seitlich — folgt sofort ihrem Link;
   nur ein erkannter horizontaler Drag dreht statt zu navigieren. */
.h-scroll:not(.jack) .pin { padding: clamp(24px, 4vh, 44px) 0; }
.h-scroll:not(.jack) .h-track {
  position: relative;
  height: 60svh;
  max-height: 440px;
  perspective: 1300px;
  touch-action: pan-y;
}
.h-scroll:not(.jack) .panel {
  position: absolute;
  top: 0; left: 50%;
  width: min(72vw, 320px);
  /* Halbe Kartenbreite als Margin statt translateX(-50%) im Transform:
     Ein Prozentwert im Transform muss der Browser in jedem Frame gegen die
     Elementbreite auflösen. So bleibt der animierte Transform reine
     Pixel-Arithmetik, die der Compositor ohne Rückfrage ans Layout abarbeitet. */
  margin-left: calc(min(72vw, 320px) / -2);
  height: 100%;
  box-shadow: 0 24px 48px rgba(22,24,29,.38);
  /* Kein backface-visibility nötig: HS_ROT × HS_FADE in main.js deckelt die
     Drehung auf 78°, eine Karte kippt also nie über die Kante. Die
     Eigenschaft erzwingt auf iOS eigene Ebenen und wäre hier nur zusätzliche
     Arbeit ohne Wirkung. will-change setzt main.js gezielt auf die
     sichtbaren Karten. */
}
/* Während Wischen und Nachlauf ohne den 48px-Weichzeichner.
   Ein weicher Schlagschatten ist das teuerste, was eine Ebene enthalten
   kann, und WebKit rastert eine Ebene neu, wenn sich ihr Maßstab ändert —
   beim Wischen also fortlaufend, für jede Karte einzeln. Der harte Ersatz
   trennt die Karten optisch weiter, kostet aber keinen Weichzeichner.
   Im Ruhezustand ist der weiche Schatten wieder da. */
.h-scroll:not(.jack) .h-track.hs-drag .panel {
  box-shadow: 0 0 0 1px rgba(255,255,255,.14);
}
/* Kein Parallax im Karussell (siehe plyHosts in main.js) und deshalb auch
   kein Überstand mehr: Die Grundregel zieht das Medium um 70px pro Seite
   über die Karte hinaus, damit es sich bewegen kann, ohne Ränder
   freizugeben. Ohne Bewegung wurde damit nur die halbe Kartenbreite
   zusätzlich gerastert und weggeschnitten — bei sieben sichtbaren Karten
   in jedem Frame. */
.h-scroll:not(.jack) .panel-media { inset: 0; transform: none; }
.h-scroll:not(.jack) .panel-cap { left: 24px; right: 24px; bottom: 28px; }
.h-scroll:not(.jack) .panel-cap .pname { font-size: 1.4rem; }
.h-scroll:not(.jack) .v-cap { display: none; }

/* --- Wisch-Hinweise auf den beiden CTA-Karten ---
   Sie sind die Drehpunkte des Kreises: von hier geht es in die eine
   Richtung in den Kinder-, in die andere in den Erwachsenenblock. Ohne
   Beschriftung ist einem Erstbesucher nicht klar, dass die Karten
   überhaupt gewischt werden — deshalb steht die Richtung auf der Karte,
   oben und unten je eine.
   Der Pfeil zeigt auf die Seite, auf der der Block im Stapel liegt, nicht
   auf die Fingerbewegung: Beides ist gegenläufig (nach links wischen holt
   die rechte Karte herein), und eine Beschriftung, die von der
   Fingerrichtung spricht, liest sich neben dem Pfeil zwangsläufig
   vertauscht. */
.h-scroll:not(.jack) .panel--cta .swipe-hint {
  display: block;
  position: absolute; left: 24px; right: 24px;
  z-index: 2;
  color: rgba(255,255,255,.72);
  font-size: .66rem; letter-spacing: .16em; text-transform: uppercase;
  line-height: 1.3;
}
.h-scroll:not(.jack) .panel--cta .swipe-hint--top { top: 26px; }
.h-scroll:not(.jack) .panel--cta .swipe-hint--bottom { bottom: 26px; }
/* Rechts zeigender Hinweis auch rechts ausgerichtet — sonst steht der
   Pfeil mitten auf der Karte und deutet ins Leere. */
.swipe-hint--rechts { text-align: right; }
.swipe-hint em {
  display: block; margin-top: 5px;
  font-style: normal; font-weight: 700;
  font-size: .84rem; letter-spacing: .01em; text-transform: none;
  color: #fff;
}
.sh-arrow {
  display: inline-block;
  font-size: 1.05rem; line-height: 1; vertical-align: -1px;
  color: #fff;
}
.sh-arrow--left { margin-right: 9px; }
.sh-arrow--right { margin-left: 9px; }
/* Kleiner Dauer-Anstoß in Wischrichtung — macht ohne Text klar, dass die
   Karte seitlich weitergeht. */
@media (prefers-reduced-motion: no-preference) {
  .sh-arrow--left { animation: sh-nudge-left 2.4s var(--ease) infinite; }
  .sh-arrow--right { animation: sh-nudge-right 2.4s var(--ease) infinite; }
}
@keyframes sh-nudge-left {
  0%, 62%, 100% { transform: translateX(0); }
  80% { transform: translateX(-6px); }
}
@keyframes sh-nudge-right {
  0%, 62%, 100% { transform: translateX(0); }
  80% { transform: translateX(6px); }
}
/* Titel in die Kartenmitte, sonst stößt er unten an den Wisch-Hinweis */
.h-scroll:not(.jack) .panel--cta .panel-cap {
  top: 50%; bottom: auto;
  transform: translateY(-50%);
}
/* Der große Pfeil unter dem Titel wäre auf der Drehpunkt-Karte der dritte
   Pfeil neben den beiden Wisch-Hinweisen und würde als weitere Richtung
   gelesen. Im Desktop-Akkordeon gibt es die Hinweise nicht, dort bleibt er. */
.h-scroll:not(.jack) .panel--cta .arr-big { display: none; }

/* ==========================================================================
   Vollbild-Foto-Band (Saal / Zwischenkapitel)
   ========================================================================== */
.photo-band {
  position: relative;
  min-height: clamp(480px, 82vh, 780px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  padding: 0;
}
.photo-band .media { position: absolute; inset: 0; }
.photo-band .scrim {
  position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(15,16,20,.75) 0%, rgba(15,16,20,.15) 55%, rgba(15,16,20,.1) 100%);
}
.photo-band .wrap { position: relative; z-index: 2; padding-bottom: clamp(40px, 7vh, 80px); width: 100%; }
.photo-band h2 { color: #fff; max-width: 16ch; }
.photo-band .label { color: rgba(255,255,255,.65); }
.photo-band .lead { color: rgba(255,255,255,.8); margin: 16px 0 28px; }

/* ==========================================================================
   Bühnen-Band „Warum wir" — dunkle Fläche im Licht der Scheinwerfer,
   Argumente als 2×2-Raster mit Linien
   ========================================================================== */
.stage-band {
  position: relative;
  background:
    radial-gradient(ellipse 45% 60% at 12% 0%, rgba(190, 61, 139, .28) 0%, transparent 65%),
    radial-gradient(ellipse 45% 60% at 88% 8%, rgba(110, 79, 181, .32) 0%, transparent 65%),
    radial-gradient(ellipse 60% 50% at 50% 110%, rgba(201, 138, 95, .18) 0%, transparent 60%),
    var(--stage, #241A2E);
  overflow: hidden;
}
.stage-grid { display: grid; grid-template-columns: 1fr 1.4fr; gap: clamp(36px, 5vw, 90px); align-items: start; }
.stage-grid .sticky { position: sticky; top: 110px; }
.stage-band .label { color: rgba(255,255,255,.5); }
.stage-band h2 { color: #fff; }
.stage-band .lead { color: rgba(255,255,255,.6); margin-top: 18px; }

.r2-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(36px, 4vw, 56px) clamp(28px, 3vw, 48px); }
.r2 { border-top: 1px solid rgba(255,255,255,.25); padding-top: 20px; }
.r2 .num {
  display: block;
  font-size: .7rem; font-weight: 700; letter-spacing: .22em;
  color: #E06BB0;
  margin-bottom: 12px;
}
.r2 h3 { color: #fff; margin-bottom: 8px; }
.r2 p { color: rgba(255,255,255,.62); font-size: .95rem; }

/* ==========================================================================
   Zitate — typografische Collage: drei Stimmen in drei Größen,
   asymmetrisch versetzt, alles auf einen Blick
   ========================================================================== */
.q-collage {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 24px;
  margin-top: clamp(32px, 5vw, 56px);
}
.qc { margin: 0; }
.qc::before {
  content: "";
  display: block;
  width: 44px; height: 2px;
  background: var(--blue);
  margin-bottom: 18px;
}
.qc p {
  font-weight: 500;
  letter-spacing: -.01em;
  line-height: 1.35;
  text-wrap: balance;
}
.qc footer {
  margin-top: 16px;
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.qc--big { grid-column: 1 / span 8; }
.qc--big p { font-size: clamp(1.5rem, 3vw, 2.4rem); }
.qc--side { grid-column: 10 / span 3; margin-top: clamp(64px, 9vw, 140px); }
.qc--side p { font-size: 1.02rem; line-height: 1.6; }
.qc--low { grid-column: 3 / span 5; margin-top: clamp(8px, 2vw, 24px); }
.qc--low p { font-size: clamp(1.1rem, 1.7vw, 1.4rem); }
@media (max-width: 860px) {
  .qc--big, .qc--side, .qc--low { grid-column: 1 / -1; margin-top: 0; }
  /* Einspaltig, nicht bloß volle Zeilenbreite: Die zwölf Spalten blieben
     sonst bestehen, und mit ihnen elf Lücken à 36px. Allein die Lücken
     ergaben eine Mindestbreite von 396px — unter etwa 436px Viewport
     liefen die Zitate samt Quellenangabe über den rechten Rand hinaus
     (nur unsichtbar, weil html overflow-x: hidden trägt). */
  .q-collage { grid-template-columns: 1fr; gap: 36px; }
}

/* ==========================================================================
   Longread — SEO-Vertiefungstext, standardmäßig eingeklappt
   ========================================================================== */
.longread { max-width: 72ch; }
.longread-body {
  max-height: 260px;
  overflow: hidden;
  position: relative;
  transition: max-height .5s var(--ease);
}
.longread-body h3 { margin: 28px 0 10px; font-size: clamp(1.05rem, 1.6vw, 1.3rem); }
.longread-body h3:first-child { margin-top: 0; }
.longread-body p { color: var(--ink-soft); font-size: .98rem; line-height: 1.7; margin-bottom: 14px; }
.longread-body::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 90px;
  background: linear-gradient(0deg, var(--ivory) 0%, rgba(247,244,238,0) 100%);
  pointer-events: none;
  transition: opacity .3s ease;
}
.longread.open .longread-body::after { opacity: 0; }
.longread-toggle {
  margin-top: 18px;
  display: inline-flex; align-items: center; gap: 8px;
  background: none;
  border: 1px solid var(--ink);
  border-radius: 2px;
  padding: 12px 22px;
  font-family: var(--font);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  transition: background .25s ease, color .25s ease;
}
.longread-toggle:hover { background: var(--ink); color: var(--ivory); }
.longread-toggle svg { width: 13px; height: 13px; transition: transform .3s var(--ease); }
.longread.open .longread-toggle svg { transform: rotate(180deg); }
.longread-toggle .txt-less { display: none; }
.longread.open .longread-toggle .txt-more { display: none; }
.longread.open .longread-toggle .txt-less { display: inline; }

/* Rechtstexte (Impressum/Datenschutz): gleiche Typografie wie Longread, aber ohne Höhenbegrenzung */
.legal-body { max-width: 72ch; }
.legal-body h2 { font-size: clamp(1.4rem, 2.2vw, 1.9rem); margin: 48px 0 6px; }
.legal-body h2:first-child { margin-top: 0; }
.legal-body h3 { margin: 26px 0 8px; font-size: clamp(1.02rem, 1.5vw, 1.2rem); }
.legal-body h3:first-child { margin-top: 0; }
.legal-body p { color: var(--ink-soft); font-size: .96rem; line-height: 1.7; margin-bottom: 14px; }
.legal-body a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.legal-body a:hover { color: var(--blue); }

/* ==========================================================================
   FAQ — Linien, kein Karton
   ========================================================================== */
.faq { max-width: 860px; margin: 0 auto; border-top: 1px solid var(--line-dark); }
.faq-item { border-bottom: 1px solid var(--line-dark); }
.faq-q {
  width: 100%; text-align: left; background: none; border: 0; cursor: pointer;
  font-family: var(--font);
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  font-weight: 700;
  color: var(--ink);
  padding: 24px 54px 24px 0;
  position: relative;
  text-transform: none;
}
.faq-q::after {
  content: "+"; position: absolute; right: 6px; top: 50%;
  transform: translateY(-50%);
  font-size: 1.6rem; font-weight: 300; color: var(--blue);
  transition: transform .3s var(--ease);
}
.faq-item.open .faq-q::after { transform: translateY(-50%) rotate(45deg); }
.faq-a { max-height: 0; overflow: hidden; transition: max-height .35s var(--ease); }
.faq-a-inner { padding: 0 0 24px; color: var(--ink-soft); font-size: .98rem; max-width: 64ch; }
.faq-a-inner a { color: var(--blue); text-decoration: underline; text-underline-offset: 3px; }

/* ==========================================================================
   Kontakt
   ========================================================================== */
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 80px); align-items: start; }
.contact-block { border-top: 1px solid var(--line-dark); padding-top: 22px; margin-bottom: 34px; }
.contact-block .label { margin-bottom: 12px; }
.contact-block p, .contact-block a { font-size: clamp(1.05rem, 1.6vw, 1.3rem); font-weight: 600; }
.contact-block a:hover { color: var(--blue); }
.hours { font-size: .95rem; margin-top: 6px; }
.hours div { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--line); max-width: 380px; }
.hours div:last-child { border: 0; }
.hours span:last-child { color: var(--ink-soft); }
/* Karte mit Rückfallebene.
   Cookiebot hält die Google-Karte bis zur Einwilligung zurück, indem es das
   src-Attribut entfernt. Zurück bliebe ein leerer 420px-Kasten ohne jede
   Erklärung — an einer Stelle, an der Besucher die Adresse suchen. Deshalb
   liegt darunter eine eigene Fläche mit Anschrift, Hinweis und zwei Wegen
   weiter: Einwilligung nachholen oder direkt zu Google Maps wechseln. */
.map-wrap { position: relative; min-height: 420px; }
.map-frame { border: 0; width: 100%; height: 100%; min-height: 420px; filter: grayscale(1) contrast(1.05); position: relative; z-index: 1; }
.map-fallback {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: center;
  gap: 10px;
  padding: clamp(24px, 4vw, 40px);
  background: var(--paper);
  border: 1px solid var(--line-dark);
}
.map-fallback[hidden] { display: none; }
.map-fallback p { font-size: 1.05rem; line-height: 1.5; }
.map-fallback-note { font-size: .9rem; color: var(--ink-soft); max-width: 42ch; }
.map-fallback .btn { align-self: flex-start; margin-top: 6px; }
.map-fallback-link { font-size: .8rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
.map-fallback-link:hover { color: var(--blue); }

/* ==========================================================================
   Finaler CTA — Tintenblau, große Type
   ========================================================================== */
.cta-final {
  background: var(--blue);
  color: #fff;
  padding: clamp(80px, 11vw, 150px) 0;
  margin: 0;
}
.cta-final h2 { color: #fff; max-width: 18ch; }
.cta-final .lead { color: rgba(255,255,255,.78); margin: 20px 0 36px; }
.cta-final .label { color: rgba(255,255,255,.6); }
.cta-final .cta-note { color: rgba(255,255,255,.7); }
.cta-final .btn-ghost { border-color: #fff; color: #fff; }
.cta-final .btn-ghost:hover { background: #fff; color: var(--blue); }

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer { background: var(--ink); color: #B9B4A9; padding: 64px 0 32px; }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 40px; margin-bottom: 48px; }
.footer-grid--simple { grid-template-columns: 1.5fr 1fr; }
.site-footer h4 { color: #fff; font-size: .74rem; letter-spacing: .2em; text-transform: uppercase; margin-bottom: 18px; font-weight: 700; }
.site-footer a { color: #B9B4A9; font-size: .93rem; }
.site-footer a:hover { color: #fff; }
.site-footer li { margin-bottom: 10px; }
.footer-brand .brand-name { color: #fff; font-size: 1.2rem; }
.footer-brand p { font-size: .9rem; margin-top: 14px; max-width: 300px; color: #8D897F; }
.footer-bottom { border-top: 1px solid rgba(255,255,255,.14); padding-top: 26px; font-size: .8rem; color: #8D897F; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px; }

/* Freistehende Links in Fußzeile und Kontaktblock sind nur 15–17px hoch und
   damit kleiner als die 24px, die für ein Tippziel gelten. Die Trefferfläche
   wächst per Pseudo-Element nach oben und unten; Textgröße, Zeilenabstand und
   Umbruch bleiben unverändert. Nur senkrecht erweitert — waagerecht sind alle
   breit genug, und ein seitlicher Überstand ließe benachbarte Flächen wie
   „Impressum · Datenschutz" überlappen.
   Links mitten im Satz (Longread, FAQ-Antworten) sind ausgenommen: dort ist
   die kleine Fläche unvermeidbar und laut Richtlinie auch zulässig. */
.site-footer li a, .footer-bottom a, .contact-block a { position: relative; }
.site-footer li a::after,
.footer-bottom a::after,
.contact-block a::after { content: ""; position: absolute; inset: -5px 0; }

/* ==========================================================================
   GESAMTANSICHT DES SAALS — nur mobil
   Randlos über die volle Breite, das Bild behält sein Seitenverhältnis:
   height:auto statt object-fit, damit nichts beschnitten wird. Genau das
   fehlt auf dem Telefon, wo das Hero-Foto auf einen schmalen Ausschnitt
   zusammengeschnitten ist.
   ========================================================================== */
.saal-voll { display: none; }
@media (max-width: 860px) {
  .saal-voll {
    display: block;
    padding: clamp(30px, 7vw, 56px) 0 clamp(24px, 5vw, 40px);
    background: var(--paper);
  }
  .saal-voll img {
    display: block;
    width: 100%;
    height: auto;
  }
  .saal-voll-cap {
    margin: clamp(16px, 3.4vw, 24px) auto 0;
    padding: 0 clamp(20px, 5vw, 32px);
    max-width: 620px;
    text-align: center;
    font-size: .95rem;
    line-height: 1.55;
    color: var(--ink-soft);
  }
  .saal-voll-cap .label {
    display: block;
    margin-bottom: 6px;
  }
  /* Luft zwischen dem Band und der folgenden Überschrift. Nur hier nötig:
     Ohne das Band schließt die Galerie direkt an den Statement-Absatz an und
     braucht oben keinen eigenen Abstand. */
  .saal-voll + #galerie { padding-top: clamp(34px, 7vw, 52px); }
}
/* Stand bisher als padding-top:0 direkt im HTML der Galerie. Dort war es nicht
   überschreibbar — eine Angabe im Element schlägt jede Regel aus der Datei.
   Deshalb hier, damit der Abstand oben je nach Umgebung greifen kann. */
#galerie { padding-top: 0; }

/* ==========================================================================
   ÜBER MICH — Foto neben langem Text
   Der Lebenslauf ist rund doppelt so hoch wie das Porträt (gemessen 1349px
   gegen 967px). Ohne Zutun bleibt neben dem Text eine Leerfläche von 330 bis
   710px stehen. Das Foto wandert deshalb mitlesend mit.
   ========================================================================== */
/* Absatzabstand: Für Fließtext gibt es global keinen — bei drei Absätzen fiel
   das kaum auf, bei acht wird der Lebenslauf ohne Abstand zur Textwand. */
#ueber-mich .contact-grid p + p { margin-top: 15px; }
@media (min-width: 861px) {
  #ueber-mich .contact-grid > :first-child {
    position: sticky;
    /* 72px Kopfzeile + Luft */
    top: 96px;
  }
}
/* Einspaltig ab 860px abwärts wird das 9:16-Porträt bis zu 1407px hoch und
   verdeckt allein schon mehr als einen Bildschirm. Breite begrenzen, das
   Seitenverhältnis bleibt. */
@media (max-width: 860px) {
  #ueber-mich .contact-grid > :first-child { max-width: 420px; }
}

/* ==========================================================================
   FEHLERSEITE (404)
   Eigene Bausteine statt der Kurs-Kacheln: .grid-cta wird unter 560px zur
   klebenden Stapelkarte mit 78svh Höhe — auf einer Fehlerseite drei solche
   Karten wären eine Zumutung. Hier stattdessen ruhige Verweiskarten, die
   sich einfach umbrechen.
   ========================================================================== */
.nf-hint {
  margin-top: 18px;
  font-size: .8rem;
  letter-spacing: .04em;
  color: var(--ink-soft);
}
.nf-hint code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .92em;
  background: var(--paper);
  border: 1px solid var(--line);
  padding: 2px 7px;
  word-break: break-all;
}
.nf-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  gap: 2px;
  background: var(--line-dark);
  border: 1px solid var(--line-dark);
  margin-top: clamp(28px, 4vw, 44px);
}
.nf-card {
  display: flex;
  flex-direction: column;
  padding: clamp(24px, 3vw, 34px);
  background: var(--ivory);
  transition: background .3s var(--ease), color .3s var(--ease);
}
.nf-card h2 {
  font-size: clamp(1.15rem, 2vw, 1.45rem);
  line-height: 1.2;
  margin: 12px 0 10px;
}
.nf-card p {
  font-size: .93rem;
  line-height: 1.6;
  color: var(--ink-soft);
  flex: 1;
}
.nf-card .arr {
  margin-top: 18px;
  font-size: 1.5rem;
  font-weight: 300;
  color: var(--blue);
  transition: transform .3s var(--ease);
}
@media (hover: hover) {
  html:not(.touch-input) .nf-card:hover { background: var(--stage, var(--ink)); }
  /* h2 trägt aus der Grundtypografie eine eigene Farbe (var(--ink)) und erbt
     deshalb nicht vom Elternteil — ohne diese Zeile bleibt die Überschrift
     dunkel auf dunkel und verschwindet beim Überfahren. */
  html:not(.touch-input) .nf-card:hover h2 { color: #fff; }
  html:not(.touch-input) .nf-card:hover .label,
  html:not(.touch-input) .nf-card:hover p { color: rgba(255,255,255,.78); }
  html:not(.touch-input) .nf-card:hover .arr { color: #fff; transform: translateX(6px); }
}
/* Weiterführende Verweise als ruhige Liste unter den Karten */
.nf-more {
  display: flex;
  flex-wrap: wrap;
  gap: 10px clamp(18px, 2.4vw, 30px);
  margin-top: clamp(26px, 3.4vw, 40px);
  padding-top: clamp(20px, 2.6vw, 28px);
  border-top: 1px solid var(--line);
  font-size: .74rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-weight: 600;
}
.nf-more a { position: relative; }
/* Trefferfläche auf 24px bringen, ohne den Zeilenabstand zu verändern */
.nf-more a::after { content: ""; position: absolute; inset: -6px 0; }
.nf-more a:hover { color: var(--blue); }

/* ==========================================================================
   Floating WhatsApp
   ========================================================================== */
.wa-float {
  position: fixed; right: 24px; bottom: 24px; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  background: var(--wa); color: #fff;
  padding: 0; width: 64px; height: 64px;
  border-radius: 50%;
  box-shadow: 0 10px 32px rgba(23, 143, 68, .4);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
  animation: wa-throb 2.4s ease-in-out infinite;
}
.wa-float .txt { display: none; }
.wa-float:hover { transform: translateY(-3px); box-shadow: 0 14px 38px rgba(23,143,68,.5); animation-play-state: paused; }
.wa-float svg { width: 28px; height: 28px; }
/* Doppelter Puls-Ring: zwei versetzte Wellen, deutlich sichtbar */
.wa-float::before,
.wa-float::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 3px solid var(--wa);
  animation: wa-pulse 2.4s ease-out infinite;
  pointer-events: none;
}
.wa-float::after { animation-delay: 1.2s; }
@keyframes wa-pulse {
  0%   { transform: scale(1); opacity: .9; }
  70%, 100% { transform: scale(1.35); opacity: 0; }
}
/* sanftes Atmen des Buttons selbst */
@keyframes wa-throb {
  0%, 100% { scale: 1; }
  50% { scale: 1.05; }
}
@media (prefers-reduced-motion: reduce) {
  .wa-float, .wa-float::before, .wa-float::after { animation: none; }
}

/* ==========================================================================
   Scroll-Reveal
   ========================================================================== */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity .9s var(--ease), transform .9s var(--ease); }
.reveal.visible { opacity: 1; transform: none; }
.reveal-d1 { transition-delay: .1s; } .reveal-d2 { transition-delay: .2s; }
.reveal-d3 { transition-delay: .3s; } .reveal-d4 { transition-delay: .42s; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ==========================================================================
   KURSE — Flip-Grid (Nutzer-Feature), reduziert gestaltet
   ========================================================================== */
.page-hero { padding: 150px 0 40px; }
.page-hero h1 { max-width: 14ch; }
.page-hero .lead { margin-top: 20px; }

.flip-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; background: var(--line-dark); border: 1px solid var(--line-dark); }
.flip-card {
  position: relative;
  /* --flip-h setzt main.js (flipFit) je Raster auf die Höhe, die die
     längste Rückseite braucht — 420px ist nur der Rückfall ohne Skript. */
  perspective: 1400px; min-height: var(--flip-h, 420px); cursor: pointer;
  -webkit-tap-highlight-color: transparent; background: var(--ivory);
  /* JS (flipGrow) setzt beim Umdrehen eine größere min-height, damit die
     Rückseite komplett passt — die Karte wächst statt den Text zu clippen
     und schiebt nachfolgende Grid-Zeilen sichtbar nach unten. */
  transition: min-height .5s var(--ease);
}
/* Verlinkte Karten (z.B. von der Startseite per #id) erhalten beim Laden
   automatisch den Fokus, weil sie tabindex="0" haben — der generische
   3px-Outline-Kasten wirkt dabei roh gegen die Foto-Karte. Weicherer,
   markenkonformer Fokusring statt hartem Rahmen. */
.flip-card:focus-visible {
  /* Transparent statt entfernt: Windows High-Contrast-Modus ersetzt die
     Farbe trotzdem durch die System-Fokusfarbe, Tastatur-Zugänglichkeit
     bleibt also erhalten, ohne dass im Normalfall ein Rahmen zu sehen ist. */
  outline: 3px solid transparent;
  outline-offset: 3px;
  box-shadow: none;
}
.flip-inner {
  /* absolute statt height:100% — eine Prozent-Höhe würde bei einer nur
     über min-height (statt height) gesetzten Kartenhöhe auf "auto"
     zurückfallen (CSS-Spec) und nie mitwachsen, wenn JS die Karte
     beim Umdrehen größer macht. */
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  transition: transform .7s var(--ease);
}
/* html:not(.touch-input): Sobald einmal getippt wurde, setzt main.js diese
   Klasse und die Hover-Regeln fallen weg. Nötig, weil (hover: hover) nicht
   überall zuverlässig ist — meldet ein Browser sie auf einem Telefon, bleibt
   nach dem Antippen sonst ein :hover-Zustand kleben und dreht die Karte
   gegen den Zustand zurück, den das Skript gerade gesetzt hat. */
@media (hover: hover) {
  html:not(.touch-input) .flip-card:hover .flip-inner { transform: rotateY(180deg); }
}
.flip-card.flipped .flip-inner { transform: rotateY(180deg); }
/* Direktlink von der Startseite (JS setzt kurz .flip-slow): das Umdrehen
   läuft spürbar langsamer ab, damit sichtbar wird, welche Karte sich
   öffnet — statt wie beim normalen Klick/Hover sofort umzuschlagen. */
.flip-card.flip-slow { transition-duration: 1.6s; }
.flip-card.flip-slow .flip-inner { transition-duration: 1.6s; }

.flip-face {
  position: absolute; inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  overflow: hidden;
}
/* Manche Browser (v. a. iOS Safari) nehmen eine per backface-visibility
   unsichtbare Fläche trotzdem noch fürs Hit-Testing mit — ein Tap auf die
   sichtbare Rückseite kann so an der unsichtbaren, davor liegenden
   Vorderseite hängen bleiben und den Umdreh-Klick verschlucken. Explizit
   nur die jeweils sichtbare Fläche für Zeigereingaben freigeben. */
.flip-back { pointer-events: none; }
.flip-card.flipped .flip-front { pointer-events: none; }
.flip-card.flipped .flip-back { pointer-events: auto; }
@media (hover: hover) {
  html:not(.touch-input) .flip-card:hover .flip-front { pointer-events: none; }
  html:not(.touch-input) .flip-card:hover .flip-back { pointer-events: auto; }
}
/* Ein <video> liegt auf mobilen Browsern in einer eigenen Compositor-Ebene,
   die das backface-visibility:hidden der umgebenden 3D-Fläche ignoriert:
   Die Rückseite ist längst sichtbar, das Videobild klebt aber noch obenauf.
   Deshalb beim Umdrehen explizit ausblenden statt auf die Rückseiten-
   Kaschierung zu vertrauen. Darunter liegt das Poster als Hintergrund des
   .ph-Containers (per JS gesetzt), sodass an der Stelle nahtlos dasselbe
   Standbild steht und kein Platzhalter aufblitzt. */
.flip-card.flipped .flip-front video { visibility: hidden; }
@media (hover: hover) {
  html:not(.touch-input) .flip-card:hover .flip-front video { visibility: hidden; }
}
.flip-front { display: flex; flex-direction: column; background: var(--ivory); }
.flip-front .thumb { flex: 1; min-height: 0; position: relative; }
.flip-front .caption {
  padding: 16px 18px;
  background: var(--ivory);
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  border-top: 1px solid var(--line-dark);
}
.flip-front .caption h3 { font-size: 1rem; }
.flip-front .age { font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); white-space: nowrap; }
/* Die Plakette trägt Kursname und Alter mit, nicht nur den Hinweis. Grund ist
   der mobile Sticky-Stack: Dort schiebt sich die nächste Karte von unten über
   die aktuelle und deckt die Bildunterschrift zu — oben blieb dann nur
   „Preise ansehen“ stehen, ohne dass erkennbar war, um welchen Kurs es geht. */
.flip-hint {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  max-width: calc(100% - 24px);
  background: rgba(255,255,255,.92); color: var(--ink);
  padding: 9px 12px; border-radius: 2px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  text-align: left;
  opacity: 1;
  transition: opacity .25s ease;
}
.flip-hint .fh-kurs {
  font-weight: 700;
  font-variation-settings: 'wdth' 112;
  font-size: .78rem;
  line-height: 1.15;
  letter-spacing: -.005em;
}
.flip-hint .fh-alter {
  font-size: .64rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.flip-hint .fh-cta {
  display: flex; align-items: center; gap: 6px;
  margin-top: 5px;
  padding-top: 5px;
  border-top: 1px solid var(--line);
  align-self: stretch;
  font-size: .6rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--blue);
}
.flip-hint svg { width: 11px; height: 11px; flex: none; }
/* Manche mobilen Browser rendern die rückseitige Fläche trotz
   backface-visibility:hidden kurz sichtbar — den Hinweis-Button
   deshalb zusätzlich direkt über den Flip-Zustand ausblenden. */
.flip-card.flipped .flip-hint { opacity: 0; }
@media (hover: hover) {
  html:not(.touch-input) .flip-card:hover .flip-hint { opacity: 0; }
}

.flip-back { transform: rotateY(180deg); display: flex; }
.flip-back .bg { position: absolute; inset: 0; }
.flip-back .bg .ph { filter: blur(6px); transform: scale(1.1); }
.flip-back .veil { position: absolute; inset: 0; background: rgba(23, 33, 51, .88); }
.flip-back .content {
  position: relative; z-index: 1;
  display: flex; flex-direction: column;
  padding: 28px 26px;
  color: #fff;
  width: 100%;
}
.flip-back h3 { color: #fff; margin-bottom: 6px; overflow-wrap: break-word; }
.flip-back .age-line { font-size: .7rem; color: rgba(255,255,255,.6); letter-spacing: .18em; text-transform: uppercase; margin-bottom: 16px; }
.flip-back p { font-size: .92rem; line-height: 1.55; color: rgba(255,255,255,.9); flex: 1; }
.flip-back .btn { margin-top: 18px; align-self: flex-start; padding: 13px 20px; font-size: .7rem; }
.price-block { margin-top: 4px; }
.price-row { display: flex; justify-content: space-between; gap: 10px; padding: 5px 0; border-bottom: 1px solid rgba(255,255,255,.15); font-size: .82rem; }
.price-row:last-child { border-bottom: 0; }
.price-row span:first-child { color: rgba(255,255,255,.65); }
.price-row span:last-child { font-weight: 600; color: #fff; }
.price-strike { text-decoration: line-through; opacity: .55; font-weight: 400; margin-right: 6px; }
.price-note { font-size: .74rem; line-height: 1.4; color: rgba(255,255,255,.55); margin-top: 6px; }

/* Positions-Punkte am rechten Rand: nur im mobilen Sticky-Stack (<=560px)
   sinnvoll, wo Karten einzeln nacheinander im Vollbild erscheinen — im
   Grid (Tablet/Desktop) sind ohnehin alle Karten gleichzeitig sichtbar. */
.kurse-dots { display: none; }
@media (max-width: 560px) {
  /* Der Desktop-Wert (150px) reißt auf schmalen Screens ein großes Loch
     zwischen Titel und erster Kurskarte, bevor die klebende Karte sichtbar
     wird — auf dem Handy soll die erste Karte ohne viel Scrollen ins Bild
     kommen. */
  .page-hero { padding: 96px 0 20px; }

  .kurse-dots {
    position: fixed;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 40;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
  }
  .kurse-dots button {
    width: 6px; height: 6px; border-radius: 50%;
    padding: 0; border: 0;
    background: var(--line-dark);
    opacity: .35;
    cursor: pointer;
    transition: opacity .3s ease, transform .3s ease, background-color .3s ease;
  }
  .kurse-dots button:hover { opacity: .7; }
  .kurse-dots button.active { opacity: 1; transform: scale(1.4); background: var(--blue); }
}

/* ==========================================================================
   RAUMVERMIETUNG — Bausteine
   ========================================================================== */
/* Hero-Foto: Im schmalen Mobil-Ausschnitt bleibt von der 16:9-Weitwinkel-
   aufnahme nur gut ein Drittel der Breite übrig. Zentriert zeigt der
   Ausschnitt fast nur leeres Parkett — am rechten Bildrand steht dagegen
   die Spiegelwand, die dem Ausschnitt Tiefe gibt und den Saal als Raum
   erkennbar macht. */
@media (max-width: 640px) {
  .miete-hero-photo { object-position: right center; }
}
.specs-strip {
  display: flex; flex-wrap: wrap;
  gap: clamp(28px, 5vw, 72px);
  padding: clamp(28px, 4vw, 44px) 0;
  border-top: 1px solid var(--line-dark);
  border-bottom: 1px solid var(--line-dark);
}
.specs-strip .num { font-size: clamp(1.6rem, 3vw, 2.6rem); font-weight: 700; font-variation-settings: 'wdth' 118; line-height: 1; }
.specs-strip .lbl { font-size: .72rem; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft); margin-top: 6px; }

/* Rundgang statt Raster: große Einzelbilder mit Bildunterschriften,
   abwechselnd versetzt. Parallax-Tiefe im Rahmen (JS setzt --ply). */
.tour { display: grid; gap: clamp(52px, 8vw, 110px); }
.tour-item { display: grid; gap: clamp(20px, 3vw, 48px); align-items: end; }
.tour-item--left { grid-template-columns: 1.35fr .65fr; }
.tour-item--right { grid-template-columns: .65fr 1.35fr; }
.tour-item--right .tour-cap { order: -1; }
.tour-item--wide .tour-cap { padding-top: 18px; border-top: 1px solid var(--line-dark); max-width: 520px; }

.frame { position: relative; overflow: hidden; background: var(--line); }
.frame--wide { aspect-ratio: 21 / 9; }
.frame--std { aspect-ratio: 4 / 3; }
.frame--portrait { aspect-ratio: 9 / 16; }
.frame .ph {
  position: absolute;
  inset: -12% 0;
  min-height: 0;
  transform: translateY(var(--ply, 0));
  will-change: transform;
}

/* Video-Reel: vertikale Videos im eigenen Format zeigen statt in ein
   Breitbild-Frame zu zwängen — Bildunterschrift liegt als Scrim auf dem
   Video, wie im Hero. */
.tour-reel { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(10px, 2vw, 20px); }
.reel-item { position: relative; }
.reel-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(15,16,20,.88) 0%, rgba(15,16,20,.32) 42%, rgba(15,16,20,0) 66%);
  pointer-events: none;
}
.reel-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: clamp(16px, 2.4vw, 28px); }
.reel-cap .label { color: rgba(255,255,255,.72); }
.reel-cap h3 { color: #fff; font-size: clamp(1rem, 1.6vw, 1.25rem); margin-bottom: 4px; }
.reel-cap p { color: rgba(255,255,255,.82); font-size: .86rem; max-width: 26ch; }

.tour-cap { padding-bottom: 6px; }
.tour-cap h3 { margin-bottom: 8px; }
.tour-cap p { color: var(--ink-soft); font-size: .98rem; max-width: 36ch; }

/* Video-Duo: 3-Spalten-Grid – Video / Text (frei, ohne Rahmen) / Video */
.frame-duo {
  aspect-ratio: 21 / 9;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  align-items: center;
}
.frame-duo video {
  width: 100%; height: 100%;
  object-fit: cover;
  background: var(--ink, #14151a);
}
.frame-duo .tour-cap {
  padding: 0 clamp(12px, 2vw, 28px);
  text-align: center;
}
@media (max-width: 640px) {
  .frame-duo { aspect-ratio: auto; grid-template-columns: 1fr; }
  .frame-duo video { aspect-ratio: 4 / 5; }
  .frame-duo .tour-cap { padding: 20px 12px; }
}

/* Foto-Bänder: gleiche Parallax-Tiefe */
.photo-band .media {
  inset: -12% 0;
  transform: translateY(var(--ply, 0));
  will-change: transform;
}

.usage-list { border-top: 1px solid var(--line-dark); }
.usage {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 18px;
  align-items: baseline;
  padding: 22px 8px;
  border-bottom: 1px solid var(--line-dark);
}
.usage h3 { font-size: 1.05rem; }
.usage p { color: var(--ink-soft); font-size: .95rem; }

.steps-inline { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; border: 1px solid var(--line-dark); background: var(--line-dark); }
.step { background: var(--ivory); padding: clamp(26px, 3vw, 40px); }
.step h3 { margin-bottom: 10px; }
.step p { color: var(--ink-soft); font-size: .95rem; }

.note-plain {
  border-left: 3px solid var(--blue);
  padding: 6px 0 6px 22px;
  font-size: .95rem;
  color: var(--ink-soft);
  max-width: 70ch;
}
.note-plain strong { color: var(--ink); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1024px) {
  .flip-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .usage { grid-template-columns: 1fr; gap: 6px; }
}

@media (max-width: 860px) {
  .stage-grid { grid-template-columns: 1fr; }
  .stage-grid .sticky { position: static; }
  .r2-grid { grid-template-columns: 1fr; }
  .contact-grid { grid-template-columns: 1fr; }
  .steps-inline { grid-template-columns: 1fr; }
  .tour-item--left, .tour-item--right { grid-template-columns: 1fr; }
  .tour-item--right .tour-cap { order: 0; }
  .frame--wide { aspect-ratio: 16 / 10; }
  .tour-reel { grid-template-columns: 1fr; gap: 16px; }
  .specs-strip { gap: 24px; }

}

/* Kopfzeile: Das horizontale Menü braucht mit fünf Punkten, dem CTA-Button
   und dem ausgeschriebenen Schulnamen rund 1130px. Darunter quetscht es den
   Markennamen zusammen — deshalb schaltet die Navigation (und nur sie,
   nicht das übrige Layout) schon hier auf das Burger-Panel um. */
@media (max-width: 1239px) {
  .main-nav {
    /* WICHTIG: nicht über bottom:0 aufspannen. backdrop-filter auf
       .site-header (Zustände .scrolled und body.nav-open) macht die
       Kopfzeile laut Filter-Effects-Spec zum Containing Block für
       fixed-Nachfahren — top:0;bottom:0 würde das Panel dann auf die
       72px hohe Kopfzeile zusammenfalten; die Links liefen ohne
       Hintergrund über die Seite („transparentes Menü"). Mit expliziter
       Höhe rendert das Panel in beiden Fällen identisch, weil die
       Kopfzeile selbst fix und volle Breite an der Viewport-Oberkante
       sitzt. */
    position: fixed; top: 0; right: 0; left: auto;
    height: 100vh;
    height: 100dvh;
    width: min(64vw, 360px);
    flex-direction: column; justify-content: center;
    gap: 30px;
    /* Direkt auf dem Panel selbst (nicht nur auf ::before) — deckend,
       egal ob die Pseudo-Ebene aus irgendeinem Grund nicht greift. */
    background: var(--ivory);
    transform: translateX(100%);
    transition: transform .35s var(--ease);
    z-index: 9000;
    isolation: isolate;
  }
  /* Eigene Ebene fürs Panel: deckendes Ivory garantiert unabhängig von
     etwaigen Stapelkontext-Eigenheiten, egal was auf der Seite dahinter
     liegt oder gerade animiert. */
  .main-nav::before {
    content: "";
    position: absolute; inset: 0;
    background: var(--ivory);
    box-shadow: -12px 0 40px rgba(0,0,0,.18);
    z-index: 1;
  }
  .main-nav.open { transform: none; }
  .main-nav a {
    position: relative; z-index: 2;
    font-size: 1.05rem; color: var(--ink) !important;
  }
  /* Untermenü im Panel: eingerückte Liste, per Pfeil aufklappbar */
  /* Das Panel legt seinen deckenden Hintergrund über ::before (z-index 1).
     Links heben sich per z-index:2 darüber — Pfeil-Button und Wrapper
     brauchen dasselbe, sonst fängt die Hintergrundebene die Taps ab und
     das Untermenü lässt sich mobil gar nicht öffnen. */
  .nav-item, .nav-sub-toggle { position: relative; z-index: 2; }
  .nav-item { flex-wrap: wrap; justify-content: center; width: 100%; }
  .nav-sub {
    display: none;
    width: 100%;
    margin-top: 14px;
    padding-left: 14px;
    border-left: 1px solid var(--line);
    text-align: left;
  }
  .nav-has-sub.open .nav-sub { display: grid; gap: 14px; }
  .main-nav .nav-sub a { font-size: .92rem; }
  .nav-sub .sub-note { display: block; margin-top: 2px; font-size: .72rem; color: var(--ink-soft); text-transform: none; letter-spacing: .04em; }
  .nav-sub-toggle { padding: 6px 8px; }
  .nav-arrow { width: 14px; height: 14px; }

  .main-nav a.btn { color: #fff !important; }
  .nav-toggle { display: block; }
  /* Über dem transparenten Foto-Header ist das X sonst weiß auf dem
     hellen Menü-Panel kaum sichtbar — bei offenem Menü immer dunkel. */
  .header-on-photo .site-header:not(.scrolled) .nav-toggle.open span { background: var(--ink); }
  /* Derselbe Fall für den Pfeil-Button: er steckt im hellen Panel, nicht
     mehr auf dem Foto — die weiße Kopfzeilen-Farbe macht ihn dort
     unsichtbar. Im Panel deshalb immer die dunkle Textfarbe. */
  .header-on-photo .site-header:not(.scrolled) .nav-sub-toggle,
  .nav-sub-toggle { color: var(--ink); }
}

@media (max-width: 560px) {
  .flip-grid { grid-template-columns: 1fr; gap: 0; background: none; border: 0; }
  /* Karten bleiben beim Scrollen an Ort und Stelle stehen (sticky) —
     die jeweils nächste Karte fährt von unten darüber und deckt die
     vorige komplett zu, statt dass alles gemeinsam weiterscrollt. */
  .flip-card {
    position: sticky;
    top: 72px;
    min-height: 78svh;
    box-shadow: 0 -22px 44px rgba(22,24,29,.35);
  }
  .flip-card.reveal { transform: translateY(70px); }
  .flip-card.reveal.visible { transform: none; }
  /* Eine festgepinnte Sticky-Karte bewegt sich beim Scrollen nicht mehr —
     Rückseiten-Inhalt, der höher ist als der Bereich unter der Kopfzeile,
     wäre sonst nie erreichbar. Überlänge scrollt im Inhalt selbst
     (JS deckelt die Kartenhöhe passend auf Viewport − Kopfzeile). */
  .flip-back .content { overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .footer-grid { grid-template-columns: 1fr; gap: 32px; }

  /* Schwimmender WhatsApp-Button: auf schmalen Screens etwas kompakter,
     damit er weniger Tap-Ziele darunter verdeckt (z.B. Flip-Karten). */
  .wa-float { right: 16px; bottom: 16px; width: 56px; height: 56px; }
  .wa-float svg { width: 24px; height: 24px; }
}
/* ==========================================================================
   KINDERGEBURTSTAG — 3D-Optionskarten
   Zwei Angebotsvarianten stehen in einer gemeinsamen Perspektive und
   richten sich beim Hereinscrollen aus der Neigung auf. Auf Zeigergeräten
   kippen sie zusätzlich leicht zum Cursor. Bewusst OHNE <video> im
   3D-Kontext: Videoebenen ignorieren auf Mobilbrowsern die 3D-Sortierung
   (siehe .flip-front video weiter oben).
   ========================================================================== */
.geb-stage { perspective: 1500px; perspective-origin: 50% 30%; }
.geb-options {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(18px, 2.4vw, 32px);
  transform-style: preserve-3d;
}
.geb-card {
  position: relative;
  display: flex;
  flex-direction: column;
  /* Rasterzellen haben min-width: auto und schrumpfen daher nie unter ihren
     Mindestinhalt. Zusammen mit dem langen Kompositum in der Überschrift
     (siehe unten) ergab das eine harte Untergrenze von 337px — auf 320er
     und 360er Displays stand die Karte über ihrem Raster hinaus. */
  min-width: 0;
  padding: clamp(28px, 3.4vw, 48px);
  background: var(--ivory);
  border: 1px solid var(--line);
  transform-style: preserve-3d;
  /* Ausgangslage: nach hinten geneigt, als läge die Karte noch flach */
  transform: rotateX(16deg) translateZ(-70px);
  opacity: 0;
  transition:
    transform 1s var(--ease),
    opacity .8s var(--ease),
    box-shadow .45s var(--ease),
    border-color .45s var(--ease);
  will-change: transform;
}
.geb-card.in { transform: none; opacity: 1; }
.geb-card.in:nth-child(2) { transition-delay: .14s; }
.geb-card:hover { border-color: var(--blue); box-shadow: 0 26px 60px rgba(37, 27, 44, .18); }
/* Tiefenstaffelung: Die Überschrift steht am weitesten vorne und macht den
   räumlichen Effekt sichtbar, Text und Liste liegen gestaffelt dahinter. */
/* „Geburtstagsraum" allein ist 279px breit und damit auf einem 320er
   Display nicht unterzubringen. hyphens trennt es an der richtigen Stelle,
   overflow-wrap fängt Wörter ab, für die kein Trennmuster greift. Bewusst
   nur hier statt global — eine breite Regel hatte schon einmal Überschriften
   mitten im Wort umbrechen lassen, wo genug Platz war. */
.geb-card h3 {
  transform: translateZ(46px);
  font-size: clamp(1.35rem, 2.1vw, 1.85rem);
  margin-bottom: 10px;
  hyphens: auto;
  overflow-wrap: break-word;
}
.geb-card p { transform: translateZ(22px); color: var(--ink-soft); font-size: .98rem; line-height: 1.7; }
.geb-card .geb-list { transform: translateZ(18px); margin-top: 16px; display: grid; gap: 8px; }
.geb-card .geb-list li {
  list-style: none;
  position: relative;
  padding-left: 22px;
  font-size: .92rem;
  color: var(--ink-soft);
}
.geb-card .geb-list li::before {
  content: "";
  position: absolute; left: 0; top: .45em;
  width: 9px; height: 9px;
  border: 1.5px solid var(--blue);
  border-radius: 50%;
}
.geb-card .btn { transform: translateZ(34px); margin-top: clamp(22px, 2.6vw, 32px); align-self: flex-start; }

@media (max-width: 860px) {
  .geb-options { grid-template-columns: 1fr; }
  /* Flacher Einflug: Auf kleinen Screens wirkt eine starke Neigung
     schnell wie ein Darstellungsfehler statt wie Absicht. */
  .geb-card { transform: rotateX(9deg) translateZ(-40px); }
}
@media (prefers-reduced-motion: reduce) {
  .geb-card { transform: none; opacity: 1; transition: none; }
  .geb-card h3, .geb-card p, .geb-card .geb-list, .geb-card .btn { transform: none; }
}

/* ==========================================================================
   QUERVERWEIS-KACHEL im Kartenraster
   Füllt den sonst verwaisten Restplatz (Kinderseite 5 Kurse, Erwachsenen-
   seite 4 Kurse — ohne Füller bliebe ein 3+2- bzw. 3+1-Rest) und dient
   zugleich der internen Verlinkung zwischen den Kursseiten.
   Bewusst keine Flip-Karte: Es gibt keine Rückseite zum Umdrehen.
   ========================================================================== */
.grid-cta {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 420px;
  padding: clamp(26px, 3vw, 40px);
  background: var(--stage, var(--ink));
  color: #fff;
  overflow: hidden;
  transition: background .35s var(--ease);
}
.grid-cta:hover { background: var(--blue); }
/* Zwei Querverweis-Kacheln direkt hintereinander (Erwachsenenseite) würden
   als eine einzige dunkle Fläche gelesen — die zweite bekommt deshalb den
   violetten Zweitklang der Palette. */
.grid-cta + .grid-cta { background: var(--lilac, var(--ink)); }
.grid-cta + .grid-cta:hover { background: var(--blue); }
.grid-cta .label { color: rgba(255,255,255,.6); }
.grid-cta h3 { color: #fff; margin: 10px 0 8px; }
.grid-cta p { color: rgba(255,255,255,.82); font-size: .95rem; line-height: 1.6; }
.grid-cta .arr {
  margin-top: clamp(18px, 2.4vw, 28px);
  font-size: 1.6rem;
  line-height: 1;
  transition: transform .35s var(--ease);
}
.grid-cta:hover .arr { transform: translateX(8px); }
@media (max-width: 560px) {
  /* Mobil sind die Kurskarten kein Raster, sondern ein Sticky-Stapel:
     Jede Karte bleibt stehen, die nächste schiebt sich darüber. Die
     Kachel muss dieselben Sticky-Werte bekommen, sonst scrollt sie als
     einziges Element normal durch und die Abfolge bricht am Ende ab. */
  .grid-cta {
    position: sticky;
    top: 72px;
    min-height: 78svh;
    /* Der weiche Schatten der Flip-Karten trennt nur gegen helle Fotos.
       Schiebt sich eine dunkle Kachel über eine andere dunkle, ist er
       unsichtbar und beide verschmelzen — eine helle Haarlinie an der
       Oberkante markiert die Grenze unabhängig vom Untergrund. */
    box-shadow: 0 -22px 44px rgba(22,24,29,.45), 0 -1px 0 rgba(255,255,255,.32);
  }
}
