html {
    scroll-behavior: smooth;
}


/* =========================================================
   Schriftdateien

   Selbst gehostet, nicht von Google geladen. Das ist keine Kosmetik: ein
   <link> auf fonts.googleapis.com meldet Google die IP-Adresse jedes
   Besuchers, noch bevor irgendetwas zu sehen ist. Genau das war beim
   Kaufvideo der Grund fuer die ganze Klick-zum-Laden-Bauart – solange die
   Schriften von Google kamen, war die Muehe an einer Stelle umsonst.

   Anton und JetBrains Mono stehen unter der SIL Open Font License; das
   Selbsthosten ist dort ausdruecklich erlaubt.

   Nur die Teilmengen latin und latin-ext. Kyrillisch, Griechisch und
   Vietnamesisch braucht diese Website nicht, und dank unicode-range holt der
   Browser latin-ext nur, wenn auf der Seite wirklich ein Zeichen daraus
   vorkommt. Ein deutscher Besucher laedt damit rund 50 KB.

   font-display: swap – bis die Datei da ist, steht der Text in der
   Systemschrift. Sichtbarer Text schlaegt den richtigen Schnitt.

   JetBrains Mono ist EINE variable Datei fuer alle Schnitte, deshalb
   font-weight: 100 800 statt zweier Dateien fuer 400 und 700.
   ========================================================= */

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

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

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

@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 100 800;
    font-display: swap;
    src: url("assets/fonts/jetbrains-mono-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* =========================================================
   Sewer-Tech Academy – gemeinsames Stylesheet
   Wird von allen Seiten eingebunden: <link rel="stylesheet" href="sta.css">
   Aufbau:
     1. Tokens & Basis
     2. Navigation & Mobilmenü
     3. Hero (Start- und Unterseiten)
     4. Buttons
     5. Sektions-Bausteine (Titel, Eyebrow, Reveal)
     6. Info-Karten (Startseite)
     7. Slider & Testimonials
     8. Partner-Logos
     9. FAQ-Akkordeon
    10. Unterseiten-Komponenten
    11. Formularfelder
    12. Footer
    13. Landingpage /fuer-betriebe
    14. Media Queries
   ========================================================= */

/* ---------- Farben ----------

   Es gibt zwei Fassungen: dunkel und hell. Dunkel ist die Voreinstellung und
   steht hier im :root-Block – wer nichts umschaltet, bekommt sie. Hell steht
   weiter unten unter :root[data-thema="hell"] und überschreibt nur die Werte,
   sonst nichts.

   Deshalb steht ab hier im ganzen Stylesheet keine feste Farbe mehr, die sich
   zwischen den Fassungen unterscheiden müsste. Wer eine neue Regel schreibt,
   nimmt ein Token von hier – sonst ist sie in einer der beiden Fassungen
   falsch, und zwar in der, die man gerade nicht offen hat.

   Ausgenommen sind drei Stellen, die in BEIDEN Fassungen dunkel bleiben und
   deshalb ihre festen Farben behalten dürfen: die Fußzeile, der Hintergrund
   des Videos im Kauf-Popup und die Abdunklung hinter Menü und Popup. Warum,
   steht jeweils dort. */
:root {
    --bg-dark: #131313;
    --bg-card: #1c1c1c;
    --bg-input: #101010;
    --text-light: #f4f4f9;
    --text-muted: #abb8c3;
    --primary-blue: #51a4de;
    --primary-hover: #3d8ec4;
    --accent-bright: #6ce5e8;
    --nav-muted: rgb(179, 177, 177);
    --border-color: rgba(255, 255, 255, 0.1);

    /* Flächen unterhalb der Grundfarbe */
    --bg-deep: #0a0a0a;                /* Navileiste beim Scrollen, Mobilmenü */
    --bg-deep-glas: rgba(10, 10, 10, 0.95);
    --bg-band: #0d0d0d;                /* dunkles Band: Slider, Stimmen, band-dark */
    --bg-footer: #070707;              /* bleibt in beiden Fassungen dunkel */
    --bg-kachel: #1a1a1a;              /* Grundton der Infokarten */

    /* Infokarten: Rahmen und der Schleier über dem Bild */
    --rand-kachel: #383838;
    --rand-kachel-innen: #222222;
    --kachel-verlauf: linear-gradient(180deg, rgba(19, 19, 19, 0.72) 0%, rgba(19, 19, 19, 0.96) 100%);
    --kachel-verlauf-hover: linear-gradient(180deg, rgba(19, 19, 19, 0.52) 0%, rgba(19, 19, 19, 0.88) 100%);

    /* Navileiste, solange nicht gescrollt wurde: ein Schleier über dem Bild */
    --nav-schleier: linear-gradient(180deg, rgba(0, 0, 0, 0.8) 0%, transparent 100%);

    /* Trichterseiten: dort läuft kein Video, sondern eine ruhige Fläche mit
       einem Schimmer in Markenblau von oben. Warum kein Video, steht unten
       im Block "Trichterseiten". */
    --trichter-flaeche:
        radial-gradient(ellipse 75% 55% at 50% 0%, rgba(81, 164, 222, 0.13), transparent 70%),
        var(--bg-dark);

    /* Milchglas (Slider-Pfeile) */
    --glas-bg: rgba(15, 15, 15, 0.55);
    --glas-rand: rgba(255, 255, 255, 0.14);

    /* Feine Linien, Tönungen, zurückgenommene Schrift */
    --linie-zart: rgba(255, 255, 255, 0.05);
    --flaeche-zart: rgba(255, 255, 255, 0.02);
    --flaeche-aktiv: rgba(255, 255, 255, 0.1);
    --punkt-inaktiv: rgba(255, 255, 255, 0.4);
    --text-zart: rgba(255, 255, 255, 0.3);
    --rand-hell: rgba(255, 255, 255, 0.3);
    --rand-mittel: rgba(255, 255, 255, 0.2);
    --erfolg-bg: rgba(108, 229, 232, 0.08);
    --knopf-zu-bg: rgba(20, 20, 20, 0.75);

    /* Schatten. Auf Dunkel dürfen sie kräftig sein – auf Hell nicht, dort
       wirkt derselbe Wert wie ein Fleck. Deshalb sind es ganze Werte und
       nicht nur Farben. */
    --schatten-kachel: 0 8px 20px rgba(0, 0, 0, 0.4);
    --schatten-karte: 0 10px 25px rgba(0, 0, 0, 0.5);
    --schatten-karte-stark: 0 10px 25px rgba(0, 0, 0, 0.6);
    --schatten-glas: 0 6px 20px rgba(0, 0, 0, 0.45);
    --schatten-popup: 0 20px 60px rgba(0, 0, 0, 0.6);
    --schatten-hoch: 0 10px 30px rgba(0, 0, 0, 0.5);
    --glut-blau: 0 4px 15px rgba(81, 164, 222, 0.4);
    --glut-blau-stark: 0 6px 20px rgba(81, 164, 222, 0.6);
    --glut-blau-zart: 0 4px 15px rgba(81, 164, 222, 0.35);

    /* Grundfarbe für zurückgenommene Schrift und feine Linien in der
       Fußzeile. Als drei Zahlen, damit die Durchsichtigkeit an der
       Verwendungsstelle bleibt: rgba(var(--text-basis), 0.45). */
    --text-basis: 255, 255, 255;

    /* ---------- Hero ----------
       Es gibt zwei Filme derselben Kreuzung: bei Nacht und bei Tag. Welcher
       läuft, entscheidet sta.js über data-hell an der <source>; wie er wirkt,
       diese drei Tokens.

       Nachts wird kräftig abgedunkelt, damit die weiße Schrift steht. Der
       Schleier ist dabei durchsichtig – die Abdunklung reicht.
       Am Tag ist es umgekehrt: das Bild bleibt, wie es ist, und ein heller
       Schleier trägt die dunkle Schrift. */
    --hero-video-filter: brightness(35%);
    --hero-schleier: transparent;
    --hero-schatten: 0, 0, 0;
    --hero-schatten-deckung: 0.8;
    --brand-glow-schatten: 0 0 10px rgba(81, 164, 222, 0.6);

    /* Der Zweitknopf im Hero ("Was dich erwartet"). Er steht auf dem Film und
       nicht auf einer Fläche der Seite – deshalb ein eigenes Token und nicht
       --text-light: über einer Nachtaufnahme ist er weiß, über einer
       Tagaufnahme schwarz. --knopf-zweit-text ist die Gegenfarbe fürs
       Überfahren, wenn die Fläche gefüllt wird. */
    --knopf-zweit: white;
    --knopf-zweit-text: #131313;

    /* ---------- Schrift-CI (siehe Schrift-CI.txt) ----------
       Schriften werden AUSSCHLIESSLICH hier festgelegt. Weiter unten im
       Stylesheet steht kein einziger Schriftname mehr – immer nur eines
       der Tokens von hier.
       Eine Schrift wechseln heisst: genau eine Zeile hier ändern.

       Laut CI sind ausschliesslich diese vier Familien erlaubt:
         ANTON              ein Schnitt         Überschriften | Hervorhebungen
         TALL               ein Schnitt         Überschriften | Hervorhebungen
         Canva Sans         Regular|Semi|Bold   Fliesstexte
         Gentlemens Script  ein Schnitt         Sublines | Hervorhebungen

       Eingebunden ist bis auf Weiteres nur ANTON (Google Fonts, frei
       lizenziert). Für Canva Sans und Gentlemens Script fehlen die
       lizenzierten Webfont-Dateien – Canva Sans ist ausserhalb von Canva
       gar nicht kommerziell nutzbar, Gentlemens Script braucht eine
       gekaufte Weblizenz. Solange greift der Systemschrift-Fallback.
       TALL trägt derzeit keine Rolle, weil Anton alle Überschriften macht.

       Nachrüsten, sobald die Dateien vom Marketing da sind:
         1. woff2 nach assets/fonts/ legen
         2. @font-face-Regel oben im Block "Schriftdateien" ergänzen
         3. den Namen im passenden Token unten voranstellen
       Sonst nichts ändern – der Rest der Datei zieht automatisch nach. */
    --font-heading: 'Anton', Impact, 'Arial Narrow', sans-serif;
    --font-body: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; /* TODO: Canva Sans */
    --font-accent: var(--font-body); /* TODO: Gentlemens Script */

    /* JetBrains Mono nur für Preise*/
    --font-mono: 'JetBrains Mono', ui-monospace, Consolas, monospace;
}

/* =========================================================
   Helle Fassung

   Eingeschaltet über <html data-thema="hell">. Gesetzt wird das an zwei
   Stellen: von einem kurzen Skript im <head> jeder Seite, damit beim Laden
   nichts aufblitzt, und danach vom Umschalter in sta.js.

   Absichtlich NICHT an prefers-color-scheme gekoppelt: Voreinstellung ist
   immer dunkel, hell bekommt nur, wer es selbst gewählt hat.

   Das Markenblau wird hier dunkler. #51a4de steht auf Weiß bei einem
   Kontrast von 2,3:1 – als Fließtext oder Link nicht lesbar und unter der
   Grenze der Barrierefreiheit. #1f77b8 ist dieselbe Farbe, nur tiefer, und
   kommt auf 4,7:1. Auf Dunkel bleibt es beim hellen Blau.
   ========================================================= */
:root[data-thema="hell"] {
    --bg-dark: #f2f4f7;
    --bg-card: #ffffff;
    /* Nicht reinweiß: Eingabefelder stehen meist in weißen Karten, und ein
       weißes Feld in einer weißen Karte sieht man erst beim Hineinklicken. */
    --bg-input: #f7f8fa;
    --text-light: #14181d;
    --text-muted: #55606b;
    /* Das Markenblau bleibt in beiden Fassungen dasselbe – so entschieden.
       Auf Weiß kommt #51a4de auf einen Kontrast von 2,3:1. Für Flächen und
       Ränder ist das in Ordnung, als Fließtext oder Link ist es grenzwertig.
       Falls das später stören sollte: eine dunklere Fassung nur für Schrift
       wäre ein zweites Token, nicht dieses hier. */
    --primary-blue: #1a9dd9;
    --primary-hover: #0d568a;
    /* Das Türkis dagegen bleibt abgedunkelt: #6ce5e8 ist auf Weiß nicht
       blass, sondern praktisch unsichtbar. Es kommt nur an zwei Stellen vor
       (Erfolgsmeldung, Preisakzent) und ist nicht die Hauptfarbe. */
    --accent-bright: #6ce5e8;
    --nav-muted: #3f4750;
    --border-color: rgba(20, 30, 45, 0.14);

    --bg-deep: #ffffff;
    --bg-deep-glas: rgba(255, 255, 255, 0.95);
    --bg-band: #e7eaef;
    --bg-footer: #ffffff;
    --bg-kachel: #ffffff;

    /* Das Tagvideo ist hell genug – es wird nicht aufgehellt, sondern nur
       leicht beruhigt. Für die Schrift sorgt der Schleier darüber: eine
       Mittagsaufnahme einer Stadt ist ein unruhiger Untergrund, und ohne ihn
       säße die Überschrift mal auf Himmel, mal auf Hochhaus.
       0.42 ist der Wert, bei dem die Aufnahme noch zu erkennen ist und die
       Schrift trotzdem trägt. */
    --hero-video-filter: saturate(0.9) contrast(0.95);

    /* Der Schleier ist kein gleichmäßiges Milchglas, sondern in der Mitte am
       dichtesten. Genau dort steht die Schrift, und genau dort ist die
       Aufnahme am unruhigsten – Hochhäuser, Schilder, Autobahnkreuz.

       Oben und unten bleibt er dünn: dort liegen ohnehin schon zwei eigene
       Verläufe darüber (der Schleier der Navileiste und das Ausblenden in die
       Seitenfarbe), und die Aufnahme darf da noch Aufnahme sein. */
    --hero-schleier: linear-gradient(180deg,
            rgba(255, 255, 255, 0.24) 0%,
            rgba(255, 255, 255, 0.66) 14%,
            rgba(255, 255, 255, 0.66) 86%,
            rgba(255, 255, 255, 0.24) 100%);

    /* Der Schatten ist auch hier schwarz, nur viel leiser: 0.2 statt 0.8.

       Weiß war der Fehler von vorhin – ein weißer Schatten auf hellem Grund
       ist kein Schatten, sondern ein Schmierer neben jedem Buchstaben.
       Schwarz mit 20 % legt die Schrift auf die Fläche, ohne dass man den
       Schatten als solchen bemerkt. Den Kontrast trägt weiterhin der
       Schleier. */
    --hero-schatten: 0, 0, 0;
    --hero-schatten-deckung: 0.0;

    /* Kein Glow in der hellen Fassung – weder der Schein um die Wortmarke
       noch der blaue Schimmer unter den Knöpfen. Ein Leuchten setzt einen
       dunklen Grund voraus, auf dem es leuchten kann; auf Hell wird daraus
       ein unscharfer Rand. */
    --brand-glow-schatten: none;
    --glut-blau: none;
    --glut-blau-stark: none;
    --glut-blau-zart: none;

    /* Schwarz statt Weiß: der Zweitknopf steht auf der Tagaufnahme. */
    --knopf-zweit: #14181d;
    --knopf-zweit-text: #ffffff;

    /* Weiß auf Dunkel, Dunkelblau auf Hell. Steht als drei Zahlen da, damit
       die Durchsichtigkeit an der Verwendungsstelle bleiben kann:
       rgba(var(--text-basis), 0.45). So bleiben die fein abgestuften Werte
       in der Fußzeile erhalten, ohne dass es für jeden davon ein eigenes
       Token braucht. */
    --text-basis: 20, 30, 45;

    --rand-kachel: #d7dce3;
    --rand-kachel-innen: #eef1f5;
    /* Die Infokacheln sind hier nicht anders eingestellt, sondern anders
       gebaut: oben Foto, unten Fläche, dazwischen ein kurzer Übergang.
       Warum, steht unten bei ".info-card in der hellen Fassung". */

    --kachel-verlauf: linear-gradient(180deg,
            rgba(255, 255, 255, 0) 0%,
            rgba(255, 255, 255, 0) 30%,
            rgba(255, 255, 255, 0.97) 51%,
            rgba(255, 255, 255, 1) 100%);
    --kachel-verlauf-hover: linear-gradient(180deg,
            rgba(255, 255, 255, 0) 0%,
            rgba(255, 255, 255, 0) 30%,
            rgba(255, 255, 255, 0.97) 51%,
            rgba(255, 255, 255, 1) 100%);

    --nav-schleier: linear-gradient(180deg, rgba(242, 244, 247, 0.92) 0%, transparent 100%);

    /* Am Tag bleibt die nackte Fläche. Der blaue Schimmer gehört zur selben
       Familie wie --glut-blau, und die ist hier durchgehend abgeschaltet:
       auf Hell wird aus einem Leuchten ein Schleier. */
    --trichter-flaeche: var(--bg-dark);

    --glas-bg: rgba(255, 255, 255, 0.7);
    --glas-rand: rgba(20, 30, 45, 0.14);

    --linie-zart: rgba(20, 30, 45, 0.09);
    --flaeche-zart: rgba(20, 30, 45, 0.035);
    --flaeche-aktiv: rgba(20, 30, 45, 0.09);
    --punkt-inaktiv: rgba(20, 30, 45, 0.3);
    --text-zart: rgba(20, 30, 45, 0.45);
    --rand-hell: rgba(20, 30, 45, 0.3);
    --rand-mittel: rgba(20, 30, 45, 0.2);
    --erfolg-bg: rgba(14, 127, 136, 0.1);
    --knopf-zu-bg: rgba(255, 255, 255, 0.85);

    /* Deutlich zurückgenommen: ein Schatten mit 50 % Schwarz, der auf Dunkel
       kaum auffällt, sieht auf Hell aus wie ein Dreckfleck. */
    --schatten-kachel: 0 8px 20px rgba(23, 35, 54, 0.12);
    --schatten-karte: 0 10px 25px rgba(23, 35, 54, 0.13);
    --schatten-karte-stark: 0 10px 25px rgba(23, 35, 54, 0.18);
    --schatten-glas: 0 6px 20px rgba(23, 35, 54, 0.14);
    --schatten-popup: 0 24px 60px rgba(23, 35, 54, 0.25);
    --schatten-hoch: 0 10px 30px rgba(23, 35, 54, 0.16);
}

/* Die Navileiste braucht in der hellen Fassung keine eigene Regel.

   Sie liegt bis zum ersten Scrollen als Schleier über dem Hero – in beiden
   Fassungen, nur eben in der jeweiligen Farbe (--nav-schleier). Das geht
   erst, seit der Hero am Tag hell ist: über einem dunklen Video wäre die
   dunkle Schrift der hellen Fassung nicht zu lesen gewesen. Jetzt passt es,
   weil beides zusammen umschaltet.

   Auf Impressum, Datenschutz und AGB gibt es keinen Hero. Dort liegt der
   Schleier über der normalen Seitenfläche und hat fast dieselbe Farbe –
   man sieht ihn schlicht nicht, und das ist richtig so. */

/* ---------- Das Wortmarken-Logo ----------

   assets/Kragen_logo_white.png ist die weiße Fassung, assets/Sewer_Tech_Academy_logo.png
   die dunkle – dasselbe Logo, beide Dateien liegen längst da.

   Getauscht wird über ein Hintergrundbild und nicht über einen Filter. Zwei
   Gründe:

   1. Ein Filter rechnet an der Marke herum. Bei einer einfarbig weißen Datei
      geht das noch, bei der richtigen farbigen Fassung nicht mehr.
   2. Ein Hintergrundbild in einer Regel, die gerade nicht gilt, wird auch
      nicht geladen. In der dunklen Fassung kostet die helle Datei damit
      keinen einzigen Byte – anders als ein zweites <img> im Markup, das der
      Browser auch dann holt, wenn es auf display:none steht.

   Und weil CSS vor dem ersten Bild geladen ist, steht die richtige Fassung
   von Anfang an da. Nichts blitzt auf, nichts springt um. */
:root[data-thema="hell"] .nav-logo,
:root[data-thema="hell"] .footer-logo {
    background-image: url("assets/Sewer_Tech_Academy_logo.png");
    background-repeat: no-repeat;
    background-size: contain;
    background-position: left center;
}

/* Das weiße Original bleibt im Markup stehen – es trägt die Größe und die
   Bildbeschreibung. Sichtbar ist in der hellen Fassung der Hintergrund. */
:root[data-thema="hell"] .nav-logo img,
:root[data-thema="hell"] .footer-logo img {
    opacity: 0;
}

/* ---------- .info-card in der hellen Fassung ----------

   Auf Dunkel liegt über dem Foto ein dunkler Schleier, und die Schrift steht
   weiß darauf. Das funktioniert, weil Abdunkeln ein Foto nicht zerstört: es
   wird zur Nacht­aufnahme, bleibt aber ein Bild.

   Andersherum geht es nicht. Ein weißer Schleier, der dicht genug ist, dass
   dunkle Schrift darauf steht, lässt vom Foto nur noch Rauschen übrig – und
   Rauschen unter Schrift sieht nicht nach Struktur aus, sondern nach Schmutz.
   Ein grauer Schleier macht es nicht besser, nur trüber. Zwischen "Foto
   sichtbar" und "Schrift lesbar" gibt es hier keinen Wert, der beides kann;
   das ist keine Frage der Einstellung, sondern der Bauart.

   Deshalb hier eine andere: **oben Foto, unten Fläche.** Das obere Viertel
   der Kachel bleibt unbedeckt, dann ein kurzer Übergang, darunter deckendes
   Weiß. Die Schrift beginnt erst unterhalb – dafür der große Innenabstand
   oben. Das Foto ist damit ganz zu sehen statt zu einem Viertel zu ahnen,
   und die Schrift steht auf einer sauberen Fläche.

   Der Rahmen wird dünn: die 3 px daneben fangen auf Dunkel Lichtblitze an
   den Kanten ab, ein Problem, das es auf Hell nicht gibt. Übrig bleibt dort
   nur ein fetter blasser Ring. Stattdessen trägt die Kachel einen Schatten
   und hebt sich so von der Seite ab. */
:root[data-thema="hell"] .info-card {
    padding-top: 150px;
    border-width: 1px;
    box-shadow: var(--schatten-kachel);
}

:root[data-thema="hell"] .info-card:hover {
    box-shadow: 0 0 0 1px var(--primary-blue), var(--schatten-karte);
}

/* ---------- Notbehelf für die Partnerlogos ----------

   Die fünf Partnerlogos sind einfarbig weiß auf durchsichtig. Auf einer
   hellen Fläche sind sie nicht blass, sondern weg.

   brightness(0) macht daraus reines Schwarz. Bei einer einfarbig weißen
   Datei ist das genau die dunkle Fassung – bei einer farbigen wäre es
   Vandalismus. Es ist deshalb ausdrücklich ein Notbehelf, bis die richtigen
   dunklen Dateien da sind.

   Die Regel räumt sich selbst ab: sobald ein Logo ein data-hell mit dem
   Pfad seiner dunklen Fassung trägt, greift sie für dieses Logo nicht mehr,
   und sta.js tauscht stattdessen die Datei. Welche Dateien dafür gebraucht
   werden, steht in _nicht-hochladen/THEMA-HELL-DUNKEL.md. */
:root[data-thema="hell"] .partner-grid img:not([data-hell]) {
    filter: brightness(0);
}

body {
    font-family: var(--font-body);
    background-color: var(--bg-dark);
    color: var(--text-light);
    margin: 0;
    overflow-x: hidden;
    line-height: 1.6;
}

/* Alle Überschriften laufen auf der CI-Überschriftenschrift. Anton hat nur
   einen Schnitt, deshalb hier fest font-weight: 400 – sonst rechnet der
   Browser einen künstlichen Fettschnitt dazu, der ausgefranst aussieht.
   Aus demselben Grund stehen in den Regeln weiter unten keine
   font-weight-Angaben mehr auf Überschriften. */
h1,
h2,
h3,
h4,
h5,
h6 {
    font-family: var(--font-heading);
    font-weight: 400;
}

/* Sprunglink zum Inhalt. Liegt ausserhalb des sichtbaren Bereichs und wird
   erst beim Anfahren mit der Tabulatortaste eingeblendet. Ohne ihn muss sich
   jemand, der die Seite per Tastatur bedient, auf jeder Unterseite erst durch
   die komplette Navigation arbeiten. */
.skip-link {
    position: absolute;
    left: 20px;
    top: -100px;
    z-index: 2000;
    background-color: var(--primary-blue);
    color: #fff;
    padding: 12px 22px;
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
    transition: top 0.2s ease;
}

.skip-link:focus {
    top: 20px;
}

/* Da, aber nicht zu sehen.

   Für Beschriftungen, die auf dem Bildschirm überflüssig sind, weil der
   Zusammenhang aus der Umgebung hervorgeht – die ein Vorleseprogramm aber
   braucht, um ein Feld benennen zu können.

   Bewusst nicht display:none und nicht visibility:hidden: beides nimmt das
   Element auch aus dem Vorlesen heraus, und dann wäre nichts gewonnen. Der
   Umweg über einen Ein-Pixel-Ausschnitt ist der einzige, der es sichtbar für
   Hilfsmittel und unsichtbar für das Auge lässt.

   white-space: nowrap steht hier, weil ein umgebrochener Text in einem
   Ein-Pixel-Kasten bei manchen Browsern doch wieder Platz einnimmt. */
.nur-lesbar {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Navigationsleiste */
.navbar {
    width: 100%;
    background: var(--nav-schleier);
    position: fixed;
    top: 0;
    left: 0;
    padding: 20px 40px;
    display: grid;
    /* Logo | freier Raum | Sprachumschalter | Hell/Dunkel | CTA.

       Die Navigationspunkte stehen NICHT im Raster: sie sind an der Leiste
       selbst zentriert, siehe weiter unten. Deshalb sind es hier vier
       Spalten und nicht fünf. Nicht vorhandene Elemente – eine einzige
       Sprache, oder kein Umschalter, weil JavaScript ausfällt – machen ihre
       Spalte 0 breit; die freie Spalte davor gleicht das aus. */
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    z-index: 1000;
    box-sizing: border-box;
    transition: background 0.3s ease, padding 0.3s ease;
}

/* Wird von sta.js nur kurz gesetzt, wenn der Zustand der Leiste ohne
   Scrollen hergestellt wird (Reload mitten auf der Seite, Zurueck-Button).
   Ohne diese Zeile wuerde die Leiste dabei sichtbar einblenden. */
.navbar.nav-no-transition,
.navbar.nav-no-transition .nav-logo img {
    transition: none;
}

.navbar.scrolled,
.navbar.menu-open {
    background: var(--bg-deep);
    padding-top: 12px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border-color);
}

.nav-logo img {
    height: 45px;
    /* width: auto überschreibt das width="500"-Attribut im HTML. Ohne diese
       Zeile setzt der Browser die Breite auf 500px und quetscht das Logo
       flach. Die Attribute bleiben im Markup, damit der Browser das
       Seitenverhältnis kennt und beim Laden nichts springt. */
    width: auto;
    display: block;
    transition: height 0.3s ease;
}

.navbar.scrolled .nav-logo img {
    height: 35px;
}

.navbar ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
}

/* Die Navigationspunkte sitzen in der Mitte der SEITE, nicht in der Mitte
   ihrer Rasterspalte.

   Das ist ein Unterschied: links steht nur das Logo, rechts Sprachauswahl,
   Hell/Dunkel und der Knopf zur Lernplattform. Die freie Spalte dazwischen
   ist damit nach links verschoben – und mit ihr alles, was darin zentriert
   ist. Als 2021 nur Logo und CTA dastanden, fiel das kaum auf; mit jedem
   Element rechts wurde es deutlicher.

   Deshalb hier aus dem Raster heraus und an der Leiste selbst ausgerichtet.
   Die Leiste ist über die volle Breite fixiert, ihre Mitte ist also die
   Seitenmitte – egal, was links und rechts steht. Kommt eine Sprache dazu
   oder fällt eine weg, verrutscht nichts mehr.

   top statt einer festen Höhe, weil die Leiste beim Scrollen flacher wird.

   Nur ab 1151 px. Darunter klappt die Liste als Block unter die Leiste; das
   regelt der Block "Navigation: Burger-Menü" weiter unten, und der soll hier
   nicht gegenangeschrieben werden. */
@media (min-width: 1151px) {
    .navbar ul {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
    }
}

.navbar ul li {
    margin: 0 20px;
}

.navbar ul li a {
    color: var(--nav-muted);
    text-decoration: none;
    font-weight: 500;
    font-size: 0.95rem;
    transition: color 0.3s;
}

.navbar ul li a:hover {
    color: var(--primary-blue);
}

/* Durchgehend gefüllt, nicht erst beim Überfahren. Über dem Hero steht er auf
   einem Bild – eine blaue Kontur mit blauer Schrift verschwindet dort je nach
   Bildausschnitt, eine gefüllte Fläche nie. Beim Überfahren wird sie dunkler
   statt sich erst aufzubauen. */
.nav-cta {
    justify-self: end;
    border: 1px solid var(--primary-blue);
    background-color: var(--primary-blue);
    color: #fff !important;
    padding: 8px 20px;
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9rem;
    transition: all 0.3s ease;
}

.nav-cta:hover {
    background-color: var(--primary-hover);
    border-color: var(--primary-hover);
    color: #fff !important;
    transform: scale(1.05);
    box-shadow: var(--glut-blau);
}

/* Sprachumschalter
   Steht zwischen Navigation und CTA und bleibt bewusst zurueckhaltend: die
   Sprache waehlt man einmal, danach soll sie nicht mit dem CTA um
   Aufmerksamkeit streiten. Deshalb Kuerzel statt Flaggen – eine Flagge steht
   fuer ein Land, nicht fuer eine Sprache, und Englisch gehoert keinem.

   Die aktuelle Sprache ist ein <span>, kein Link: ein Link, der auf die Seite
   zeigt, auf der man schon steht, ist fuer Screenreader und Tastatur nur eine
   Sackgasse. Erzeugt wird der ganze Block von build.js. */
.lang-switch {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: 24px;
    margin-right: 16px;
    justify-self: end;
}

.lang-switch a,
.lang-switch .lang-current {
    display: block;
    padding: 4px 7px;
    border-radius: 4px;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    line-height: 1;
    text-decoration: none;
    transition: color 0.3s ease, background-color 0.3s ease;
}

.lang-switch a {
    color: var(--nav-muted);
}

.lang-switch a:hover,
.lang-switch a:focus-visible {
    color: var(--primary-blue);
    background-color: rgba(81, 164, 222, 0.12);
}

.lang-switch .lang-current {
    color: var(--text-light);
    background-color: var(--flaeche-aktiv);
    cursor: default;
}

/* ---------- Umschalter hell / dunkel ----------

   Erzeugt von sta.js, siehe dort den Block "Hell und Dunkel". Er sitzt links
   vom Knopf zur Lernplattform - der bleibt das Letzte in der Reihe und damit
   das Auffälligste.

   Sonne und Mond liegen übereinander im selben Rasterfeld; sichtbar ist immer
   nur eines. Der Wechsel dreht das eine heraus und das andere herein, statt
   sie hart zu tauschen. */
.thema-knopf {
    justify-self: end;
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    padding: 0;
    margin-right: 14px;
    flex-shrink: 0;
    border: 1px solid var(--border-color);
    border-radius: 50%;
    background-color: transparent;
    color: var(--nav-muted);
    cursor: pointer;
    transition: color 0.3s ease, border-color 0.3s ease, background-color 0.3s ease;
}

.thema-knopf:hover,
.thema-knopf:focus-visible {
    color: var(--primary-blue);
    border-color: var(--primary-blue);
}

.thema-knopf svg {
    /* Beide Zeichen im selben Rasterfeld, also exakt übereinander. */
    grid-area: 1 / 1;
    width: 19px;
    height: 19px;
    transition: opacity 0.35s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.64, 1);
}

/* Dunkel zeigt die Sonne (der Klick führt ins Helle), hell den Mond. */
.thema-sonne {
    opacity: 1;
    transform: rotate(0) scale(1);
}

.thema-mond {
    opacity: 0;
    transform: rotate(-90deg) scale(0.4);
}

:root[data-thema="hell"] .thema-sonne {
    opacity: 0;
    transform: rotate(90deg) scale(0.4);
}

:root[data-thema="hell"] .thema-mond {
    opacity: 1;
    transform: rotate(0) scale(1);
}

/* ---------- Der Übergang beim Umschalten ----------

   Ohne das hier kippt die ganze Seite in einem einzigen Bild um. Das ist
   nicht nur unschön, es ist auch kurz orientierungslos: alles ist plötzlich
   woanders hell.

   Deshalb setzt sta.js für einen halben Moment diese Klasse ans <html> und
   nimmt sie danach wieder weg. Nur währenddessen tragen alle Elemente einen
   Übergang auf ihre Farben. Dauerhaft wäre das teuer und würde ausserdem
   jeden Hover-Effekt verlangsamen.

   background-image steht mit in der Liste: die Kacheln auf der Startseite und
   der Schleier über der Navileiste sind Verläufe, keine Flächen. filter auch,
   sonst würden die weissen Logos hart umschlagen statt mitzuziehen. */
:root.thema-wechselt,
:root.thema-wechselt *,
:root.thema-wechselt *::before,
:root.thema-wechselt *::after {
    transition: background-color 0.4s ease, background-image 0.4s ease,
                color 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease,
                fill 0.4s ease, stroke 0.4s ease, filter 0.4s ease,
                text-decoration-color 0.4s ease !important;
}

/* Die Regel oben würde sonst die Drehung von Sonne und Mond überschreiben -
   also genau die Bewegung, um die es beim Klick geht. */
:root.thema-wechselt .thema-knopf svg {
    transition: opacity 0.35s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.64, 1) !important;
}

/* Wer im Betriebssystem weniger Bewegung eingestellt hat, bekommt den
   Wechsel ohne Blende. sta.js setzt die Klasse dann gar nicht erst - diese
   Regel ist die zweite Sicherung. */
@media (prefers-reduced-motion: reduce) {

    :root.thema-wechselt,
    :root.thema-wechselt *,
    :root.thema-wechselt *::before,
    :root.thema-wechselt *::after,
    :root.thema-wechselt .thema-knopf svg {
        transition: none !important;
    }
}

/* Burger-Menü */
.menu-toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    cursor: pointer;
    z-index: 1001;
}

.menu-toggle span {
    width: 25px;
    height: 3px;
    background-color: var(--text-light);
    transition: 0.3s;
}

.menu-overlay {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.85);
    z-index: 999;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}

.menu-overlay.active {
    opacity: 1;
    visibility: visible;
}

/* Hero Sektion */
.hero {
    position: relative;
    height: 100vh;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
}

.hero-video {
    position: absolute;
    top: 50%;
    left: 50%;
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    z-index: -1;
    transform: translate(-50%, -50%);
    object-fit: cover;
    filter: var(--hero-video-filter);
}

/* Der Schleier über dem Film. In der dunklen Fassung ist er durchsichtig und
   damit wirkungslos – dort erledigt die Abdunklung des Videos die Arbeit. In
   der hellen liegt er als milchige Scheibe über der Mittagsaufnahme, damit
   die dunkle Schrift nicht mal auf Himmel und mal auf Hochhaus sitzt.

   z-index 0: über dem Video (-1), unter dem Text (2). */
.hero::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--hero-schleier);
    z-index: 0;
    pointer-events: none;
}

.hero::after {
    content: "";
    position: absolute;
    bottom: -1px;
    left: -1px;
    right: -1px;
    height: 50%;
    background: linear-gradient(to bottom, transparent, var(--bg-dark));
    z-index: 0;
    pointer-events: none;
}

.hero .container {
    position: relative;
    z-index: 2;
    padding: 20px;
    text-align: center;
    max-width: 1000px;
}

@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.hero .container>* {
    animation: fadeInUp 1s ease-out forwards;
}

h1.brand-title {
    font-size: 4.5rem;
    margin: 0 0 10px 0;
    text-shadow: 3px 3px 10px rgba(var(--hero-schatten), var(--hero-schatten-deckung));
}

.brand-glow {
    font-family: var(--font-heading);
    color: var(--primary-blue);
    text-shadow: var(--brand-glow-schatten);
}

.hero h2 {
    font-size: 1.8rem;
    color: var(--text-light);
    margin: 0 0 15px 0;
    text-shadow: 2px 2px 8px rgba(var(--hero-schatten), var(--hero-schatten-deckung));
    animation-delay: 0.3s;
}

.hero h3 {
    font-size: 1.3rem;
    color: var(--primary-blue);
    margin: 0 0 35px 0;
    text-shadow: 1px 1px 5px rgba(var(--hero-schatten), var(--hero-schatten-deckung));
    animation-delay: 0.5s;
}

.hero-buttons {
    display: flex;
    gap: 20px;
    justify-content: center;
    animation-delay: 0.7s;
}

.btn {
    padding: 14px 30px;
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
    transition: all 0.3s ease;
    font-size: 1rem;
}

.btn-primary {
    background-color: var(--primary-blue);
    color: white;
    box-shadow: var(--glut-blau);
}

.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: var(--glut-blau-stark);
}

.btn-secondary {
    border: 2px solid var(--knopf-zweit);
    color: var(--knopf-zweit);
}

.btn-secondary:hover {
    background-color: var(--knopf-zweit);
    color: var(--knopf-zweit-text);
    transform: translateY(-2px);
}

/* Scroll-Down Pfeil */
.scroll-down {
    position: absolute;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    width: 50px;
    height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    animation: bounce 2s infinite;
    transition: opacity 0.3s ease;
}

.scroll-down::after {
    content: "";
    width: 15px;
    height: 15px;
    border-right: 3px solid var(--knopf-zweit);
    border-bottom: 3px solid var(--knopf-zweit);
    transform: rotate(45deg);
    margin-top: -5px;
}

@keyframes bounce {

    0%,
    20%,
    50%,
    80%,
    100% {
        transform: translateX(-50%) translateY(0);
    }

    40% {
        transform: translateX(-50%) translateY(-10px);
    }

    60% {
        transform: translateX(-50%) translateY(-5px);
    }
}

/* Info Sektion - Mit grauer Kante & lückenloser Randeinfassung */
.info-section {
    padding: 100px 40px;
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 30px;
}

.info-row {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 30px;
}

.info-card {
    position: relative;
    background-color: var(--bg-kachel);
    /* Dunkler Grundton fängt Lichtblitze an den Kanten ab */
    background-size: cover;
    background-position: center;
    padding: 60px 45px;
    border-radius: 10px;
    border: 3px solid var(--rand-kachel);
    /* Stabile graue Kante */
    box-shadow: inset 0 0 0 1px var(--rand-kachel-innen);
    /* Innerer Schnittschutz gegen helles Pixel-Bleeding */
    /* Die Höhe ist die einzige Stellschraube, die es hier gibt: die Breite
       steckt in .info-section und ist dieselbe wie bei jedem anderen
       Abschnitt (1200px). Breitere Kacheln liefen aus der Flucht. */
    min-height: 400px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    overflow: hidden;
    z-index: 1;
    box-sizing: border-box;
    background-clip: padding-box;
    transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
    text-decoration: none;
    color: inherit;
}

.info-card::before {
    content: '';
    position: absolute;
    inset: -1px;
    background: var(--kachel-verlauf);
    z-index: -1;
    border-radius: inherit;
    transition: background 0.3s ease;
}

.info-card:hover {
    transform: translateY(-5px);
    border-color: var(--primary-blue);
    box-shadow: inset 0 0 0 1px var(--primary-blue), var(--schatten-kachel);
}

.info-card:hover::before {
    background: var(--kachel-verlauf-hover);
}

/* Schrift und Knopf wachsen mit. Nur die Kachel größer zu machen, hätte den
   Inhalt darin verloren aussehen lassen – dieselbe Menge Text in mehr Raum
   wirkt nicht größer, sondern leerer. */
.info-card h2 {
    font-size: 2rem;
    color: var(--text-light);
    margin: 0 0 15px 0;
    line-height: 1.2;
}

.info-card p {
    color: var(--text-light);
    opacity: 0.9;
    font-size: 1.05rem;
    margin: 0 0 35px 0;
    line-height: 1.6;
}

.info-card .card-btn {
    background-color: transparent;
    border: 1px solid var(--primary-blue);
    color: var(--primary-blue);
    padding: 10px 24px;
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    text-align: center;
    transition: all 0.3s ease;
    display: inline-block;
    width: fit-content;
}

.info-card .card-btn:hover {
    background-color: var(--primary-blue);
    color: white;
    box-shadow: var(--glut-blau);
}

/* Slider Sektion & Testimonials Common Config */
.slider-section,
.testimonials-section {
    background-color: var(--bg-band);
    padding: 80px 0;
}

.slider-container {
    position: relative;
}

.slider-section h2,
.testimonials-section h2,
.section-title {
    margin: 0 0 30px 40px;
    font-size: 2.2rem;
    color: var(--text-light);
}

/* Der seitliche Innenabstand ist halbe Sichtfensterbreite minus halbe
   Kartenbreite (340px / 2 = 170px). Dadurch rastet die aktive Karte in der
   Mitte ein statt am linken Rand. max() faengt sehr schmale Fenster ab, in
   denen der Wert negativ und die Angabe damit ungueltig waere.

   WICHTIG: padding-left und scroll-padding-left muessen denselben Wert tragen,
   deshalb die gemeinsame Variable. Der Schnappunkt einer Karte liegt bei
   "Kartenposition minus scroll-padding-left" - nur wenn beide gleich sind,
   bleiben die Schnappunkte exakte Vielfache der Kartenbreite. Genau damit
   rechnet setupPremiumSlider() in sta.js (goToIndex, currentIndex und die
   Umbruchgrenzen des Endlos-Laufs). Wer nur einen der beiden Werte aendert,
   verschiebt den Slider gegen seine eigene Rechnung. */
.slider-wrapper {
    --slider-inset: max(20px, calc(50% - 170px));

    display: flex;
    overflow-x: auto;
    gap: 25px;
    padding: 20px var(--slider-inset) 40px var(--slider-inset);
    -webkit-overflow-scrolling: touch;
    cursor: grab;
    /* Der Zwilling ist keine Kosmetik: Safari kennt das unpraefixierte
       user-select erst seit Version 17. Davor - und auf jedem iOS darunter -
       wird die Zeile schlicht ignoriert, und beim Ziehen markiert der Browser
       den Text der Karten mit. Genau das war ein Jahr lang der Fall, ohne dass
       es jemandem auffiel: die Regel STAND ja da. */
    -webkit-user-select: none;
    user-select: none;
    scroll-snap-type: x mandatory;
    scroll-padding-left: var(--slider-inset);
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.slider-wrapper::-webkit-scrollbar {
    display: none;
}

.slider-wrapper:active {
    cursor: grabbing;
}

.testimonial-slider-wrapper {
    padding-top: 170px;
}

.slider-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background-color: var(--glas-bg);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    color: var(--text-light);
    border: 1px solid var(--glas-rand);
    border-radius: 50%;
    width: 48px;
    height: 48px;
    padding: 0;
    box-shadow: var(--schatten-glas);
    cursor: pointer;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.3s, transform 0.3s, background-color 0.3s, border-color 0.3s;
}

/* Das Chevron ist ein Inline-SVG im HTML. Strichstaerke und Rundungen stehen
   hier und nicht als Attribute am Pfad, damit alle Pfeile identisch bleiben.
   pointer-events: none sorgt dafuer, dass immer der Button das Klickziel ist. */
.slider-nav svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    pointer-events: none;
}

/* Die Zentrierung laeuft ueber translateY(-50%) - der Scale muss deshalb
   mit angegeben werden, sonst springt der Button beim Hover aus der Mitte. */
.slider-nav:hover {
    background-color: var(--primary-blue);
    border-color: transparent;
    transform: translateY(-50%) scale(1.06);
}

/* Den Fokusrahmen liefert bereits die globale button:focus-visible-Regel
   weiter unten. */

/* Die Pfeile sind normalerweise unsichtbar und erscheinen beim Ueberfahren.
   Fuer die Tastaturbedienung muss :focus-within mit hinein, sonst springt der
   Fokus auf einen Button, den niemand sehen kann. */
.slider-container:hover .slider-nav,
.slider-container:focus-within .slider-nav,
.slider-nav:focus-visible {
    opacity: 1;
}

/* Auf Touch-Geraeten gibt es kein Ueberfahren - dort blieben die Pfeile sonst
   dauerhaft unsichtbar. */
@media (hover: none) {
    .slider-nav {
        opacity: 1;
    }
}

.slider-nav.prev {
    left: 14px;
}

.slider-nav.next {
    right: 14px;
}

/* transform-origin: die Karte waechst beim Ueberfahren NUR nach rechts, ihre
   linke Kante bleibt stehen. Das ist kein Geschmacksentscheid, sondern behebt
   ein Zittern:

   Der Schnappbereich einer Karte ist ihr TRANSFORMIERTER Rahmen, nicht ihre
   Layout-Box. Waechst die Karte aus der Mitte heraus, wandert ihre linke Kante
   beim Vergroessern nach links - und weil scroll-snap-align: start genau diese
   Kante einrastet, zieht die Karte die Scrollposition hinter sich her. Das
   ergibt eine Rueckkopplung mit der is-scrolling-Regel weiter unten:
   Hover -> Karte waechst -> Scrollposition rutscht -> scroll-Ereignis ->
   is-scrolling -> transform: none -> Karte schrumpft -> Scrollposition rutscht
   zurueck -> scroll-Ereignis -> und von vorn, rund sechs Mal pro Sekunde.
   Sichtbar als Zittern in KLEINER Darstellung: die Karte kam nie ueber
   scale(1.006) hinaus, weil is-scrolling sie jedes Mal zurueckwarf.

   Betroffen war immer genau die gerade eingerastete Karte - auf index.html also
   die erste, die von Luca Arceri. Mit der linken Kante als Ursprung bleibt der
   Schnappbereich beim Vergroessern unveraendert, die Scrollposition ruehrt sich
   nicht, und der Hover-Effekt laeuft sauber bis scale(1.03) durch.

   NICHT durch einen Ruhezustand scale(0.97) ersetzen: der Schnappbereich
   wandert dann genauso, das Zittern bleibt (nachgemessen). */
.course-card,
.testimonial-card {
    flex: 0 0 auto;
    width: 340px;
    background-color: var(--bg-card);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    scroll-snap-align: start;
    box-sizing: border-box;
    transform-origin: left center;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.course-card {
    overflow: hidden;
}

.testimonial-card {
    overflow: visible;
}

.course-card:hover,
.testimonial-card:hover {
    transform: scale(1.03);
    box-shadow: var(--schatten-karte);
}

/* NUR waehrend der Slider faehrt, kein Hover-Effekt: die Karten ziehen dann
   unter einem stehenden Zeiger vorbei, der Hover-Zustand wechselt schneller von
   Karte zu Karte als die 0,3s-Animation dauert, und die Reihe zappelt in lauter
   angefangenen Zwischengroessen ("gross und klein zugleich").

   Der Hover-Effekt selbst bleibt vollstaendig erhalten - er ruht nur, solange
   sich der Slider bewegt, und kommt rund 0,2s nach dem Anhalten von allein
   zurueck, ohne dass die Maus bewegt werden muss. Das Rollen der Seite
   beruehrt ihn ueberhaupt nicht.

   Die Klasse setzt sta.js auf .slider-wrapper. Der Uebergang bleibt stehen:
   es schrumpft einmal weich, statt zu flackern. */
.slider-wrapper.is-scrolling .course-card,
.slider-wrapper.is-scrolling .testimonial-card {
    transform: none;
    box-shadow: none;
}

/* Die Masse stehen als Variablen hier oben, damit Punkt und Pille nicht
   auseinanderlaufen koennen. Die Punkte duerfen eng stehen: die Pille ist kein
   Element ueber der Reihe, sondern der aktive Punkt selbst - die Nachbarn
   ruecken beim Wachsen von allein zur Seite. */
.slider-pagination {
    --dot-size: 12px;
    --dot-active-width: 26px;

    position: absolute;
    bottom: 10px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 10px;
    z-index: 10;
}

/* Die Punkte werden von sta.js als <button> erzeugt, damit sie per Tastatur
   erreichbar sind. Deshalb muessen hier die Button-Standardstile (Rahmen,
   Innenabstand, Systemaussehen) abgeraeumt werden.

   WICHTIG: Die Markierung ist allein die Breite - alle Punkte haben dieselbe
   Farbe. Genau daran krankte die alte Fassung: sie markierte ueber eine
   0,3s-Blende von Grau nach Blau, und beim schnellen Scrollen wanderte .active
   weiter, bevor irgendein Punkt volles Blau erreicht hatte. Die ganze Reihe
   blieb blass und die Markierung schien zu verschwinden. Eine Breite kann das
   nicht: sie ist zu jedem Zeitpunkt eindeutig, egal wie schnell gescrollt wird.

   border-radius als halbe Hoehe statt 50%: bei 26x12 ergaebe 50% eine Ellipse,
   so wird daraus eine saubere Pille (und beim 12x12-Punkt weiterhin ein
   Kreis). */
.pagination-dot {
    width: var(--dot-size);
    height: var(--dot-size);
    flex: 0 0 auto;
    padding: 0;
    border: 0;
    appearance: none;
    -webkit-appearance: none;
    border-radius: calc(var(--dot-size) / 2);
    background-color: var(--punkt-inaktiv);
    cursor: pointer;
    transition: width 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), transform 0.2s;
}

.pagination-dot:not(.active):hover {
    transform: scale(1.2);
}

/* Der aktive Punkt IST die Pille. Unterschieden wird allein ueber die Breite -
   die Farbe bleibt bewusst dieselbe wie bei den uebrigen Punkten, deshalb steht
   hier kein background-color.

   Weil immer genau einer aktiv ist, bleibt die Gesamtbreite der Reihe konstant:
   der schrumpfende und der wachsende Punkt heben sich zu jedem Zeitpunkt auf,
   die zentrierte Reihe wackelt also nicht. Aus demselben Grund gibt es beim
   Sprung von der letzten auf die erste Folie keine weite Wanderung mehr - es
   tauschen nur zwei Nachbarn ihre Breite. */
.pagination-dot.active {
    width: var(--dot-active-width);
}

.course-img-wrapper {
    position: relative;
    height: 240px;
    width: 100%;
    overflow: hidden;
}

.course-img-wrapper img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.course-content {
    padding: 25px;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

.course-content h3 {
    font-size: 1.25rem;
    margin: 0 0 10px 0;
    color: var(--text-light);
    min-height: 56px;
    display: flex;
    align-items: center;
}

.course-content p {
    color: var(--text-muted);
    font-size: 0.9rem;
    margin: 0 0 20px 0;
    flex-grow: 1;
}

.course-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: auto;
    padding-top: 15px;
    border-top: 1px solid var(--linie-zart);
}

.course-price {
    font-weight: 600;
    color: var(--text-light);
    font-size: 0.95rem;
}

.course-btn {
    background-color: transparent;
    border: 1px solid var(--primary-blue);
    color: var(--primary-blue);
    padding: 6px 14px;
    border-radius: 4px;
    text-decoration: none;
    font-weight: 500;
    font-size: 0.85rem;
    transition: all 0.2s ease;
}

.course-btn:hover {
    background-color: var(--primary-blue);
    color: white;
}

.testimonial-card {
    padding: 0 30px 40px 30px;
    text-align: center;
    align-items: center;
}

.testimonial-img-wrapper {
    width: 226px;
    height: 226px;
    border-radius: 50%;
    overflow: hidden;
    margin-top: -150px;
    margin-bottom: 25px;
    flex-shrink: 0;
    box-shadow: var(--schatten-karte-stark);
    background-color: var(--bg-card);
}

.testimonial-img-wrapper img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.testimonial-content {
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    flex-grow: 1;
    width: 100%;
}

.testimonial-content h4 {
    margin: 0 0 4px 0;
    font-size: 1.3rem;
    color: var(--text-light);
}

.testimonial-content .company {
    font-size: 0.85rem;
    color: var(--primary-blue);
    font-weight: 500;
    margin-bottom: 20px;
    display: block;
}

.testimonial-content p {
    color: var(--text-muted);
    font-size: 0.95rem;
    margin: 0;
    font-style: italic;
    flex-grow: 1;
    line-height: 1.7;
    text-align: left;
    text-wrap: balanced;
    hyphens: auto;
}

/* Mentoren & Partner-Logos */
.partner-section {
    padding: 80px 40px;
    max-width: 1200px;
    margin: 0 auto;
    text-align: center;
}

.partner-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 50px;
    opacity: 0.75;
}

.partner-grid img {
    max-height: 50px;
    max-width: 160px;
    object-fit: contain;
    transition: opacity 0.3s;
}

.partner-grid img:hover {
    opacity: 1;
}

/* ---------- Laufband ----------
   Die Klasse setzt sta.js, nicht das HTML. Faellt JavaScript aus, bleibt oben
   die zentrierte, umbrechende Reihe stehen - dann gibt es weder Klone noch
   etwas zu scrollen, und ein Streifen mit abgeschnittenen Logos waere
   schlechter als das, was vorher da war.

   Bewegt wird ueber scrollLeft, nicht per transform-Animation: nur so teilen
   sich Automatik und Handbetrieb dieselbe Position. Eine CSS-Animation waere
   nicht von Hand scrollbar. */
.partner-grid.is-marquee {
    flex-wrap: nowrap;
    /* Bei ueberlaufendem Inhalt verteilt center den Ueberlauf auf BEIDE Seiten -
       der linke Teil landet im negativen Scrollbereich und ist unerreichbar. */
    justify-content: flex-start;
    overflow-x: auto;
    cursor: grab;
    /* Zwilling wie bei .slider-wrapper weiter oben - siehe den Grund dort. */
    -webkit-user-select: none;
    user-select: none;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* Ohne Weichzeichner an den Kanten poppen die Logos hart ins Bild. */
    -webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
    mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
}

/* dasselbe Muster wie bei .slider-wrapper weiter oben */
.partner-grid.is-marquee::-webkit-scrollbar {
    display: none;
}

.partner-grid.is-marquee.is-dragging {
    cursor: grabbing;
}

/* Steht der Streifen, weil das Geraet auf "Bewegung reduzieren" steht.

   Die Einstellung wird nicht ueberschrieben - ein endlos laufendes Band ist
   genau das, wogegen sie gemacht ist. Der Streifen soll dabei aber nicht wie
   eingefroren aussehen: die Kanten laufen deutlicher aus, damit erkennbar
   bleibt, dass es dort weitergeht und man wischen kann.

   Ohne diesen Zustand sah es fuer jemanden mit der Einstellung so aus, als
   waere die Reihe schlicht kaputt. */
.partner-grid.is-marquee.is-static {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
    mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
}

/* Flex-Elemente haben von Haus aus flex-shrink: 1. Mit nowrap wuerden die Logos
   gestaucht statt ueberzulaufen - es gaebe dann gar nichts zu scrollen. */
.partner-grid.is-marquee img {
    flex: 0 0 auto;
}

/* FAQ Sektion */
.faq-section {
    padding: 100px 40px;
    max-width: 1100px;
    margin: 0 auto;
}

.faq-container {
    margin-top: 40px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    align-items: start;
}

.faq-column {
    display: flex;
    flex-direction: column;
    gap: 15px;
}

.faq-item {
    background-color: var(--bg-card);
    border-radius: 6px;
    border: 1px solid var(--border-color);
    overflow: hidden;
}

.faq-question {
    padding: 22px 30px;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    color: var(--text-light);
    font-size: 1.1rem;
    font-weight: 500;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.faq-question::after {
    content: "+";
    font-size: 1.5rem;
    color: var(--primary-blue);
    transition: transform 0.3s;
}

.faq-item.active .faq-question::after {
    transform: rotate(45deg);
}

.faq-answer {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease-out;
}

.faq-answer-content {
    padding: 0 30px 25px 30px;
    color: var(--text-muted);
    font-size: 0.95rem;
}

/* Ohne eigene Regel bliebe hier das Browser-Blau stehen – auf dunklem Grund
   kaum lesbar. */
.faq-answer-content a {
    color: var(--primary-blue);
}

/* Mobile Login Sektion */
.mobile-auth-section {
    display: none;
    padding: 30px 20px;
    background-color: var(--bg-band);
    text-align: center;
    border-bottom: 1px solid var(--border-color);
}

/* Der Knopf nimmt die volle Breite. Stand vorher als style="display: block"
   am Link – auf jeder der acht Seiten dieselbe Zeile. */
.mobile-auth-section .btn {
    display: block;
}

/* ---------- Formulare ----------
   Ein Aussehen für alle Eingabefelder der Website. Das Newsletter-Feld im
   Footer war vorher das einzige mit weissem Kasten und grauer Kante – ein
   heller Fremdkörper in einem sonst durchgehend dunklen Layout, und
   ausserdem eine zweite Definition neben der des Landingpage-Formulars.
   Beide teilen sich jetzt diese Regeln: wer das Aussehen ändert, ändert es
   an genau einer Stelle. Seitenspezifisch bleibt nur, was wirklich
   seitenspezifisch ist (beim Newsletter der Abstand nach unten).

   .sta-form hiess vorher .lp-form und stand im <style>-Block der
   Landingpage. Seit dasselbe Formular auch auf /kontakt steht, trägt es
   keinen Seitennamen mehr. */
/* Kasten um ein Formular. Bewusst eine eigene Klasse und nicht .contact-card
   von der Kontaktseite: deren Regel .contact-card p würde das Kleingedruckte
   unter dem Knopf überschreiben (höhere Spezifität als .form-legal). */
.form-card,
.booking-card {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 40px 35px;
}

.sta-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.sta-form label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-muted);
    display: block;
    margin-bottom: 6px;
}

.sta-form input,
.sta-form select,
.sta-form textarea,
.newsletter-form input[type="email"] {
    width: 100%;
    box-sizing: border-box;
    padding: 13px 15px;
    border-radius: 6px;
    border: 1px solid var(--border-color);
    background-color: var(--bg-input);
    color: var(--text-light);
    font-family: var(--font-body);
    font-size: 0.95rem;
}

.sta-form textarea {
    resize: vertical;
    min-height: 120px;
    line-height: 1.6;
}

/* Die kleinen Pfeilchen am Zahlenfeld weg.

   Chrome, Edge und Safari setzen bei type="number" zwei Pfeile ins Feld, die
   sich nicht mitgestalten lassen: helles Grau auf dunklem Grund, eigene
   Schrift, eigene Groesse. Auf der einen Stelle, wo wir so ein Feld haben
   ("Wie viele Mitarbeitende?"), sind sie ueberfluessig – man tippt eine Zahl,
   man klickt sie nicht hoch.

   Firefox braucht dafuer die eigene Zeile appearance: textfield; die
   -webkit-Pseudoelemente kennt er nicht.

   Getippt, gefuegt oder ueber die Pfeiltasten geaendert wird weiterhin ganz
   normal – nur die Klickpfeile sind fort. Und weil das Feld type="number"
   bleibt, oeffnet das Handy weiterhin die Zifferntastatur. */
.sta-form input[type="number"] {
    appearance: textfield;
    -moz-appearance: textfield;
}

.sta-form input[type="number"]::-webkit-outer-spin-button,
.sta-form input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
}

.sta-form input:focus,
.sta-form select:focus,
.sta-form textarea:focus,
.newsletter-form input[type="email"]:focus {
    outline: 2px solid var(--primary-blue);
    border-color: var(--primary-blue);
}

.sta-form button {
    margin-top: 8px;
    padding: 15px;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    background-color: var(--primary-blue);
    color: #fff;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 1rem;
    transition: all 0.3s ease;
    box-shadow: var(--glut-blau);
}

.sta-form button:hover {
    background-color: var(--primary-hover);
    transform: translateY(-2px);
}

/* Spamschutz. Das Feld ist für Menschen unsichtbar, automatische Skripte
   füllen es trotzdem aus – submit.php verwirft solche Einsendungen. Bewusst
   NICHT display:none: manche Bots erkennen das und lassen das Feld dann leer.
   Stand vorher als langer style="…" am Feld selbst, in jedem Formular neu. */
/* Der Honigtopf: ein Feld, das Menschen nicht sehen und Bots ausfuellen.

   Hier stand position: absolute mit left: -9999px - das Feld lag also noch im
   Layout. Ausfuellhelfer ueberspringen AUSGEBLENDETE Felder, verschobene aber
   nicht: ein Passwortmanager konnte es treffen. Und dann waere die Anfrage
   eines echten Kunden als Bot aussortiert worden, still und ohne Spur.

   display: none nimmt es aus dem Layout UND aus dem Zugriff der Ausfuellhelfer.
   Einfache Spam-Skripte lesen das HTML und fuellen trotzdem alles aus - genau
   die faengt es weiter ab. */
.honeypot {
    display: none;
}

/* Kleingedrucktes unter dem Absenden-Knopf */
.form-legal {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin: 4px 0 0;
}

.form-legal a {
    color: var(--primary-blue);
}

/* Bestätigung nach dem Absenden. Wird von sta.js eingeblendet – bis dahin
   steht sie im HTML, ist aber unsichtbar. */
.form-success {
    display: none;
    background: var(--erfolg-bg);
    border: 1px solid var(--accent-bright);
    border-radius: 6px;
    padding: 16px;
    color: var(--text-light);
    font-size: 0.92rem;
}

/* Footer Sektion */
.footer {
    background-color: var(--bg-footer);
    border-top: 1px solid var(--border-color);
    padding: 80px 40px 30px 40px;
}

.footer-container {
    max-width: 1200px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1.5fr;
    gap: 50px;
}

.footer-brand p {
    color: var(--text-muted);
    margin: 20px 0;
    font-size: 0.95rem;
    max-width: 300px;
}

.footer-logo img {
    height: 45px;
    width: auto;
}

.footer-links h4 {
    color: var(--text-light);
    font-size: 1.1rem;
    margin: 0 0 20px 0;
}

.footer-links ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.footer-links ul li {
    margin-bottom: 12px;
}

.footer-links ul li a {
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.95rem;
    transition: color 0.2s;
}

.footer-links ul li a:hover {
    color: var(--primary-blue);
}

.newsletter-box h4 {
    color: var(--text-light);
    font-size: 1.1rem;
    margin: 0 0 15px 0;
}

.newsletter-box p {
    color: var(--text-muted);
    font-size: 0.85rem;
    margin: 0 0 20px 0;
}

/* Im Footer ist der Untergrund fast schwarz. Dort braucht das Feld eine
   deutlichere Kante als in einer Karte, sonst verschwindet es in der Fläche. */
.newsletter-form input[type="email"] {
    margin-bottom: 12px;
    border-color: rgba(var(--text-basis), 0.22);
}

.newsletter-form button {
    width: 100%;
    padding: 12px;
    background-color: var(--primary-blue);
    color: white;
    border: none;
    border-radius: 4px;
    font-weight: 600;
    cursor: pointer;
    font-size: 0.95rem;
    transition: background-color 0.2s;
}

.newsletter-form button:hover {
    background-color: var(--primary-hover);
}

.newsletter-legal {
    font-size: 0.75rem !important;
    color: rgba(var(--text-basis), 0.4) !important;
    margin-top: 12px;
    line-height: 1.4;
}

.newsletter-legal a {
    color: inherit;                      /* gleiche Farbe wie der Satz drumherum */
    text-decoration: underline;
    text-decoration-color: rgba(var(--text-basis), 0.25);  /* Linie dezenter als die Schrift */
    text-underline-offset: 3px;          /* Linie von der Schrift abrücken */
    transition: color 0,2s, text-decoration-color 0.2s;
}

.newsletter-legal a:hover {
    color: var(--primary-blue);
    text-decoration-color: var(--primary-blue);
}

/* Der Footer der Landingpage besteht nur aus dieser unteren Zeile – darüber
   steht nichts, wovon sie sich abgrenzen müsste. Trennlinie und der Abstand
   nach oben entfallen deshalb. Stand vorher als style="border-top: none" im
   Baustein; der Abstand blieb dabei stehen und riss ein Loch in den Footer. */
.footer.footer-lp .footer-bottom {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
}

.footer-bottom {
    max-width: 1200px;
    margin: 30px auto 0 auto;
    padding-top: 30px;
    border-top: 1px solid var(--linie-zart);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 20px;
}

.cert-seal img {
    height: 90px;
    width: auto;
    object-fit: contain;
}

.social-links {
    display: flex;
    align-items: center;
    /* Klein, weil der sichtbare Abstand vor allem aus der Klickflaeche
       kommt: im 52er Kasten sitzt ein rund 30 Pixel breites Logo, das sind
       gut 10 Pixel Luft auf jeder Seite. */
    gap: 6px;
    flex-wrap: wrap;
    margin-left:auto;
}

/* Die Logos stehen frei, ohne Kreis darum. Der Anker ist nur noch die
   Klickflaeche – die bleibt mit 44 Pixeln so gross, wie ein Finger sie
   braucht, auch wenn das Logo darin kleiner ist. Das ist auch der Grund,
   warum die Kaesten eine feste Groesse haben: dadurch steht die Breite der
   Reihe fest, bevor das erste Logo geladen ist, und beim Laden rutscht
   nichts. */
.social-icon {
    /* Muss groesser sein als das groesste Logo darin, sonst schrumpft der
       Browser es hinein: ein Bild in einem Flex-Kasten gibt von sich aus
       nach. Genau das hat frueher jede Feinjustierung ab einer gewissen
       Groesse wirkungslos gemacht. */
    width: 52px;
    height: 52px;
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    text-decoration: none;
    /* Zurueckhaltend, aber nicht ausgegraut. Mit einfarbig weissen Logos
       koennte man weiter heruntergehen; sobald hier farbige Markenlogos
       stehen, wirkt alles unter etwa 0.8 wie abgeschaltet. */
    opacity: 0.85;
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.social-icon:hover,
.social-icon:focus-visible {
    opacity: 1;
    transform: translateY(-2px);
}

/* Die Groesse steht hier und nicht in der SVG-Datei: ein ausgetauschtes Logo
   ist damit gleich gross, egal welche viewBox es mitbringt. object-fit sorgt
   dafuer, dass nichts verzerrt wird.

   --logo-hoehe ist die Feinjustierung. Markenlogos haben unterschiedlich viel
   Luft in ihrer viewBox: ein breites Logo wie der YouTube-Knopf wirkt in
   einem quadratischen Kasten kleiner als ein quadratisches wie Instagram,
   obwohl beide gleich viel Platz bekommen. Wer das ausgleichen will, setzt
   den Wert unten je Netzwerk. */
.social-icon img {
    height: var(--logo-hoehe, 30px);
    width: auto;
    /* Kein max-width und kein Schrumpfen: --logo-hoehe soll die einzige
       Stellschraube sein. Steht hier eine Obergrenze, tut sich beim
       Hochdrehen ab einem Punkt nichts mehr – und man dreht weiter, ohne
       dass es hilft. Die Grenze ist stattdessen die Groesse des Kastens
       oben; wird ein Logo groesser als der, wird der Kasten angepasst. */
    flex-shrink: 0;
    display: block;
    object-fit: contain;
}

/* ---------- Größen angleichen ----------

   --logo-hoehe ist die Höhe der viewBox, nicht die des Logos darin. Jedes
   Markenlogo hat unterschiedlich viel Luft am Rand, deshalb braucht jedes
   einen eigenen Wert. 

   WICHTIG: Diese Zahlen gelten für genau diese fünf Dateien. Wer ein Logo
   austauscht, stellt den Wert daneben neu ein – am besten mit dem Auge,
   nebeneinander im Browser. Nach oben gibt es keine Grenze mehr; wird ein
   Logo größer als der 52er Kasten oben, wächst der Kasten mit. */
.social-icon[aria-label="LinkedIn"]  { --logo-hoehe: 29px; }
.social-icon[aria-label="Instagram"] { --logo-hoehe: 31px; }
.social-icon[aria-label="Facebook"]  { --logo-hoehe: 45px; }
.social-icon[aria-label="YouTube"]   { --logo-hoehe: 49px; }
.social-icon[aria-label="TikTok"]    { --logo-hoehe: 51px; }

.copyright {
    width: 100%;
    text-align: center;
    margin-top: 40px;
    font-size: 0.85rem;
    color: rgba(var(--text-basis), 0.3);
}

.copyright a {
    color: rgba(var(--text-basis), 0.5);
    text-decoration: none;
}

/* =========================================================
   10. Unterseiten-Komponenten
   ========================================================= */

/* Hero-Variante für Unterseiten: flacher als die Startseite */
.hero.hero-sub {
    height: 72vh;
    min-height: 540px;
}

/* Eyebrow über Sektionstiteln */
/* Rolle laut CI: "Sublines". Sobald Gentlemens Script lizenziert vorliegt und
   in --font-accent steht, müssen hier text-transform und letter-spacing raus –
   Schreibschriften brechen in gesperrten Grossbuchstaben. */
.section-eyebrow {
    font-family: var(--font-accent);
    font-size: 0.8rem;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--primary-blue);
    display: block;
    margin-bottom: 14px;
}

/* Der Basis-.section-title hat margin-left 40px (Slider-Kontext).
   Auf Unterseiten sitzt er in einem Container, deshalb zurücksetzen. */
.page-section .section-title,
.section-title.flush {
    margin-left: 0;
}

/* Standard-Sektion mit Innenabstand */
.page-section {
    padding: 100px 40px;
    max-width: 1200px;
    margin: 0 auto;
}

.page-section.narrow {
    max-width: 900px;
}

.page-section.tight {
    padding-top: 0;
}

/* Dunkles Band, wie bei Slider/Testimonials */
.band-dark {
    background-color: var(--bg-band);
}

.band-dark .page-section {
    padding-top: 90px;
    padding-bottom: 90px;
}

/* Nach einem Farbwechsel gilt "tight" nicht.

   .tight heisst: kein Abstand nach oben, weil der Abschnitt darüber schon
   einen nach unten mitbringt. Hinter einem Band stimmt das nicht – dessen
   Innenabstand liegt INNERHALB der Farbe. Der Inhalt klebte dann direkt an
   der Kante, an der die Fläche wechselt.

   Das ist keine Ausnahme für eine Seite, sondern die Regel für die
   Kombination: sie greift überall, wo jemand die beiden künftig
   nebeneinanderstellt. _nicht-hochladen/pruefe-bandabstand.js hält sie fest. */
.band-dark + .page-section.tight {
    padding-top: 100px;
}

/* Zentrierter Sektionskopf */
.section-head {
    text-align: center;
    max-width: 760px;
    margin: 0 auto 50px auto;
}

/* Folgt dem Titel noch ein Fliesstext, gehoeren beide enger zusammen als der
   Kopf zum Inhalt darunter. Stand vorher als style="margin-bottom: 15px" in
   jeder einzelnen Seite - dieselbe Zahl an sechs Stellen. */
.section-head .section-title:not(:last-child) {
    margin-bottom: 15px;
}

.section-head p {
    color: var(--text-muted);
    font-size: 1.1rem;
    margin: 0;
}

/* Sanftes Einblenden beim Scrollen */
.reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.7s ease-out, transform 0.7s ease-out;
}

.reveal.visible {
    opacity: 1;
    transform: translateY(0);
}

/* --- Zweispaltiges Text-Layout --- */
.split {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    gap: 60px;
    align-items: center;
}

.split.even {
    grid-template-columns: 1fr 1fr;
}

.prose p {
    color: var(--text-muted);
    font-size: 1.05rem;
    margin: 0 0 20px 0;
}

.prose p strong {
    color: var(--text-light);
    font-weight: 600;
}

/* Links im Fliesstext auf der Markenfarbe. Ohne diese Regel bliebe das
   Browser-Blau stehen, das auf dunklem Grund kaum lesbar ist. Knöpfe sind
   ausgenommen – die bringen ihre eigene Farbe mit. */
.prose p a:not(.btn) {
    color: var(--primary-blue);
}

.prose p:last-child {
    margin-bottom: 0;
}

/* --- Säulen-Karten (Werte, Argumente) --- */
.pillar-list {
    display: flex;
    flex-direction: column;
    gap: 15px;
}

.pillar {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-left: 3px solid var(--primary-blue);
    border-radius: 6px;
    padding: 24px 28px;
    transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.pillar:hover {
    transform: translateX(5px);
    border-color: var(--primary-blue);
    box-shadow: var(--schatten-kachel);
}

.pillar h3 {
    margin: 0 0 6px 0;
    font-size: 1.15rem;
    color: var(--primary-blue);
}

.pillar p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.95rem;
}

/* --- Zitat-Block --- */
.quote-block blockquote {
    margin: 0;
    font-size: 1.6rem;
    font-weight: 300;
    line-height: 1.5;
    color: var(--text-light);
    position: relative;
    padding-top: 40px;
}

.quote-block blockquote::before {
    content: "\201E";
    position: absolute;
    /* Das dt. Anfuehrungszeichen sitzt auf der Grundlinie, also ca. 0,8em
       unterhalb der Oberkante. Ohne Ausgleich landet es auf Texthoehe. */
    top: -0.72em;
    left: -5px;
    font-size: 5rem;
    line-height: 1;
    color: var(--primary-blue);
    opacity: 0.5;
    font-family: var(--font-heading);
}

.quote-author {
    margin-top: 25px;
    padding-top: 20px;
    border-top: 1px solid var(--border-color);
}

.quote-author strong {
    display: block;
    color: var(--text-light);
    font-size: 1.05rem;
    font-weight: 600;
}

.quote-author span {
    color: var(--primary-blue);
    font-size: 0.85rem;
    font-weight: 500;
}

/* --- Werte-Raster (2 bis 4 Spalten) --- */
.value-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 25px;
}

.value-grid.cols-3 {
    grid-template-columns: repeat(3, 1fr);
}

.value-grid.cols-2 {
    grid-template-columns: repeat(2, 1fr);
}

.value-card {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 35px 28px;
    position: relative;
    overflow: hidden;
    transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.value-card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 3px;
    background-color: var(--primary-blue);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.3s ease;
}

.value-card:hover {
    transform: translateY(-5px);
    border-color: var(--primary-blue);
    box-shadow: var(--schatten-kachel);
}

.value-card:hover::before {
    transform: scaleX(1);
}

.value-card h3 {
    font-size: 1.2rem;
    margin: 0 0 12px 0;
    color: var(--text-light);
}

.value-card p {
    color: var(--text-muted);
    font-size: 0.92rem;
    margin: 0;
}

/* --- Kurs-Raster (statt Slider, für die Schulungsübersicht) --- */
.course-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 30px;
}

/* .course-card kommt aus dem Slider-Bereich; im Raster volle Breite */
.course-grid .course-card {
    width: auto;
    flex: 1 1 auto;
}

/* --- Ablauf-Schritte (echte Reihenfolge, deshalb nummeriert) --- */
.step-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    counter-reset: step;
    max-width: 820px;
    margin: 0 auto;
}

.step {
    display: grid;
    grid-template-columns: 70px 1fr;
    gap: 25px;
    padding: 30px 0;
    border-bottom: 1px solid var(--border-color);
    align-items: start;
}

.step:last-child {
    border-bottom: none;
}

.step::before {
    counter-increment: step;
    content: counter(step, decimal-leading-zero);
    font-family: var(--font-mono);
    font-size: 1.5rem;
    color: var(--primary-blue);
    line-height: 1.2;
}

.step h3 {
    margin: 0 0 8px 0;
    font-size: 1.2rem;
    color: var(--text-light);
}

.step p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.98rem;
}

/* --- Gegenüberstellung: vorher / nachher --- */
.compare-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 30px;
}

.compare-col {
    border-radius: 10px;
    padding: 35px;
    border: 1px solid var(--border-color);
    background-color: var(--bg-card);
}

.compare-col.highlight {
    border-color: var(--primary-blue);
}

.compare-col h3 {
    margin: 0 0 20px 0;
    font-size: 1.2rem;
}

.compare-col.highlight h3 {
    color: var(--primary-blue);
}

.compare-col ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.compare-col li {
    color: var(--text-muted);
    font-size: 0.95rem;
    padding-left: 24px;
    margin-bottom: 14px;
    position: relative;
}

.compare-col li:last-child {
    margin-bottom: 0;
}

.compare-col li::before {
    content: "–";
    position: absolute;
    left: 0;
    color: var(--text-zart);
}

.compare-col.highlight li::before {
    content: "+";
    color: var(--primary-blue);
    font-weight: 600;
}

/* --- Angebots-/Paketkarten --- */
.join-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 30px;
}

.join-card {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 40px 35px;
    display: flex;
    flex-direction: column;
    transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.join-card:hover {
    transform: translateY(-5px);
    border-color: var(--primary-blue);
    box-shadow: var(--schatten-karte);
}

.join-card h3 {
    font-size: 1.5rem;
    margin: 0 0 25px 0;
    color: var(--text-light);
}

.join-card ul {
    list-style: none;
    padding: 0;
    margin: 0 0 35px 0;
    flex-grow: 1;
}

.join-card ul li {
    color: var(--text-muted);
    font-size: 0.95rem;
    padding-left: 26px;
    margin-bottom: 14px;
    position: relative;
}

.join-card ul li::before {
    content: "+";
    position: absolute;
    left: 0;
    top: -2px;
    color: var(--primary-blue);
    font-size: 1.25rem;
    font-weight: 600;
    line-height: 1.4;
}

.join-card .card-btn {
    background-color: transparent;
    border: 1px solid var(--primary-blue);
    color: var(--primary-blue);
    padding: 12px 24px;
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    text-align: center;
    transition: all 0.3s ease;
    display: block;
    margin-top: auto;
}

.join-card .card-btn:hover {
    background-color: var(--primary-blue);
    color: white;
    box-shadow: var(--glut-blau);
}

/* --- Zertifikats-Band --- */
.cert-container {
    max-width: 900px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 50px;
    justify-content: center;
    flex-wrap: wrap;
}

.cert-container img {
    height: 140px;
    width: auto;
    object-fit: contain;
    flex-shrink: 0;
}

.cert-copy h3 {
    margin: 0 0 10px 0;
    font-size: 1.4rem;
    color: var(--text-light);
}

.cert-copy p {
    margin: 0;
    color: var(--text-muted);
    font-size: 1rem;
    max-width: 480px;
}

/* --- Abschluss-CTA --- */
.cta-box {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 60px 40px;
    text-align: center;
}

.cta-box h2 {
    font-size: 2rem;
    margin: 0 0 15px 0;
}

.cta-box p {
    color: var(--text-muted);
    font-size: 1.05rem;
    margin: 0 0 35px 0;
    max-width: 620px;
    margin-left: auto;
    margin-right: auto;
}

.cta-buttons {
    display: flex;
    gap: 20px;
    justify-content: center;
    flex-wrap: wrap;
}

/* Tastatur-Fokus sichtbar halten */
a:focus-visible,
button:focus-visible,
input:focus-visible {
    outline: 2px solid var(--primary-blue);
    outline-offset: 3px;
}

/* Der Slider ist per tabindex fokussierbar, war als div aber von der Regel
   oben nicht erfasst: man landete beim Tabben darauf, ohne es zu sehen, und
   die Pfeiltasten wirkten dadurch wie kaputt. Der Rahmen liegt innen
   (negativer Offset), sonst schneidet ihn der Ueberlauf des Sliders ab. */
.slider-wrapper:focus-visible {
    outline: 2px solid var(--primary-blue);
    outline-offset: -2px;
}

/* Media Queries für Mobilgeräte */

/* Navigation: Burger-Menü ab 1150px, da der Header Logo + 6 Links + CTA trägt.
   sta.js liest die Sichtbarkeit des Burgers aus dem CSS aus – dieser Wert kann
   also frei geändert werden, ohne das Skript anzupassen. */
@media (max-width: 1150px) {
    .navbar {
        padding: 15px 20px;
        display: flex;
        justify-content: space-between;
    }

    .navbar ul {
        display: flex;
        flex-direction: column;
        position: absolute;
        top: 100%;
        left: 0;
        width: 100%;
        background: var(--bg-deep);
        padding: 20px 0;
        text-align: center;
        opacity: 0;
        visibility: hidden;
        border-bottom: 1px solid var(--border-color);
        transition: opacity 0.3s ease, visibility 0.3s ease;
    }

    .navbar ul.active {
        opacity: 1;
        visibility: visible;
    }

    .navbar ul li {
        margin: 15px 0;
    }

    .menu-toggle {
        display: flex;
    }

    .menu-toggle.active span:nth-child(1) {
        transform: rotate(45deg) translate(5px, 6px);
    }

    .menu-toggle.active span:nth-child(2) {
        opacity: 0;
    }

    .menu-toggle.active span:nth-child(3) {
        transform: rotate(-45deg) translate(5px, -6px);
    }

    .navbar>.nav-cta {
        display: none;
    }

    /* Der Sprachumschalter bleibt sichtbar, auch wenn das Menue zuklappt: er
       ist klein genug und waere im Burger-Menue erst nach zwei Klicks
       erreichbar. Er rueckt nur naeher an den Burger. */
    .lang-switch {
        margin-left: auto;
        margin-right: 14px;
    }

    .mobile-auth-section.mobile-only {
        display: block;
    }
}

@media (max-width: 992px) {
    .footer-container {
        grid-template-columns: 1fr 1fr;
        gap: 40px;
    }

    h1.brand-title {
        font-size: 3.2rem;
    }

    .faq-container,
    .info-row {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 768px) {
    
    h1.brand-title {
        font-size: 2.4rem;
    }

    .hero h2 {
        font-size: 1.3rem;
    }

    .hero h3 {
        font-size: 1.05rem;
    }

    .hero-buttons {
        flex-direction: column;
        gap: 12px;
    }

    .footer-container {
        grid-template-columns: 1fr;
        gap: 40px;
    }

    .footer-bottom {
        flex-direction: column;
        text-align: center;
    }

    .slider-section,
    .testimonials-section {
        padding: 60px 0 60px 20px;
    }

    /* Auf Touch stehen die Pfeile dauerhaft sichtbar ueber den Karten. Bei
       290px Kartenbreite verdecken 48px zu viel Inhalt. */
    .slider-nav {
        width: 40px;
        height: 40px;
    }

    .slider-nav svg {
        width: 18px;
        height: 18px;
    }

    .course-card,
    .testimonial-card {
        width: 290px;
    }

    /* Karten sind hier 290px breit, also 145px als Haelfte. Die zusaetzlichen
       10px gleichen das padding-left von 20px der Sektion aus: 50% bezieht sich
       auf den dadurch nach rechts versetzten Container, gemeint ist aber die
       Mitte des Bildschirms. */
    .slider-wrapper {
        --slider-inset: max(10px, calc(50% - 155px));
    }

    .testimonial-card {
        padding-top: 0;
    }

    .testimonial-img-wrapper {
        width: 190px;
        height: 190px;
        margin-top: -125px;
    }

    .testimonial-slider-wrapper {
        padding-top: 140px;
    }

    /* Hier stehen nur noch die Groessen. Das Laufband selbst (nowrap, Ueberlauf,
       Ziehen) haengt an .is-marquee weiter oben und gilt in jeder Breite.
       Vorher galten die Desktop-Werte bis aufs Telefon durch: bei 40px
       Sektionsabstand blieben auf 375px nur 295px nutzbare Breite, ein Logo ist
       aber bis zu 160px breit und der Abstand 50px - es passte nie ein zweites
       Logo in die Zeile, alle fuenf standen untereinander und die Sektion war
       rund 610px hoch. */
    .partner-section {
        padding: 50px 0;
    }

    .partner-grid {
        gap: 30px;
    }

    .partner-grid img {
        max-height: 40px;
        max-width: 120px;
    }
}
/* --- Media Queries für die Unterseiten-Komponenten --- */
@media (max-width: 992px) {

    .split,
    .split.even {
        grid-template-columns: 1fr;
        gap: 45px;
    }

    .value-grid,
    .value-grid.cols-3 {
        grid-template-columns: repeat(2, 1fr);
    }

    .course-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .join-grid {
        grid-template-columns: 1fr;
    }

    .compare-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 768px) {

    .hero.hero-sub {
        height: auto;
        min-height: 0;
        padding: 140px 0 90px 0;
    }

    .hero.hero-sub .scroll-down {
        display: none;
    }

    .page-section {
        padding: 70px 20px;
    }

    .band-dark .page-section {
        padding-top: 70px;
        padding-bottom: 70px;
    }

    .value-grid,
    .value-grid.cols-3,
    .value-grid.cols-2,
    .course-grid {
        grid-template-columns: 1fr;
    }

    .quote-block blockquote {
        font-size: 1.3rem;
    }

    .cert-container {
        flex-direction: column;
        text-align: center;
        gap: 30px;
    }

    .step {
        grid-template-columns: 50px 1fr;
        gap: 15px;
    }

    .cta-box {
        padding: 45px 25px;
    }
}

/* Reduzierte Bewegung respektieren */
@media (prefers-reduced-motion: reduce) {
    html {
    scroll-behavior: auto;
    }

    .hero .container>*,
    .scroll-down {
        animation: none;
    }

    .reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

    /* Die Pille springt ohne Verformung auf den aktiven Punkt. Sie bleibt
       sichtbar - sie ist eine Positionsanzeige, keine Zierde. */
    .pagination-dot {
        transition: none;
    }

    /* Das Skelett bleibt als ruhige Fläche stehen, nur der Lauf hört auf.
       Es ist eine Auskunft ("lädt noch"), keine Zierde - wer es ausblendet,
       nimmt sie weg. */
    .sta-laedt {
        animation: none;
        background-image: none;
    }
}

/* --- Rechtliche Links in der Fußzeile --- */
.footer-legal-links {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 22px;
    margin-top: 30px;
}

.footer-legal-links a {
    color: rgba(var(--text-basis), 0.45);
    text-decoration: none;
    font-size: 0.85rem;
    transition: color 0.2s;
}

.footer-legal-links a:hover {
    color: var(--primary-blue);
}

/* --- Footer mobil anpassung --- */
@media (max-width: 768px) {
    .footer-container {
        grid-template-columns: 1fr 1fr;
        gap: 36px 24px;
    }

    .footer-brand,
    .newsletter-box {
        grid-column: 1 / -1;
    }
    
    
}

@media (max-width: 992px) {
    .newsletter-box { order: 3; }
    .footer-links   { order: 1; }
    .footer-brand   { order: 2; }
    .footer-brand .cert-seal {
        display: flex;
        align-items: center;
        gap: 14px;
        flex-basis: 100%;
    }

    .footer-brand .cert-seal img {
        height: 64px;
    }

    .footer-brand .cert-seal p {
        margin: 0;
    }

    .footer-brand {
        display: flex;
        align-items: center;
        gap: 14px;
        flex-wrap: wrap;   /* Siegel-Zeile darf drunter rutschen */
    }

    .footer-brand > p {
        flex: 1;
        min-width: 140px;
        margin: 0;
    }

}

/* --- Preiskarten --- */
.join-card.featured {
    border-color: var(--primary-blue);
    box-shadow: 0 0 0 1px var(--primary-blue), var(--schatten-hoch);
}

.join-card .badge {
    display: inline-block;
    align-self: flex-start;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--primary-blue);
    border: 1px solid var(--primary-blue);
    border-radius: 4px;
    padding: 4px 10px;
    margin-bottom: 18px;
}

.join-card .price {
    font-family: var(--font-mono);
    font-size: 2.4rem;
    color: var(--text-light);
    line-height: 1.1;
    margin: 0 0 4px 0;
}

.join-card .price-note {
    color: var(--text-muted);
    font-size: 0.85rem;
    margin: 0 0 28px 0;
}

/* --- Preistabelle für Einzelkurse --- */
.price-table {
    width: 100%;
    border-collapse: collapse;
    /* Rahmen, Fläche und Radius sitzen an der Hülle, nicht hier.

       Grund: border-collapse und border-radius vertragen sich nicht. Eine
       Tabelle mit zusammengefassten Rändern ignoriert den Radius, und
       overflow: hidden greift an einem <table> auch nicht. Die Ecken waren
       deshalb eckig, obwohl hier 10px standen - man sah es nur, wenn man
       hinsah. Ein <div> darum kann beides. */
    table-layout: auto;
}

.price-table th {
    text-align: left;
    padding: 18px 25px;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border-color);
}

.price-table td {
    padding: 20px 25px;
    border-bottom: 1px solid var(--linie-zart);
    color: var(--text-muted);
    font-size: 0.95rem;
    vertical-align: middle;
}

.price-table tr:last-child td {
    border-bottom: none;
}

.price-table tbody tr {
    transition: background-color 0.2s;
}

.price-table tbody tr:hover {
    background-color: var(--flaeche-zart);
}

.price-table .course-name {
    color: var(--text-light);
    font-weight: 500;
}

/* tabular-nums bleibt zusätzlich stehen: greift der Monospace-Fallback nicht,
   fluchtet die Spalte trotzdem. */
.price-table .amount {
    color: var(--text-light);
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

.price-table td.right {
    text-align: right;
}

/* --- Vergleichstabellen ---

   Auf /abo stehen zwei Tabellen, die zwei Angebote nebeneinanderstellen:
   Präsenzseminar gegen Abo, Einzelpreis gegen Abo. Dort war die eine
   Wertspalte links und die andere rechts ausgerichtet - die beiden Zahlen
   klebten an den Aussenkanten und wanderten mit jeder Zeile auseinander.
   Vergleichen konnte man sie so nicht; das Auge braucht eine gemeinsame
   Kante.

   Deshalb hier: die Beschreibung links, ALLE Werte rechtsbündig. Bei Zahlen
   ist das ohnehin die richtige Ausrichtung - Einer unter Einer, Zehner unter
   Zehner. Zusammen mit tabular-nums fluchtet die Spalte dann wirklich.

   Der Zusatz steht als eigene Klasse im HTML, weil die Preistabelle auf
   /preise anders gebaut ist: dort steht in der letzten Spalte ein Knopf und
   kein Wert. */
.price-table.vergleich th:not(:first-child),
.price-table.vergleich td:not(:first-child) {
    text-align: right;
}

/* Die Hülle trägt das Aussehen: dieselbe Fläche, derselbe Rahmen und
   derselbe Radius wie bei jeder anderen Tafel auf der Website.

   Und KEIN overflow-x: auto mehr. Seitwärts schieben ist auf einem Telefon
   eine Bewegung, die niemand von sich aus macht - was rechts steht, wird
   schlicht nicht gelesen. Stattdessen brechen die Zellen um; die Spalten
   werden schmaler, die Zeilen höher. Das ist auf einer Preisliste die
   richtige Richtung: nach unten scrollt man ohnehin. */
.price-table-wrap {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    overflow: hidden;
}

/* --- Kontaktangaben --- */
.contact-card {
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 35px;
}

.contact-card + .contact-card {
    margin-top: 20px;
}

.contact-card h3 {
    margin: 0 0 18px 0;
    font-size: 1.15rem;
    color: var(--primary-blue);
}

.contact-card p {
    margin: 0 0 8px 0;
    color: var(--text-muted);
    font-size: 0.98rem;
}

.contact-card p:last-child {
    margin-bottom: 0;
}

.contact-card a {
    color: var(--text-light);
    text-decoration: none;
    border-bottom: 1px solid rgba(81, 164, 222, 0.5);
    transition: color 0.2s, border-color 0.2s;
}

.contact-card a:hover {
    color: var(--primary-blue);
    border-color: var(--primary-blue);
}

.hours-row {
    display: flex;
    justify-content: space-between;
    gap: 20px;
    padding: 9px 0;
    border-bottom: 1px solid var(--linie-zart);
    color: var(--text-muted);
    font-size: 0.95rem;
}

.hours-row:last-child {
    border-bottom: none;
}

.hours-row span:last-child {
    color: var(--text-light);
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* --- Offene Stellen --- */
.job-list {
    display: flex;
    flex-direction: column;
    gap: 15px;
}

.job {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 25px;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 28px 32px;
    transition: border-color 0.3s ease, transform 0.3s ease;
}

.job:hover {
    border-color: var(--primary-blue);
    transform: translateX(5px);
}

.job h3 {
    margin: 0 0 5px 0;
    font-size: 1.15rem;
    color: var(--text-light);
}

.job p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.9rem;
}

.job .course-btn {
    flex-shrink: 0;
}

/* Hinweis, wenn keine Stellen offen sind */
.empty-note {
    background-color: var(--bg-card);
    border: 1px dashed var(--border-color);
    border-radius: 10px;
    padding: 45px 35px;
    text-align: center;
    color: var(--text-muted);
}

.empty-note strong {
    display: block;
    color: var(--text-light);
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 10px;
}

/* --- Rechtstexte (Impressum, Datenschutz, AGB) ---
   Lange Fliesstexte in einer Spalte, mit vielen Zwischenüberschriften und ohne
   Bildmaterial. Weder .prose (gedacht für die Textspalte neben einem zweiten
   Element) noch .section-head passen dafür. Ausserhalb dieser drei Seiten hat
   die Klasse nichts zu suchen. */
.legal-text {
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1.8;
}

.legal-text h2 {
    color: var(--text-light);
    font-size: 1.5rem;
    margin: 50px 0 18px;
}

.legal-text h3 {
    color: var(--primary-blue);
    font-size: 1.1rem;
    margin: 34px 0 10px;
}

/* Die erste Überschrift schliesst direkt an den Seitentitel an und braucht
   deshalb keinen zusätzlichen Abstand nach oben. */
.legal-text> :first-child {
    margin-top: 0;
}

.legal-text p {
    margin: 0 0 16px;
}

.legal-text a {
    color: var(--primary-blue);
}

.legal-text ul {
    margin: 0 0 16px;
    padding-left: 22px;
}

.legal-text li {
    margin-bottom: 6px;
}

/* Anschrift und Registerangaben. <address> steht im Browser von Haus aus
   kursiv - für eine Postanschrift unpassend. */
.legal-address {
    font-style: normal;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-left: 3px solid var(--primary-blue);
    border-radius: 8px;
    padding: 28px 30px;
    margin: 0 0 22px;
    color: var(--text-light);
}

/* Seiten ohne Hero beginnen direkt unter der festen Navigation. Stand vorher
   als style="padding-top: 180px" auf jeder der drei Rechtsseiten. */
.page-section.no-hero {
    padding-top: 180px;
}

@media (max-width: 768px) {
    .job {
        flex-direction: column;
        align-items: flex-start;
        gap: 18px;
    }

    /* Enger und kleiner, damit drei Spalten ohne Schieben nebeneinander
       passen. Lange Kursnamen brechen dabei um - das ist gewollt: eine
       hohe Zeile liest sich besser als eine, die halb ausserhalb liegt. */
    .price-table th,
    .price-table td {
        padding: 12px 10px;
        font-size: 0.85rem;
    }

    .price-table .course-name {
        overflow-wrap: anywhere;
    }

    .contact-card {
        padding: 28px 22px;
    }
}

/* --- Kategorie-Filter für den Kurskatalog --- */
.filter-tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    margin-bottom: 45px;
}

.filter-tab {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 500;
    padding: 10px 20px;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.25s ease;
}

.filter-tab:hover {
    color: var(--text-light);
    border-color: var(--rand-hell);
}

.filter-tab.active {
    background-color: var(--primary-blue);
    border-color: var(--primary-blue);
    color: #fff;
    box-shadow: var(--glut-blau-zart);
}

.filter-count {
    text-align: center;
    color: var(--text-muted);
    font-size: 0.9rem;
    margin: 0 0 25px 0;
}

/* Karten, die der Filter ausblendet */
.course-card[hidden] {
    display: none;
}

/* Produktschulungen: schlankere Karten ohne Preis */
.product-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 30px;
}

@media (max-width: 992px) {
    .product-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 768px) {
    .product-grid {
        grid-template-columns: 1fr;
    }

    .filter-tabs {
        gap: 8px;
        margin-bottom: 32px;
    }

    .filter-tab {
        font-size: 0.85rem;
        padding: 9px 15px;
    }
}

/* =========================================================
   Kauf-Popup
   Wird komplett von sta.js erzeugt (siehe Block "Kauf-Popup" dort) und zeigt
   die Eckdaten des Kurses, bevor es zum Zahlungsanbieter weitergeht.
   ========================================================= */
.course-modal {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

/* .course-modal steht auf display:flex - ohne diese Regel wuerde das
   hidden-Attribut aus sta.js wirkungslos bleiben. */
.course-modal[hidden] {
    display: none;
}

.course-modal-backdrop {
    position: absolute;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.75);
}

.course-modal-dialog {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 620px;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    box-shadow: var(--schatten-popup);
}

/* Der Schliessknopf.

   font-size und line-height standen hier für das Zeichen &times;. Das trug
   sta.js früher als Text im Knopf – und es sass sichtbar zu hoch, weil ×
   in der Schrift auf der Mathematik-Achse liegt und nicht in der Zeilenmitte.
   Jetzt steckt ein SVG darin, und zentriert wird über Flexbox: die Mitte des
   Kreuzes trifft die Mitte des Kreises, in jeder Schrift und jeder Grösse. */
.course-modal-close {
    position: absolute;
    top: 12px;
    right: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid var(--rand-mittel);
    border-radius: 50%;
    background-color: var(--knopf-zu-bg);
    color: var(--text-light);
    cursor: pointer;
    transition: background-color 0.3s;
}

/* 24px – genau die Breite der viewBox in sta.js. Damit ist eine viewBox-
   Einheit ein Pixel, und die Zahlen im Pfad (5 bis 19) sind unmittelbar die
   Masse auf dem Schirm: 14px Kreuz, 2px Strich, in einem 40px-Kreis.

   Vorher standen hier 18px bei einem Pfad von 7 bis 17 – das ergab ein Kreuz
   von 7,5px. In einem 40px-Knopf verliert sich das. */
.course-modal-kreuz {
    width: 24px;
    height: 24px;
    /* Ohne das trägt das SVG als Inline-Element die Grundlinie der Zeile mit
       sich herum – dieselbe Falle, aus der das × kam. */
    display: block;
}

.course-modal-close:hover {
    background-color: var(--primary-blue);
}

/* Das Bildband oben im Popup.

   Hier stand eine feste Höhe von 220px, und das Bild darin auf object-fit:
   cover. Das heisst: jedes Bild wurde auf ein 620x220-Band zugeschnitten,
   egal welches Format es hatte. Bei einem querformatigen Foto fiel das kaum
   auf, bei allem anderen fehlte oben und unten die Hälfte.

   Jetzt bestimmt das Bild seine Höhe selbst. Das Seitenverhältnis kennt der
   Browser vorher, weil sta.js die echten Masse als width/height-Attribute an
   das <img> schreibt - der Text springt beim Laden also nicht.

   Wer trotzdem ein Band fester Höhe will, trägt sie im Redaktionsbereich bei
   der Kaufkarte ein. Dann greift .feste-hoehe weiter unten. */
.course-modal-media {
    overflow: hidden;
    border-radius: 10px 10px 0 0;
}

.course-modal-media[hidden] {
    display: none;
}

.course-modal-media img {
    width: 100%;
    height: auto;
    display: block;
}

/* =========================================================
   Das Skelett: eine Fläche, solange ein Bild noch nicht da ist

   Zwei Stellen benutzen es, mit derselben Klasse:

   1. Das Kauf-Popup. Es ist EIN Element für alle Kurse – wird nur die Quelle
      gewechselt, malt der Browser weiter das vorige Bild, bis das neue
      geladen ist. Auf /preise und /abo sind das Sekunden, denn dort steht
      kein Kursbild im HTML. Lieber eine Fläche, die sagt „lädt noch", als
      der Kurs, den man vorhin angesehen hat.

   2. Die Bilder mit loading="lazy" in den Kurskarten und bei den Stimmen.
      Deren Kästen haben feste Höhen (240px bzw. 226px) und standen bis jetzt
      leer, bis das Bild eintraf.

   Die Klasse setzt immer sta.js, nie das HTML: eine Fläche, die sich nicht
   mehr abschalten lässt, weil JavaScript ausfällt, wäre schlimmer als ein
   Bild, das etwas später kommt. Und sie kommt verzögert – ein Bild aus dem
   Cache soll gar nichts aufblitzen lassen.

   visibility statt display oder opacity: das Bild bleibt im Layout, seine
   width/height halten den Kasten, nichts springt.
   ========================================================= */
.sta-laedt {
    background-color: var(--flaeche-zart);
    /* Schräg statt waagerecht: der Lauf geht von oben links nach unten
       rechts. Der Winkel ist bewusst flach – siehe die Rechnung unten. */
    background-image: linear-gradient(105deg,
        transparent 0%,
        transparent 35%,
        var(--flaeche-aktiv) 50%,
        transparent 65%,
        transparent 100%);
    /* Eine Kachel, in Pixeln und nicht in Prozent – siehe @keyframes.

       640px ist breiter als jede Fläche, auf der das hier liegt (das Bildband
       im Popup misst 620px). Damit ist immer nur EIN Streifen zu sehen. Mit
       240px lagen im Popup knapp drei nebeneinander, und es sah aus, als
       liefe die Bewegung dreifach.

       Der Winkel hängt daran. Bei einem schrägen Verlauf ist der senkrechte
       Rand einer Kachel nicht durchgehend durchsichtig: oben und unten liegen
       verschiedene Stellen des Verlaufs. Wie weit sie auseinanderliegen:

           H·|cos α| / (B·|sin α| + H·|cos α|)

       mit B = Kachelbreite, H = Höhe der Fläche. Solange das KLEINER ist als
       der durchsichtige Rand (35 %), stösst an der Fuge Durchsichtiges auf
       Durchsichtiges und man sieht nichts. Ein paar Werte:

           240px / 115deg / 620px hoch  ->  55 %   Fuge deutlich sichtbar
           640px / 115deg / 620px hoch  ->  31 %   knapp
           640px / 105deg / 620px hoch  ->  21 %   sicher

       Wer Winkel oder Kachelbreite ändert, rechnet das nach – oder lässt es
       _nicht-hochladen/pruefe-bildskelett.js tun, dort steht die Formel. */
    background-size: 640px 100%;
    background-repeat: repeat;
    /* linear, nicht ease-in-out: eine Bewegung, die am Ende langsamer wird,
       macht aus dem Übergang eine sichtbare Pause. */
    animation: sta-skelett 2s linear infinite;
}

.sta-laedt img {
    visibility: hidden;
}

/* Der Lauf ist nahtlos, und das hängt an drei Dingen zusammen:

   Vorher lag EIN Streifen (background-repeat: no-repeat) auf der Fläche und
   wanderte von -60 % auf 160 %. Am Ende war er rechts draussen, sprang nach
   links und lief neu – der Sprung, den man sah.

   Jetzt ist der Hintergrund gekachelt (repeat). Verschiebt man ihn um GENAU
   eine Kachelbreite, liegt danach jede Kachel dort, wo eben ihre Nachbarin
   lag: das Bild am Ende ist Pixel für Pixel dasselbe wie am Anfang. Es gibt
   keinen Sprung mehr, weil es nichts zurückzusetzen gibt.

   Deshalb steht die Kachelbreite in Pixeln. Prozentwerte in
   background-position beziehen sich auf (Fläche − Bild) und nicht auf die
   Bildbreite; 240px hier und 240px dort sind dagegen dieselbe Strecke.

   Wer die 640px ändert, ändert beide Stellen. */
@keyframes sta-skelett {
    from { background-position: 0 0; }
    to   { background-position: 640px 0; }
}

/* Feste Höhe aus dem Backend. Die Höhe selbst setzt sta.js als style, weil
   sie aus den Daten kommt; hier steht nur, was daraus folgt: Zuschneiden.
   Das ist kein Versehen, sondern der Zweck einer festen Höhe - wer ein Band
   bestellt, bekommt einen Ausschnitt. */
.course-modal-media.feste-hoehe img {
    height: 100%;
    object-fit: cover;
}

.course-modal-body {
    padding: 30px;
}

.course-modal-title {
    font-size: 1.5rem;
    margin: 0 0 15px 0;
}

/* Die Überschrift lässt sich im Redaktions-Backend abschalten. Sie
   verschwindet dann für das Auge, bleibt aber im Dokument stehen: das Popup
   verweist mit aria-labelledby darauf und wäre sonst für Vorleseprogramme
   ein Fenster ohne Namen.

   Die 1px-Bauart statt display:none ist Absicht – Ausgeblendetes im Sinne von
   display:none lesen Vorleseprogramme ebenfalls nicht vor. */
.course-modal-nur-vorlesen {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.course-modal-text {
    color: var(--text-muted);
    margin: 0 0 20px 0;
}

/* Schrift, Gewicht und Farbe wie auf der Kurskarte (.course-price), nur eine
   Spur grösser: im Dialog trägt der Preis mehr Gewicht als auf einer Karte in
   einer Reihe von sechzehn.

   Bewusst nicht --font-mono, obwohl weiter oben "JetBrains Mono nur für
   Preise" steht: der Preis auf der Kurskarte ist die Fassung, die der Besucher
   direkt davor gesehen hat, und im Popup soll dieselbe Zahl nicht plötzlich
   anders aussehen. */
.course-modal-price {
    font-weight: 600;
    font-size: 1.15rem;
    color: var(--text-light);
    margin: 0 0 25px 0;
}

.course-modal-price[hidden] {
    display: none;
}

.course-modal-price small {
    font-size: 0.8em;
    font-weight: 400;
    color: var(--text-muted);
}

/* ---------- Video ----------
   Bis zum Klick steht hier ein eigenes Vorschaubild aus assets/ – kein Bild
   von Googles Servern. Erst der Klick setzt das iframe ein. Warum das so sein
   muss, steht in sta.js im Block "Kauf-Popup". */
.course-modal-video {
    position: relative;
    margin: 0 0 20px 0;
    border-radius: 8px;
    overflow: hidden;
    background-color: #000;
    aspect-ratio: 16 / 9;
}

.course-modal-video[hidden] {
    display: none;
}

.course-modal-video iframe {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

.course-modal-play {
    display: block;
    position: relative;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.course-modal-play img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Das Dreieck ist reines CSS – ein weiteres Bild zu laden, nur um ein Dreieck
   zu zeigen, wäre eine Anfrage zu viel. */
.course-modal-play::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 68px;
    height: 68px;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background-color: rgba(0, 0, 0, 0.6);
    border: 2px solid rgba(255, 255, 255, 0.85);
    transition: background-color 0.3s;
}

.course-modal-play::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-40%, -50%);
    border-style: solid;
    border-width: 13px 0 13px 22px;
    border-color: transparent transparent transparent #fff;
}

.course-modal-play:hover::before,
.course-modal-play:focus-visible::before {
    background-color: var(--primary-blue);
}

.course-modal-play-label {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 10px;
    color: #fff;
    font-size: 0.85rem;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9);
}

.course-modal-cta {
    display: block;
    text-align: center;
}

.course-modal-note {
    color: var(--text-muted);
    font-size: 0.8rem;
    margin: 15px 0 0 0;
    text-align: center;
}

@media (max-width: 768px) {
    .course-modal-media {
        height: 160px;
    }

    .course-modal-body {
        padding: 25px 20px;
    }

    .course-modal-title {
        font-size: 1.25rem;
    }
}

/* =========================================================
   Landingpage /fuer-betriebe

   Stand vorher als <style>-Block in fuer-betriebe.html – die einzige Seite
   mit eigenem CSS. Jetzt hier, damit es genau ein Stylesheet gibt: sonst
   sucht man Regeln an zwei Orten, und die zweite Stelle wird beim Aufräumen
   regelmässig übersehen. Die Klassen sind bewusst mit .hero-lp bzw. eigenen
   Namen abgegrenzt und wirken nur auf dieser Seite.
   Die Formularfelder stehen NICHT hier, sondern zentral unter
   "Formularfelder" – sie teilen sich das Aussehen mit dem Newsletter.
   ========================================================= */

/* Kompakterer Hero: CTA und Vertrauensleiste bleiben above the fold.

   box-sizing ist hier keine Kosmetik. Ohne die Zeile gilt min-height für den
   Inhaltskasten, und die 230 px Innenabstand kommen OBEN DRAUF: aus 88vh werden
   88vh + 230px, also auf jedem Bildschirm unter rund 1900 px Höhe mehr als eine
   Sichtfläche. Der Scroll-Pfeil sitzt am unteren Rand des Heros und lag damit
   grundsätzlich unter der Bildschirmkante. */
.hero.hero-lp {
    height: auto;
    min-height: 88vh;
    padding: 140px 0 90px;
    box-sizing: border-box;
}

/* Die Überschrift ist ein ganzer Satz statt eines Markennamens und braucht
   deshalb weniger Punktgrösse als der Standard-Hero. Stand vorher als
   style="font-size: 3.2rem" direkt im <h1> – die einzige Inline-Schriftgrösse
   der Website. */
.hero.hero-lp .brand-title {
    font-size: 3.2rem;
}

.hero.hero-lp h2 {
    max-width: 780px;
    margin-left: auto;
    margin-right: auto;
}

/* Vertrauensleiste im Hero */
.trust-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 14px 28px;
    margin-top: 40px;
    animation-delay: 0.9s;
}

.trust-item {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--text-muted);
    font-size: 0.88rem;
    font-weight: 500;
}

.trust-item img {
    height: 44px;
    width: auto;
    display: block;
}

.trust-item .tick {
    color: var(--accent-bright);
    font-weight: 700;
}

/* Risiko-Abbau unter den CTAs */
.cta-microcopy {
    margin-top: 18px;
    font-size: 0.85rem;
    color: var(--text-muted);
    animation-delay: 0.8s;
}

/* Terminsektion */
.booking-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px;
    align-items: start;
}

/* Grundform steht zentral bei .form-card – hier nur, was die Terminkarten
   davon unterscheidet. */
.booking-card.calendar {
    border-color: var(--primary-blue);
}

.booking-card h3 {
    margin: 0 0 8px;
    font-size: 1.3rem;
}

.booking-card .sub {
    color: var(--text-muted);
    font-size: 0.92rem;
    margin: 0 0 25px;
}

/* Der Buchungsknopf füllt die Karte. Ein Knopf, der nur halb so breit ist wie
   die Karte darüber, sieht aus wie eine Nebensache – er ist aber das Ziel der
   ganzen Seite. */
.booking-link {
    display: block;
    text-align: center;
}

.booking-link + .form-legal {
    margin-top: 12px;
}

.phone-line {
    margin-top: 22px;
    padding-top: 22px;
    border-top: 1px solid var(--border-color);
    font-size: 0.92rem;
    color: var(--text-muted);
}

.phone-line a {
    color: var(--primary-blue);
    font-weight: 600;
    text-decoration: none;
}

/* Kalender-Embed füllt die Karte */
.meetings-iframe-container {
    min-height: 560px;
}

/* Ergebniszeile beim Testimonial */
.result-stats {
    display: flex;
    gap: 35px;
    flex-wrap: wrap;
    margin-top: 30px;
}

.result-stat strong {
    display: block;
    font-family: var(--font-mono);
    font-size: 1.6rem;
    color: var(--primary-blue);
}

.result-stat span {
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* Sticky CTA auf Mobile */
.sticky-cta {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 900;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: var(--bg-deep-glas);
    border-top: 1px solid var(--border-color);
    /* Ohne den Zwilling bleibt die Leiste in Safari unmattiert - und der Text
       darunter scheint durch die halbdurchsichtige Fläche. Ausgerechnet hier
       faellt das auf: die Trichterseiten werden fast nur auf dem Handy
       geoeffnet, und dort ist Safari der Browser. */
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}

.sticky-cta a {
    display: block;
    text-align: center;
}

@media (max-width: 900px) {
    .booking-grid {
        grid-template-columns: 1fr;
    }
}

/* Sticky CTA synchron zum Burger-Menü: sobald der Nav-CTA verschwindet */
@media (max-width: 1150px) {
    .sticky-cta {
        display: block;
    }

    /* Nur auf der Landingpage: sonst schöbe die Leiste auf jeder Seite den
       Footer hoch, obwohl es dort gar keine Leiste gibt. */
    body.has-sticky-cta {
        padding-bottom: 80px;
    }
}

/* ---------- Flache Fenster ----------
   Anders als die übrigen Heros hat dieser keine feste Höhe: er wächst mit
   Überschrift, Zweizeiler, Knöpfen, Microcopy und Vertrauensleiste. Auf einem
   Laptop – erst recht bei 125 % Anzeigeskalierung – wird er dadurch höher als
   die Sichtfläche. Gemessen bei 664 px Sichthöhe: Hero 814 px, der Scroll-Pfeil
   also 120 px unterhalb der Bildschirmkante und die Vertrauensleiste schon
   angeschnitten.

   Deshalb greift ab hier nicht die Fensterbreite, sondern die Fensterhöhe:
   Abstände und Schriftgrade schrumpfen so weit, dass Inhalt UND Pfeil in die
   Sichtfläche passen. Auf hohen Bildschirmen bleibt alles wie gehabt.
   Wer hier Werte ändert, misst danach nach - der Pfeil sitzt am unteren Rand
   des Heros, nicht am unteren Rand des Fensters. */
@media (max-height: 800px) {
    .hero.hero-lp {
        padding: 115px 0 65px;
    }

    .hero.hero-lp .brand-title {
        font-size: 2.7rem;
    }

    .hero.hero-lp h2 {
        font-size: 1.5rem;
        max-width: 720px;
    }

    .hero.hero-lp .trust-row {
        margin-top: 28px;
    }

    .hero.hero-lp .trust-item img {
        height: 36px;
    }
}

@media (max-width: 768px) {
    .hero.hero-lp {
        min-height: 0;
        padding: 120px 0 70px;
    }

    .trust-item img {
        height: 36px;
    }
}

/* =========================================================
   404 – Seite nicht gefunden

   Steht bewusst fuer sich: keine Navigation, keine Fusszeile, wenige
   Kilobyte. Wer hier landet, hat sich verlaufen und will einen Weg zurueck,
   keine zweite Seite zum Durchsuchen.

   Die Seite laedt kein sta.js – auf einer Fehlerseite gibt es nichts zu
   filtern, zu schieben oder abzuschicken.
   ========================================================= */

.seite-fehler {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
}

.fehler-inhalt {
    max-width: 560px;
    text-align: center;
}

.fehler-logo {
    display: inline-block;
    margin-bottom: 40px;
}

.fehler-logo img {
    width: 150px;
    height: auto;
    display: block;
}

/* Gross, aber nicht schreiend: die Zahl ist Zierrat, die Ueberschrift
   darunter sagt, was los ist. Deshalb aria-hidden im HTML – ein
   Screenreader liest sonst "vierhundertvier" ohne jeden Nutzen. */
.fehler-nummer {
    font-family: var(--font-heading);
    font-size: clamp(5rem, 18vw, 9rem);
    line-height: 1;
    margin: 0;
    color: var(--primary-blue);
    opacity: 0.25;
    letter-spacing: 0.02em;
}

.seite-fehler h1 {
    font-family: var(--font-heading);
    font-size: clamp(1.6rem, 5vw, 2.4rem);
    margin: -0.2em 0 18px;
    color: var(--text-light);
}

.fehler-text {
    color: var(--text-muted);
    margin: 0 0 32px;
}

.fehler-knoepfe {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 14px;
    margin-bottom: 44px;
}

.fehler-englisch,
.fehler-hilfe {
    color: var(--text-muted);
    font-size: 0.9rem;
    margin: 0 0 14px;
}

.fehler-englisch {
    padding-top: 22px;
    border-top: 1px solid var(--border-color);
}

.fehler-englisch a,
.fehler-hilfe a {
    color: var(--primary-blue);
}

@media (max-width: 480px) {
    .fehler-knoepfe .btn {
        width: 100%;
    }
}

/* Der zweite Weg aus einer Preiskarte – von der Abo-Karte auf /abo.

   Ein eigener Kasten, kein Nachsatz. Wer vor dem Kauf alles nachrechnen will,
   klickt nicht auf ein Versprechen, sondern auf ein Inhaltsverzeichnis:
   deshalb zwei Zeilen. Oben, wohin es geht; darunter, was dort steht.

   Er hat dieselbe Größe wie der Knopf darüber, aber eine gefüllte Fläche
   statt einer blauen Kontur. Gleiches Gewicht, andere Aufgabe – der eine
   führt zum Kauf, der andere zu den Zahlen. Als kleingedruckte Zeile las es
   sich wie ein Haftungsausschluss und wurde entsprechend übersehen. */
.karten-verweis {
    display: block;
    margin-top: 10px;
    padding: 14px 20px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background-color: var(--flaeche-zart);
    text-decoration: none;
    text-align: center;
    transition: border-color 0.3s ease, background-color 0.3s ease, transform 0.3s ease;
}

.karten-verweis:hover,
.karten-verweis:focus-visible {
    border-color: var(--primary-blue);
    background-color: var(--flaeche-aktiv);
    transform: translateY(-2px);
}

.karten-verweis-titel {
    display: block;
    color: var(--primary-blue);
    font-weight: 600;
    font-size: 0.95rem;
}

/* Der Pfeil steht in CSS und nicht im Text – so bleibt er aus den Daten
   heraus: im Backend steht der Satz ohne Zeichensalat, und keine Übersetzung
   kann ihn verlieren.

   Davor ein geschütztes Leerzeichen. Ohne das rutscht der Pfeil bei schmalen
   Karten allein in die nächste Zeile und steht dort als Waise. */
.karten-verweis-titel::after {
    content: "\00a0\2192";
}

.karten-verweis-inhalt {
    display: block;
    margin-top: 5px;
    color: var(--text-muted);
    font-size: 0.8rem;
    line-height: 1.45;
}

/* =========================================================
   Trichterseiten: /mitarbeiter-gewinnen und /onboarding-checkliste

   Beide sind Zielseite eines QR-Codes von der letzten Vortragsfolie. Wer
   hier landet, sitzt im Saal und will die Unterlagen aufs Handy – deshalb
   kein Menü, kein Video, ein Knopf.

   Sie standen als Entwürfe mit eigenem <style>-Block da. Jetzt hier, aus
   demselben Grund wie /fuer-betriebe weiter oben: es gibt genau ein
   Stylesheet. Zwei Orte heissen, dass beim Aufräumen der zweite übersehen
   wird – und bei diesen beiden Seiten war es schlimmer, weil .dl-card in
   beiden Dateien Zeile für Zeile doppelt stand.

   Gemeinsam ist beiden alles ausser dem Herzstück: die Titelfolie (.folie,
   Mitarbeiter gewinnen) und die Checklisten-Vorschau (.check-vorschau,
   Onboarding).
   ========================================================= */

/* ---------- Hero ohne Video ----------

   Kein Film. Wer einen QR-Code scannt, hängt am Messe-WLAN, und 8 MB Video
   sind dort keine Sekunde, sondern eine halbe Minute. Statt dessen die
   Fläche aus --trichter-flaeche.

   Masse und box-sizing wie beim Hero von /fuer-betriebe – einschliesslich
   des Fallstricks, der dort im Kommentar steht: ohne box-sizing gilt
   min-height für den Inhaltskasten, und der Innenabstand kommt oben drauf.
   140px oben halten die feste Navileiste frei (20 + 45 + 20 = 85px) und
   lassen darunter Luft; 90px unten sind der Abstand, den jede Seite dieser
   Website zwischen Hero und erstem Abschnitt hat.

   78vh statt der 88vh von /fuer-betriebe: die Oberkante der Download-Karte
   soll auf den meisten Bildschirmen noch hereinragen. Die Seite hat genau
   ein Ziel, und das darf nicht komplett unter der Kante liegen. */
.funnel-hero {
    min-height: 78vh;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 140px 24px 90px;
    background: var(--trichter-flaeche);
}

/* ---------- Scroll-Pfeil: weg, sobald gescrollt wird ----------

   Anders als auf den übrigen Seiten liegt hier direkt unter dem Pfeil die
   Download-Karte – der Hero ist nur 78vh hoch, damit ihre Oberkante noch
   hereinragt (siehe oben). Der Pfeil hat seine Arbeit getan, sobald jemand
   scrollt, und verstellt danach nur noch den Blick auf das eine Ziel der Seite.

   Kein eigener Auslöser: die Klasse .scrolled setzt sta.js ohnehin auf jeder
   Seite an die Navileiste, sobald mehr als 50px gescrollt sind. Was für die
   Leiste gilt, gilt für den Pfeil – es gibt keinen Grund, dieselbe
   Scrollposition ein zweites Mal zu messen.

   Die Leiste ist im Markup Geschwister von <main>, deshalb reicht der
   Geschwister-Kombinator und es braucht weder :has() noch scrollgesteuerte
   Animationen. Beides hat einen Browser-Boden, der Kombinator hat keinen: wo
   das Skript läuft, greift auch diese Regel.

   .funnel-hero im Selektor hält die 18 anderen Seiten heraus, die denselben
   Pfeil im Markup haben. Dort scrollt er wie bisher mit dem 100vh-Hero aus
   dem Bild und soll sich nicht anders verhalten. */
.navbar.scrolled ~ main .funnel-hero .scroll-down {
    opacity: 0;
    /* visibility hinterher, damit der unsichtbare Pfeil keine Klicks mehr
       abfängt, die der Download-Karte gelten. Die 0,3s Verzögerung lassen
       ihn erst ausblenden und dann verschwinden – ohne sie springt er weg,
       bevor man das Ausblenden sieht. Für den Rückweg steht oben bei
       .scroll-down die Überblendung ohne Verzögerung: nach oben gescrollt
       ist er sofort wieder da und blendet ein. */
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0s linear 0.3s;
}

/* Ab hier zeigt sich die .sticky-cta am unteren Rand (weiter oben, bei der
   Landingpage) – fest ans Fenster geheftet, mit z-index 900. Der Pfeil steht
   an derselben Kante und hat z-index 2: die Leiste liegt über ihm und
   schneidet ihn an.

   Derselbe Haltepunkt wie die Leiste, nicht die 768px des Handy-Blocks weiter
   unten. Der Konflikt beginnt nicht, wenn der Hero schmal wird, sondern wenn
   die Leiste erscheint – und das ist bei 1150px. Wer den einen Wert ändert,
   ändert den anderen mit.

   Weg statt versetzt: die Leiste nennt das Ziel beim Namen ("Checkliste
   herunterladen"). Ein Pfeil daneben sagt dasselbe schwächer und zieht den
   Blick von der Leiste ab. */
@media (max-width: 1150px) {
    .funnel-hero .scroll-down {
        display: none;
    }
}

.funnel-hero h1 {
    font-family: var(--font-heading);
    font-size: clamp(2.4rem, 8vw, 4.2rem);
    line-height: 1.05;
    text-transform: uppercase;
    color: var(--text-light);
    margin: 0 0 15px;
}

/* Die Jahreszahl trägt die Marke. Die Glut ist ein Token und in der hellen
   Fassung auf none gestellt – wie überall sonst auch. */
.funnel-hero h1 .jahr {
    color: var(--primary-blue);
    text-shadow: var(--brand-glow-schatten);
}

.funnel-hero .vorspann {
    color: var(--text-muted);
    font-size: 1.05rem;
    line-height: 1.6;
    max-width: 34rem;
    margin: 0 auto;
}

/* ---------- Die Titelfolie (/mitarbeiter-gewinnen) ----------

   Dieselbe Anmutung wie die erste Folie des Vortrags, damit der Sprung von
   der Leinwand aufs Handy nahtlos wirkt. Radius, Fläche und Rahmen sind die
   der übrigen Tafeln – vorher standen hier 8px, während jede andere Karte
   der Website 10px hat. Nebeneinander fällt so etwas auf. */
.funnel-hero .folie {
    width: 100%;
    max-width: 760px;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    box-shadow: var(--schatten-hoch);
    padding: 55px 45px;
    position: relative;
}

/* Der blaue Balken oben: dasselbe Zeichen wie auf .value-card, dort nur
   erst beim Überfahren. */
.funnel-hero .folie::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 96px;
    height: 3px;
    background-color: var(--primary-blue);
    box-shadow: var(--glut-blau);
}

.funnel-hero .folie .vorspann {
    margin-bottom: 28px;
}

/* Vortragender und Veranstaltung. Bewusst nicht in JetBrains Mono: die
   Schrift ist auf dieser Website für Zahlen und Preise reserviert, siehe
   den Kommentar bei --font-mono. */
.funnel-hero .redner {
    font-size: 0.85rem;
    color: var(--text-muted);
    border-top: 1px solid var(--linie-zart);
    padding-top: 20px;
    margin: 0;
}

/* ---------- Checklisten-Vorschau (/onboarding-checkliste) ----------

   Das Erkennungszeichen der Seite: die Haken setzen sich nacheinander, die
   Seite führt vor, was das PDF tut. */
.check-vorschau {
    max-width: 460px;
    margin: 40px auto 0;
    text-align: left;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 24px 28px;
    box-shadow: var(--schatten-karte);
}

.check-vorschau li {
    list-style: none;
    display: flex;
    align-items: baseline;
    gap: 12px;
    padding: 9px 0;
    color: var(--text-muted);
    border-bottom: 1px solid var(--linie-zart);
}

.check-vorschau li:last-child {
    border-bottom: none;
}

.check-vorschau .box {
    flex: none;
    width: 18px;
    height: 18px;
    border: 1.5px solid var(--rand-hell);
    border-radius: 4px;
    position: relative;
    top: 2px;
}

.check-vorschau .box::after {
    content: "";
    position: absolute;
    inset: 1px;
    background-color: var(--primary-blue);
    border-radius: 2px;
    clip-path: polygon(14% 52%, 38% 76%, 86% 22%, 74% 12%, 38% 54%, 26% 42%);
    opacity: 0;
}

.check-vorschau li:nth-child(1) .box::after { animation: haken 0.3s ease-out 0.5s forwards; }
.check-vorschau li:nth-child(2) .box::after { animation: haken 0.3s ease-out 1s forwards; }
.check-vorschau li:nth-child(3) .box::after { animation: haken 0.3s ease-out 1.5s forwards; }
.check-vorschau li:nth-child(4) .box::after { animation: haken 0.3s ease-out 2s forwards; }

@keyframes haken {
    to { opacity: 1; }
}

/* ---------- Die Download-Karte ----------

   Das Ziel beider Seiten. Stand vorher Zeile für Zeile in beiden Dateien. */
.dl-card {
    max-width: 560px;
    margin: 0 auto;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 40px 32px;
    text-align: center;
    box-shadow: var(--schatten-karte-stark);
}

.dl-card .dl-icon {
    width: 56px;
    height: 56px;
    margin: 0 auto 20px;
    color: var(--primary-blue);
}

.dl-card h2 {
    font-family: var(--font-heading);
    text-transform: uppercase;
    font-size: 1.6rem;
    color: var(--text-light);
    margin: 0 0 8px;
}

.dl-card .dl-meta {
    font-size: 0.85rem;
    color: var(--text-muted);
    margin: 0 0 28px;
}

.dl-card .btn {
    width: 100%;
    max-width: 22rem;
}

/* Steht ueber dem Formular, nicht darunter: es ist das Versprechen, fuer das
   jemand drei Felder ausfuellt. Unter dem Knopf haette es niemand gelesen,
   der noch ueberlegt. */
.dl-card .dl-hinweis {
    margin: 0;
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* ---------- Das Formular vor dem Download ----------

   Die Felder teilen sich das Aussehen mit denen auf /fuer-betriebe und
   /kontakt - .sta-form steht zentral weiter oben. Hier stehen nur die drei
   Unterschiede, die sich daraus ergeben, dass das Formular in einer
   zentrierten Karte sitzt und nicht in einer Spalte.

   Der Text der Karte ist zentriert, ein Formular darf das nicht sein: eine
   Beschriftung, die mittig ueber ihrem Feld schwebt, laesst sich beim
   Ausfuellen nicht mehr zuordnen. */
.dl-card .sta-form {
    text-align: left;
    margin-top: 28px;
}

/* Der Absendeknopf traegt hier die Rolle, die auf der Seite vorher der
   Download-Knopf hatte, und sieht deshalb auch so aus. */
.dl-card .sta-form button[type="submit"] {
    width: 100%;
    margin-top: 4px;
}

/* Nach dem Absenden. Der Verweis darin ist der Rueckfall, falls der Browser
   den Download nicht von selbst startet. */
.dl-card .form-success {
    margin-top: 24px;
    text-align: left;
}

.dl-card .form-success a {
    color: var(--accent-bright);
    font-weight: 600;
    white-space: nowrap;
}

@media (max-width: 768px) {
    .funnel-hero {
        min-height: 0;
        padding: 120px 20px 70px;
    }

    .funnel-hero .folie {
        padding: 36px 20px;
    }

    .check-vorschau {
        padding: 20px;
    }

    .dl-card {
        padding: 28px 20px;
    }
}

/* Steht dieselbe Bewegung woanders schon auf Verzicht, gilt das auch hier:
   die Haken sind dann von Anfang an gesetzt. */
@media (prefers-reduced-motion: reduce) {
    .check-vorschau .box::after {
        animation: none;
        opacity: 1;
    }
}

/* =========================================================
   /abo – die Rechnung

   Ebenfalls aus einem <style>-Block hierher geholt. Die Tafel zeigt, was
   Einzelbuchungen kosten und was das Abo daraus macht; die Zahlen stehen in
   JetBrains Mono, hier also genau richtig.
   ========================================================= */

.kalk-block {
    max-width: 720px;
    margin: 0 auto;
    background-color: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    padding: 32px 36px;
    box-shadow: var(--schatten-karte);
}

.kalk-zeile {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 24px;
    padding: 14px 0;
    border-bottom: 1px solid var(--linie-zart);
}

.kalk-zeile:last-child {
    border-bottom: none;
}

.kalk-zeile span {
    color: var(--text-muted);
}

.kalk-zeile strong {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: 1.15rem;
    color: var(--text-light);
    white-space: nowrap;
}

/* Die Ergebniszeile: abgesetzt durch eine kräftige Linie darüber, nicht
   durch eine eigene Fläche. */
.kalk-zeile.ergebnis {
    border-top: 2px solid var(--primary-blue);
    border-bottom: none;
    margin-top: 8px;
    padding-top: 18px;
}

.kalk-zeile.ergebnis strong {
    color: var(--primary-blue);
    font-size: 1.5rem;
}

.kalk-fussnote {
    margin: 16px 0 0;
    font-size: 0.85rem;
    color: var(--text-muted);
}

@media (max-width: 600px) {
    .kalk-block {
        padding: 22px 20px;
    }

    .kalk-zeile {
        flex-direction: column;
        gap: 2px;
    }
}

/* Fussnote unter einer Tafel. Stand vorher als style="" am Absatz - die
   einzige Inline-Formatierung auf /abo. */
.tabellen-fussnote {
    text-align: center;
    color: var(--text-muted);
    font-size: 0.9rem;
    margin-top: 24px;
}

/* Die Zusatzzeile unter einem Betrag in der Vergleichstabelle. Stand vorher
   sechsmal als style="" im Markup von /abo. */
.price-table .amount-zusatz {
    font-family: var(--font-body);
    font-size: 0.8rem;
    color: var(--text-muted);
}

/* Quellenangaben unter der Vergleichstabelle. */
.tabellen-quellen {
    color: var(--text-muted);
    font-size: 0.8rem;
    margin: 16px auto 0;
    max-width: 720px;
}

/* Ein Zitatkasten, der nach einer Tafel kommt und Luft davor braucht. */
.quote-block.quote-abgesetzt {
    margin-top: 40px;
}

/* Die CTA am Ende des Marktvergleichs.

   Oben mehr Luft: sie folgt auf den Ehrlichkeitshinweis und soll als eigenes
   Angebot lesbar sein, nicht als dessen Fortsetzung. Unten weniger, weil der
   naechste Abschnitt ohnehin mit 100px Innenabstand beginnt - zusammen waren
   das 200px und damit ein sichtbares Loch.

   Eigene Klassen statt Aenderung an .cta-box: den Baustein gibt es elfmal auf
   der Website, und an den anderen zehn Stellen stimmt der Abstand. */
.cta-box.cta-abgesetzt {
    margin-top: 72px;
}

.page-section.abschluss-eng {
    padding-bottom: 48px;
}

.quote-block .quote-text {
    color: var(--text-muted);
    line-height: 1.7;
}

/* =========================================================
   /team – Unser Team

   Die Karten kommen aus daten/team.json; gezeichnet werden sie aus
   daten/vorlagen/teamkarte.html und teamgruppe.html. Zwei Dinge steuert
   die Redaktion, und beide landen als Klasse bzw. als eigener Abschnitt
   im HTML:

     Gruppe   -> <section class="team-gruppe"> mit eigener Ueberschrift
     Groesse  -> .team-karte-gross | .team-karte-normal | .team-karte-klein

   Absichtlich anders als die Stimmen auf der Startseite: dort ein rundes
   Foto, das ueber der Karte haengt, mittig gesetzter Text, alles im
   Slider. Hier ein stehendes Rechteckfoto, linksbuendiger Text und ein
   Raster, das steht. Die beiden Seiten sollen nicht verwechselbar sein.

   Alle Farben kommen aus den Variablen im :root-Block. Die helle Ansicht
   braucht deshalb hier unten keine einzige eigene Regel.
   ========================================================= */

.team-abschnitt {
    padding-top: 40px;
}

.team-gruppe+.team-gruppe {
    margin-top: 90px;
}

/* Die Ueberschrift traegt den kurzen blauen Strich, den auch die
   Abschnittstitel sonst haben - nur hier als ::after, weil ueber der
   Gruppe kein eigenes Element dafuer steht. */
.team-gruppe-titel {
    font-family: var(--font-heading);
    font-size: clamp(1.4rem, 3vw, 2rem);
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--text-light);
    margin: 0 0 34px 0;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border-color);
    position: relative;
}

.team-gruppe-titel::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -1px;
    width: 64px;
    height: 3px;
    background-color: var(--primary-blue);
}

/* Eine Gruppe ohne Ueberschrift (Datensatz zeigt auf eine geloeschte
   Gruppe) faengt der Erzeuger mit hidden ab. Ohne diese Zeile bliebe die
   Linie darunter stehen und es saehe nach einem Fehler aus. */
.team-gruppe-titel[hidden] {
    display: none;
}

/* Kein starres Raster, sondern eine Reihe, die umbricht.

   Vorher war es ein Grid mit fester Spaltenzahl: eine grosse Karte belegte
   zwei Spalten, und blieb am Ende nur noch sie uebrig, stand der halbe Rest
   der Zeile leer. Dazu align-items:start - dadurch war jede Karte so hoch
   wie ihr eigener Text, und die Zeilen franstem unten aus.

   Jetzt hat jede Karte eine WUNSCHBREITE und darf darueber hinaus wachsen,
   bis die Zeile voll ist. Wie viele nebeneinander stehen, ergibt sich damit
   aus dem Platz und aus ihren Groessen - nicht aus einer Spaltenzahl. Kommt
   eine Person dazu, ordnet sich die Reihe von allein neu.

   justify-content greift erst, wenn die Karten an ihre max-width stossen -
   solange sie wachsen duerfen, ist die Zeile ohnehin randvoll. */
.team-raster {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 28px;
}

.team-karte {
    /* Wachsen ja, aber nicht ins Uferlose: ohne max-width zoege es eine
       einzelne Karte in der letzten Zeile ueber die volle Breite - und ihr
       quadratisches Foto gleich mit, das dann meterhoch waere. */
    flex: 1 1 270px;
    max-width: 430px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background-color: var(--bg-kachel);
    border: 1px solid var(--rand-kachel);
    border-radius: 12px;
    overflow: hidden;
    transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
}

.team-karte:hover {
    transform: translateY(-4px);
    box-shadow: var(--schatten-kachel);
    border-color: var(--primary-blue);
}

/* Feste Kachelform statt der Hoehe des jeweiligen Fotos: sonst stuenden in
   einer Reihe drei verschieden hohe Karten, sobald jemand ein Hochformat
   hochlaedt. Beschnitten wird mittig. */
.team-foto {
    aspect-ratio: 1 / 1;
    overflow: hidden;
    background-color: var(--bg-card);
}

.team-foto img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Nimmt den Rest der Karte ein. Die Karten einer Zeile sind jetzt gleich
   hoch; ohne diese Zeile endete die Flaeche der Karte unter dem letzten
   Absatz und darunter klaffte der Seitenhintergrund durch. */
.team-inhalt {
    flex: 1 1 auto;
    padding: 20px 22px 24px 22px;
}

.team-name {
    font-family: var(--font-heading);
    font-size: 1.15rem;
    line-height: 1.25;
    letter-spacing: 0.5px;
    color: var(--text-light);
    margin: 0 0 8px 0;
}

.team-rolle {
    font-size: 0.8rem;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: var(--primary-blue);
    margin: 0;
}

.team-bio {
    font-size: 0.95rem;
    line-height: 1.65;
    color: var(--text-muted);
    margin: 14px 0 0 0;
}

/* Leere Felder kommen als <p hidden> aus dem Erzeuger. Ohne diese beiden
   Zeilen entstuende an der Stelle ein leerer Absatz samt Abstand. */
.team-rolle[hidden],
.team-bio[hidden] {
    display: none;
}

/* ---------------------------------------------------------
   Die Bildkachel

   Ein Eintrag mit "art": "bild" - gedacht fuer ein Gruppenfoto zwischen den
   Personen. Sie liegt bewusst im selben Raster und benutzt dieselben drei
   Groessen: die BREITE kommt also aus derselben Regel wie bei den Karten
   daneben und passt damit zu der Reihe darueber.

   Die HOEHE dagegen kommt aus dem Bild. Deshalb hier kein aspect-ratio und
   kein object-fit: das Bild wird nicht beschnitten, sondern die Kachel wird
   so hoch, wie das Bild bei dieser Breite eben wird. Genau darum steht sie
   auch mit align-self oben in ihrer Zeile statt auf Zeilenhoehe gestreckt -
   sonst klaffte unter einem querformatigen Foto eine leere Flaeche.

   width/height stehen als Attribute im HTML, damit der Browser den Platz
   schon kennt, bevor das Bild da ist. Ohne sie ruckelte die ganze Reihe
   beim Nachladen.
   --------------------------------------------------------- */

/* Die Regeln stehen mit ZWEI Klassen (.team-karte.team-bildkachel). Nicht aus
   Vorliebe: die Groessenregeln weiter unten kommen spaeter in der Datei und
   wuerden eine einklassige Regel sonst schlagen. */
.team-karte.team-bildkachel {
    display: block;
    margin: 0;
    /* Die Breite kommt NICHT aus der Groessenklasse, sondern aus dem Bild:
       flex-basis auto heisst "so breit wie der Inhalt", und der Inhalt ist
       das Bild in der unten festgelegten Hoehe. Deshalb hier auch kein
       Wachsen und kein Schrumpfen. */
    flex: 0 0 auto;
    width: auto;
    max-width: 100%;
    /* Oben in der Zeile statt gestreckt: die Hoehe gehoert dem Bild. */
    align-self: flex-start;
}

/* Die Hoehe ist vorgegeben, die Breite ergibt sich aus dem Seitenverhaeltnis.
   Damit steht ein querformatiges Gruppenfoto breit und flach in der Reihe,
   ein hochkantes schmal - und keines ragt nach unten heraus.

   Vorher war es andersherum (Breite aus der Groesse, Hoehe aus dem Bild).
   Bei einem quadratischen Bild in "gross" wurde die Kachel dadurch 720x775,
   waehrend die Personenkarten daneben 322 hoch waren. */
.team-karte.team-bildkachel img {
    display: block;
    width: auto;
    height: 320px;
    max-width: 100%;
    object-fit: contain;
}

.team-bildtext {
    padding: 14px 18px 16px 18px;
    font-size: 0.9rem;
    line-height: 1.6;
    color: var(--text-muted);
    /* Die Bildunterschrift darf die Breite der Kachel nicht bestimmen -
       sonst zoege ein langer Satz die Kachel breiter als das Bild. Mit
       width:0 zaehlt sie bei der Breitenrechnung nicht mit, mit min-width
       fuellt sie danach trotzdem die ganze Kachel. */
    width: 0;
    min-width: 100%;
    box-sizing: border-box;
}

.team-bildtext[hidden] {
    display: none;
}

/* ---------------------------------------------------------
   Die drei Groessen

   normal ist der Grundzustand oben - dazu steht hier nichts.
   --------------------------------------------------------- */

.team-karte-klein {
    flex: 1 1 200px;
    max-width: 330px;
}

/* Bei einer Bildkachel steuert die Groesse die HOEHE, nicht die Breite -
   die kommt ja aus dem Bild. Die Werte sind an den Karten abgelesen:
   eine Zeile mit normalen Karten wird rund 320 hoch, eine mit grossen
   rund 420. */
.team-karte.team-bildkachel.team-karte-klein img {
    height: 240px;
}

.team-karte-klein .team-inhalt {
    padding: 14px 16px 18px 16px;
}

.team-karte-klein .team-name {
    font-size: 1rem;
}

.team-karte-klein .team-bio {
    font-size: 0.88rem;
    margin-top: 10px;
}

/* Gross belegt zwei Spalten und legt Foto und Text nebeneinander. Beides
   erst ab einer Breite, auf der zwei Spalten ueberhaupt entstehen - in
   einem einspaltigen Raster waere ein "span 2" eine leere zweite Spalte. */
@media (min-width: 700px) {

    /* Doppelt so breit gewuenscht wie eine normale Karte, und vom uebrigen
       Platz nimmt sie sich auch den doppelten Anteil.

       Die max-width ist der Grund, warum eine allein stehende grosse Karte
       nicht ueber die ganze Seite laeuft: sie bleibt bei 720px und wird von
       justify-content mittig gesetzt. */
    .team-karte-gross {
        flex: 2 1 560px;
        max-width: 720px;
        flex-direction: row;
        /* Ohne Mindesthoehe bestimmt der Text die Bildhoehe. Bei jemandem
           ohne Kurzbio - die ist freiwillig - bliebe vom Foto sonst ein
           flacher Streifen uebrig. */
        min-height: 320px;
    }

    /* Eine grosse Bildkachel wird HOEHER, nicht breiter - ihre Breite gehoert
       dem Bild. Deshalb hier weder flex-basis noch max-width der grossen
       Karten, und die Mindesthoehe muss ausdruecklich weg. */
    .team-karte.team-bildkachel.team-karte-gross {
        min-height: 0;
        flex: 0 0 auto;
        max-width: 100%;
    }

    .team-karte.team-bildkachel.team-karte-gross img {
        height: 420px;
    }

    .team-karte-gross .team-foto {
        flex: 0 0 44%;
        aspect-ratio: auto;
    }

    /* Oben ansetzen, nicht mittig. Bei mittiger Ausrichtung wanderte der Name
       je nach Laenge der Kurzbio auf eine andere Hoehe - in einer Zeile mit
       mehreren grossen Karten standen die Namen dann auf verschiedenen
       Linien. Oben angesetzt beginnen alle gleich. */
    .team-karte-gross .team-inhalt {
        align-self: flex-start;
        padding: 30px 32px;
    }

    .team-karte-gross .team-name {
        font-size: 1.5rem;
    }

    .team-karte-gross:hover {
        transform: translateY(-6px);
    }
}

/* Schmal: eine Karte je Zeile. Die max-width von oben muss dabei weg -
   sonst stuende eine 430px breite Karte mittig in einem 500px breiten
   Fenster und liesse links und rechts einen Rand stehen. */
@media (max-width: 560px) {
    .team-raster {
        gap: 22px;
    }

    .team-karte,
    .team-karte-klein,
    .team-karte-gross {
        flex-basis: 100%;
        max-width: 100%;
    }

    /* Auf dem Handy dreht sich die Regel wieder um: dort steht ohnehin nur
       eine Kachel je Zeile. Ein Bild dann auf eine feste Hoehe zu zwingen
       liesse links und rechts Rand stehen - also volle Breite und die Hoehe
       zurueck ans Bild. */
    .team-karte.team-bildkachel {
        flex-basis: 100%;
        width: 100%;
    }

    .team-karte.team-bildkachel img,
    .team-karte.team-bildkachel.team-karte-klein img {
        width: 100%;
        height: auto;
    }
}

/* Wer Bewegung abbestellt hat, bekommt den Hover als reine Farbaenderung.
   Dieselbe Regel wie an den drei anderen Stellen der Datei. */
@media (prefers-reduced-motion: reduce) {

    .team-karte,
    .team-karte:hover {
        transition: border-color 0.3s ease;
        transform: none;
    }
}

/* =========================================================
   Hervorhebung aus dem Backend

   Im Text steht *Wort*, daraus macht der Erzeuger
   <span class="hervor">Wort</span> - siehe textBereich() in build-daten.js
   und sta_textBereich() in erzeugen.php.

   Die Redaktion vergibt damit die BEDEUTUNG ("das ist hervorgehoben"), nicht
   das Aussehen. Wie eine Hervorhebung aussieht, entscheidet sich hier - und
   zwar je nach Umgebung. Vorher stand dafuer .brand-glow bzw. .jahr fest im
   HTML; wer den Satz aendern wollte, musste an die Datei.

   Die beiden Regeln geben genau das wieder, was an diesen Stellen schon
   vorher galt. Wer die Hervorhebung anderswo braucht, ergaenzt hier eine
   Zeile statt im HTML eine Klasse.
   ========================================================= */

.brand-title .hervor {
    font-family: var(--font-heading);
    color: var(--primary-blue);
    text-shadow: var(--brand-glow-schatten);
}

.funnel-hero h1 .hervor {
    color: var(--primary-blue);
    text-shadow: var(--brand-glow-schatten);
}
