/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   Gestaltung der Kunden-Sites (`.site-data`)

   Ein eigenes, aktuelles Erscheinungsbild — NICHT dem Altsystem nachgebaut. Was hier steht, ersetzt
   die Notlösungen aus der ersten Übernahme: dort wurde Baustein für Baustein so weit angeglichen,
   dass es „ungefähr wie vorher" aussah. Das Ergebnis war eine Sammlung von Einzelfällen ohne
   gemeinsame Sprache.

   Drei Regeln, die alles hier bestimmen:

   1. FARBE KOMMT VON DER SITE. Kein einziger Markenton ist hier fest verdrahtet; alles liest die
      Theme-Token (`--brand`, `--ink`, `--bg`, `--bg-alt`, `--line`). Ein Kunde behält damit sein
      Erscheinungsbild, bekommt aber die neue Struktur. Nur neutrale Werte (Schatten, Grautöne für
      Trennlinien) stehen als Rückfall drin.

   2. RHYTHMUS STATT EINZELMASSE. Abstände, Radien und Schriftgrößen kommen aus einer Skala, nicht
      aus dem Gefühl je Baustein. Deshalb die Variablen unten: Wer den Rhythmus ändern will, ändert
      eine Zahl, nicht vierzig.

   3. RUHE. Eine Seite für Eltern, die sich Sorgen um ihr Kind machen, darf nicht marktschreierisch
      sein. Große Typografie, viel Weißraum, sparsame Farbe, weiche Kanten.

   Eingegrenzt auf `.site-data`: Die Neotec-Website (`.site-neotec`) und GA bleiben unberührt.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

.site-data {
    /* Vertikaler Rhythmus. Alle Abstände sind Vielfache davon — daher wirkt die Seite ruhig, ohne
       dass man einzelne Werte vergleichen müsste. `clamp` statt fester Zahlen: auf dem Telefon
       braucht dieselbe Gliederung weniger Luft als auf einem breiten Schirm. */
    /* Gemessen war die erste Fassung zu grosszuegig: 96px oben UND unten je Abschnitt, dazu die
       Abstaende der Bausteine — ueber 60 % der Seitenhoehe war Leerraum, ein Abschnitt bestand zu
       96 % daraus. Weissraum gliedert, aber ab einem Punkt zerreisst er den Zusammenhang, und die
       Seite wirkt unfertig statt ruhig. */
    --takt: clamp(2.25rem, 3.5vw, 3.5rem);
    --takt-klein: clamp(1.25rem, 2vw, 1.75rem);

    /* Der seitliche Rand der Seite. Steht hier und nicht als Zahl im Regelwerk, weil ihn inzwischen
       zwei Stellen brauchen: der Abschnitt und der Baustein, der ohne Abschnitt an der Wurzel haengt. */
    --rand: clamp(1.25rem, 4vw, 2rem);

    /* Die Breite, auf der jede FLAECHE steht — Kartenraster, Bild-und-Text, Handlungsaufruf,
       Newsletter, Kontaktkarte. Sie ergibt sich aus der weiten Stufe minus dem Rand, weil genau das
       herauskommt, wenn eine Flaeche in der Abschnittshuelle sitzt (1040 - 2x32 = 976). Als eigene
       Variable, damit auch die Bausteine OHNE Huelle — die beiden Newsletter haengen direkt in
       `main` — auf derselben Kante landen und nicht auf 1040. */
    --breite-flaeche: calc(var(--breite-weit) - 2 * var(--rand));

    /* Weiche Formen. Ein Radius für Flächen, ein kleinerer für Bedienelemente. */
    --rund: 20px;
    --rund-klein: 12px;

    /* Schatten in zwei Stufen: ruhend und angehoben. Bewusst sehr weich und kaum sichtbar —
       ein Schatten soll Tiefe andeuten, nicht auffallen. */
    --schatten: 0 1px 2px rgba(16, 24, 40, .04), 0 8px 24px -12px rgba(16, 24, 40, .10);
    --schatten-hoch: 0 2px 4px rgba(16, 24, 40, .05), 0 16px 40px -16px rgba(16, 24, 40, .18);

    --lesebreite: 66ch;

    /* ZWEI Breiten, mehr nicht. Gemessen hatte die Startseite fuenf verschiedene und vier
       verschiedene linke Kanten (159, 191, 311, 319px): Hero und Abschnitt 1040, Bild-und-Text 976,
       Newsletter 736, Abschnittskopf 720. Jeder Baustein brachte sein eigenes Mass mit, historisch
       gewachsen — beim Scrollen sprang der Text bei jedem Block an eine andere Stelle.

       `weit`  traegt Struktur: Raster, Karten, Bild neben Text.
       `text`  traegt Sprache: Ueberschriften-Bloecke, Fliesstext, Formulare.

       Mehr Stufen braucht diese Seite nicht — und jede weitere waere wieder eine Kante mehr. */
    --breite-weit: 1040px;
    --breite-text: 44rem;
}

/* ─── Typografie ─────────────────────────────────────────────────────────────────────────────────
   Eine Stufe pro Ebene, deutlich getrennt. Der Sprung zwischen Seitentitel und Abschnittstitel ist
   groß genug, dass man ihn beim Überfliegen sieht — das war vorher nicht so. */

.site-data .nsite-hero__title,
.site-data .nsite-secthead__h,
.site-data .nsite-section__h,
.site-data .nsite-mediatext__h,
.site-data .nsite-newsletter__h,
.site-data .nsite-cta__h {
    /* `balance` verteilt die Zeilen einer Überschrift gleichmäßig, statt die erste bis zum Rand zu
       füllen und ein einzelnes Wort hängen zu lassen. */
    text-wrap: balance;
    letter-spacing: -.022em;
    line-height: 1.12;
}

.site-data .nsite-hero__title { font-size: clamp(2.1rem, 1.2rem + 3.4vw, 3.6rem); font-weight: 800; }
.site-data .nsite-secthead__h,
.site-data .nsite-section__h { font-size: clamp(1.6rem, .9rem + 2.2vw, 2.4rem); font-weight: 700; }
.site-data .nsite-mediatext__h { font-size: clamp(1.4rem, .9rem + 1.6vw, 2rem); font-weight: 700; }

/* Vorzeile: klein, gesperrt, in der Akzentfarbe. Sie ordnet ein, ohne der Überschrift die Schau zu
   stehlen — deshalb NICHT fett und deutlich kleiner. */
.site-data .nsite-hero__eyebrow,
.site-data .nsite-secthead__label,
.site-data .nsite-newsletter__label,
.site-data .nsite-cta__label {
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--brand, #e8590c);
    /* KEINE Deckkraft. site.css gibt der Hero-Vorzeile `opacity: .85` mit — auf der Markenfarbe
       gerechnet wird daraus effektiv rgb(203,100,56) statt rgb(194,74,24), und der Kontrast faellt
       von 4,58 auf 3,63. Die Farbe ist bereits gewaehlt; sie danach noch aufzuhellen nimmt ihr
       genau die Deckung, die sie fuer kleine Versalien braucht. */
    opacity: 1;
}
/* Auf dunklem Grund trägt die Vorzeile keine Markenfarbe — dort ginge sie unter.

   Die Absicht stand hier schon, der Selektor traf aber nie: `.nsite-section--tone-dark` gibt es im
   Markup nicht, die Klasse heisst `bos-section--tone-dark`. Ein toter Selektor sieht aus wie eine
   erledigte Sache — gemessen stand die Vorzeile weiter in Markenfarbe auf der dunklen Flaeche, mit
   einem Kontrast von 3,39 (noetig sind 4,5 bei 12,5px).

   Weiss statt einer aufgehellten Markenfarbe, weil die Regel fuer JEDE Kunden-Site gelten muss:
   Wie stark eine Marke aufgehellt werden muesste, haengt an ihrer Helligkeit — bei einer sehr
   dunklen Marke reicht selbst eine kraeftige Aufhellung knapp nicht. Weiss traegt immer, und der
   Hero macht es auf Bild- und Dunkelgrund laengst genauso. */
.site-data .nsite-hero--light .nsite-hero__eyebrow,
.site-data .nsite-hero--image .nsite-hero__eyebrow,
.site-data .bos-section--tone-dark .nsite-secthead__label { color: rgba(255, 255, 255, .82); }

/* Fliesstext auf dunklem Grund. `.nsite-secthead__lead` traegt aus site.css ein fest verdrahtetes
   `#5a6478` — ein BLAUGRAU fuer helle Flaechen, das auf der dunklen Flaeche nie ersetzt wurde.
   Gemessen: Kontrast 2,79 gegen die geforderten 4,5. Genau das hat der Nutzer gesehen, und
   Lighthouse meldet es als „Kontrastverhaeltnis nicht ausreichend".

   Bewusst eng gefasst auf die Textklassen statt auf `p`/`li`: In einem dunklen Abschnitt kann eine
   HELLE Karte stehen (Newsletter, Kontaktformular) — deren Text muss dunkel bleiben. */
.site-data .bos-section--tone-dark :is(.nsite-secthead__lead, .nsite-prose, .bos-richtext) {
    color: rgba(255, 255, 255, .82);
}

/* Fließtext: Lesebreite und ein Zeilenabstand, der auch längere Absätze trägt. */
.site-data .nsite-secthead__lead,
.site-data .nsite-hero__sub,
.site-data .bos-richtext,
.site-data .nsite-mediatext__body {
    font-size: clamp(1rem, .96rem + .2vw, 1.09rem);
    line-height: 1.68;
}
/* KEINE zweite Begrenzung innerhalb der Textstufe. Der Lead hatte zusaetzlich eine eigene
   Lesebreite (66ch) und war dadurch 620px breit, waehrend die Ueberschrift darueber 640 und der
   Newsletter-Titel 619 mass. Drei zentrierte Bloecke, drei Breiten — und weil Zentrierung aus der
   Breite die Kante macht, drei verschiedene Kanten (598, 608, 609).

   Die Stufe `--breite-text` (44rem) IST die Lesebreite. Wer sie zweimal setzt, bekommt sie nie. */
.site-data .nsite-secthead__lead,
.site-data .nsite-newsletter__intro,
.site-data .nsite-cta__sub { max-width: none; }

/* Eingabefelder fuellen ihre Zeile, statt sich eine eigene Breite zu suchen. */
.site-data .nsite-newsletter__form,
.site-data .nsite-contact__form { width: 100%; }

/* ─── Eine gemeinsame Achse ──────────────────────────────────────────────────────────────────────
   Gemessen war der Bruch deutlich: Der Hero-Text begann bei 40px am Fensterrand, der Inhalt
   darunter bei 423px (zentrierter Rahmen, 1040px). 383px Versatz zwischen zwei Blöcken, die
   untereinander stehen — das Auge findet beim Scrollen keine Kante, an der es sich festhält, und
   die Seite wirkt zusammengewürfelt.

   Der Hero bekommt deshalb denselben Rahmen wie jeder Abschnitt. Das ist die wirksamste einzelne
   Änderung an diesem Design: Titel, Fließtext und Karten stehen ab jetzt auf derselben Linie. */
.site-data .nsite-hero__inner,
.site-data .bos-section__inner {
    max-width: 1040px;
    width: 100%;
    margin-inline: auto;
    /* EIN Rand für beide. Er stand vorher nur am Hero — dadurch begann der Hero-Text 20px weiter
       innen als der Inhalt darunter (auf UAT gemessen: 443 gegen 423).

       Und er fehlte den Kunden-Sites bisher ganz: `.bos-section__inner` trägt in der Grundregel
       keinen seitlichen Abstand; nur die Neotec-Website setzt ihn über `--pad-x` selbst. Auf einem
       schmalen Schirm klebte der Text also am Bildschirmrand. */
    padding-inline: var(--rand);
}
/* Der Hero selbst bleibt randlos (Bild, Farbfläche) — nur sein INHALT folgt der Achse. */
.site-data .nsite-hero { padding-inline: 0; }

/* ─── Abschnitte ─────────────────────────────────────────────────────────────────────────────────
   Der Takt trägt die Gliederung. Vorher hatten Abschnitte feste Innenabstände, die auf großen
   Schirmen zu eng und auf kleinen zu weit waren. */

.site-data .bos-section--pad-lg { padding-top: var(--takt); padding-bottom: var(--takt); }
.site-data .bos-section--pad-md { padding-top: var(--takt-klein); padding-bottom: var(--takt-klein); }

/* Abgesetzte Flächen bekommen die zweite Hintergrundfarbe der Site. Der Wechsel hell/abgesetzt ist
   das Gliederungsmittel — ohne ihn läuft eine lange Seite als ein Block durch. */
.site-data .bos-section--tone-light { background: var(--bg-alt, #f7f8fa); }

/* Eine DUNKLE Toenung ist kein Grund, sondern ein Gegenstand — und bekommt deshalb die Form eines
   Gegenstands: gerundete Flaeche auf der Flaechenkante, nicht randlos ueber die ganze Seite.

   Vorher malte diese Regel das ganze Band. Direkt darunter steht der Handlungsaufruf, der dieselbe
   dunkle Farbe als KARTE traegt — zweimal Dunkel, zwei verschiedene Formen, unmittelbar
   untereinander. Genau darauf hat der Nutzer gezeigt.

   Die Neotec-Website macht das laengst so (`neotec-site.css`: „Dunkler Bereich = gerundete Box im
   Weissraum, nicht randlos"). Nur die Kunden-Sites hatten es nicht — ich habe die Regel dort neu
   geschrieben, statt die vorhandene Loesung zu uebernehmen.

   Helle Toenungen bleiben randlos: Ein heller Ton liest sich als Grund und gliedert die Seite,
   ein dunkler traegt zu viel Gewicht dafuer. */
.site-data .bos-section--tone-dark {
    background: transparent;
    color: inherit;
    padding-inline: var(--rand);
}
.site-data .bos-section--tone-dark > .bos-section__inner {
    max-width: var(--breite-flaeche);
    background: var(--bg-dark-grad, #1f2430);
    color: #fff;
    border-radius: var(--rund);
    padding-block: clamp(2rem, 4vw, 3rem);
    padding-inline: clamp(1.5rem, 3vw, 2.5rem);
}
.site-data .bos-section--tone-dark :is(h1, h2, h3, h4) { color: inherit; }
.site-data .bos-section--tone-dark a { color: #fff; text-decoration-color: rgba(255, 255, 255, .4); }

/* Abschnittskopf: Vorzeile, Überschrift, Lead — als Gruppe mit eigenem Abstand nach unten. */
.site-data .nsite-secthead { margin-bottom: var(--takt-klein); }
.site-data .nsite-secthead > * + * { margin-top: .5rem; }

/* `border-box` ist hier die eigentliche Lösung, nicht Kosmetik.

   Ohne sie zählt das Padding ZUSÄTZLICH zur `max-width`. Gemessen auf der Startseite:
   Abschnitt 1040 + 2×32 = 1104, Abschnittskopf 704 + 2×32 = 768, Newsletter 704 + 2×41,6 = 789.
   Drei Container mit denselben zwei Sollbreiten landeten auf drei verschiedenen Ist-Breiten —
   und damit auf drei verschiedenen Kanten, nur weil ihre Innenabstände sich unterscheiden.

   Mit `border-box` IST die Sollbreite die Breite. Erst dadurch wirkt die Stufeneinteilung
   darunter überhaupt. */
.site-data :is(.bos-section__inner, .nsite-hero__inner, .nsite-mediatext__inner, .nsite-cardgrid,
               .nsite-features, .nsite-secthead, .nsite-newsletter__inner, .nsite-contact,
               .nsite-section) { box-sizing: border-box; }

/* Bedienelemente gehoeren dazu. Sie standen bisher auf `content-box`, und weil sie ihre Breite aus
   der Rasterspalte beziehen (`width: 100%`), kam ihr eigener Innenabstand OBEN DRAUF:

       Spalte      302,2px
     + Padding      32,0px  (1rem links und rechts)
     + Rahmen        2,0px
     = tatsaechlich 336,2px      -> 33px ueber die Inhaltsbox der Karte hinaus

   Solange die Kontaktkarte gar keinen Innenrand hatte, lief der Ueberstand einfach bis an ihre
   Kante und fiel nicht auf. Sobald sie einen bekommt, frisst er ihn wieder auf — die Felder lagen
   9px vom Rand statt 41,6px, und die beiden Spalten ueberlappten sich um 20px. */
.site-data :is(input, textarea, select, button) { box-sizing: border-box; }

/* ─── Jeder Baustein gehört zu einer der zwei Stufen ─────────────────────────────────────────────
   Ab hier gibt es nur noch zwei linke Kanten auf der Seite — eine für Struktur, eine für Text. */

/* WEIT: alles, was Struktur zeigt. */
.site-data .nsite-hero__inner,
.site-data .bos-section__inner,
.site-data .nsite-mediatext__inner,
.site-data .nsite-cardgrid,
.site-data .nsite-features { max-width: var(--breite-weit); margin-inline: auto; }

/* TEXT: alles, was gelesen wird. Zentriert, damit die Zeile nicht am linken Rand allein steht. */
.site-data .nsite-secthead,
.site-data .nsite-section:not(.nsite-contact) { max-width: var(--breite-text); margin-inline: auto; }

/* FLAECHEN: alles, was als Kasten sichtbar ist, steht auf EINER Kante — egal was drin steht.
   Hier lag der Bruch, den der Nutzer gesehen hat: Newsletter und Kontaktkarte standen in der
   TEXT-Stufe, weil in ihnen Text steht. Sichtbar ist aber der Kasten, nicht sein Inhalt, und der
   war dadurch schmaler als das Kartenraster daneben. Gemessen auf UAT:

       Affirmationskarten / Eltern-Guide   602 / 704     <- schmal
       Drei Bausteine (Kartenraster)       466 / 976
       Hinter „Starkes Training"           466 / 976
       Handlungsaufruf                     466 / 976
       Schreib mir (Kontaktkarte)          602 / 704     <- schmal

   Zwei Kanten fuer dieselbe Sorte Ding. Jetzt stehen alle fuenf auf 466/976; der TEXT DARIN bleibt
   bei 704 (Ueberschriften) beziehungsweise bringt seine eigene Lesebreite mit.

   `.nsite-section:not(.nsite-contact)` oben ist noetig, weil die Kontaktkarte BEIDE Klassen traegt
   (`nsite-section nsite-contact`) — dieselbe Doppelrolle wie beim Innenabstand. */
.site-data .nsite-newsletter__inner,
.site-data .nsite-contact { max-width: var(--breite-flaeche); margin-inline: auto; }

/* Ein Karten-Raster gehoert zur WEITEN Stufe, auch wenn es in einem schmalen Baustein sitzt.
   Sonst brechen die Karten um: gemessen war das Raster 704px breit, die drei Karten passten nicht
   nebeneinander, und der Abschnitt wuchs auf 968px Hoehe bei 43px Ueberschrift. */
.site-data .nsite-section > .nsite-cardgrid,
.site-data .nsite-section > .nsite-features { max-width: none; width: 100%; }
.site-data .nsite-section:has(> .nsite-cardgrid, > .nsite-features) { max-width: var(--breite-weit); }

/* Der Bild-und-Text-Baustein steht IM Abschnitt und erbt dessen Breite. Eine eigene Begrenzung
   zöge den Rand ein zweites Mal ab — er sass dadurch 32px weiter innen als alles andere. */
.site-data .nsite-mediatext__inner { max-width: none; }

/* Ein Container IM Container braucht keinen eigenen seitlichen Rand — der äußere hat schon einen.
   Gemessen bei 400px Fensterbreite: Der Abschnittskopf hatte 88px Abstand auf jeder Seite (32 vom
   Abschnitt + 32 von sich selbst + Rest), es blieben 224px für den Text. Auf einem Telefon ist das
   die Hälfte der nutzbaren Fläche, nur für Luft. */
.site-data .bos-section__inner :is(.nsite-secthead, .nsite-section, .nsite-mediatext__inner):not(.nsite-contact) {
    padding-inline: 0;
}

/* ─── Doppelte Ränder auflösen ───────────────────────────────────────────────────────────────────
   Mehrere Bausteine bringen einen EIGENEN seitlichen Rand mit (`.nsite-mediatext`,
   `.nsite-newsletter`, `.nsite-section`: je 2rem), obwohl sie längst in einem Abschnitt stehen, der
   schon einen hat. Gemessen: Der Bild-Text-Block begann 32px weiter rechts als die Überschrift
   darüber — genau diese zweiten 2rem.

   Solche Verschiebungen um wenige Pixel sind einzeln kaum zu benennen und in der Summe der Grund,
   warum eine Seite „irgendwie unruhig" wirkt. Der Rand gehört dem Abschnitt; der Baustein steuert
   nur noch seinen vertikalen Anteil bei. */
.site-data .bos-section__inner :is(.nsite-mediatext, .nsite-newsletter) {
    padding-inline: 0;
    padding-block: 0;
}

/* …aber NUR dann. Der Satz oben — „Der Rand gehört dem Abschnitt" — setzt voraus, dass der Baustein
   ueberhaupt IN einem Abschnitt steht. Auf der Startseite von starkestraining tun zwei Newsletter
   das nicht: Sie haengen direkt in `main`, gleichrangig neben den Abschnitten. Ihnen den Rand zu
   nehmen hiess, ihnen den einzigen zu nehmen, den sie hatten.

   Gemessen: Zwischen „Damit aus Verletzlichkeit echte Staerke wird." und „Affirmationskarten" blieb
   nur die Fusszeile des Abschnitts darueber (49,84px); zwischen den beiden Newslettern lagen
   exakt 0px. Zwei Bausteine ohne jede Trennung — genau die Stelle, auf die der Nutzer zweimal
   gezeigt hat.

   Ein Baustein an der Wurzel bringt seinen eigenen Takt mit, und zwar denselben wie ein Abschnitt
   (`--takt`), damit die Seite EINEN Rhythmus hat und nicht zwei. */
.site-data .nsite-main > :is(.nsite-mediatext, .nsite-newsletter, .nsite-cta) {
    padding-block: var(--takt);
    padding-inline: var(--rand);
}

/* AUSNAHME — und die Unterscheidung, an der ich schon einmal vorbeigelaufen bin:
   Ein Baustein mit EIGENER Hintergrundfarbe ist eine FLAECHE, keine blosse Gruppierung. Er braucht
   Innenabstand, sonst bleibt von ihm nur ein Balken uebrig, so hoch wie sein Inhalt — die Farbe
   steht dann da, die Flaeche fehlt.

   Beim Handlungsaufruf ist genau das passiert: Er traegt `background: var(--ns-ink)`, und die Regel
   darueber nahm ihm das Padding. Uebrig blieb ein 52px hoher, dunkler Streifen ohne Rundung mitten
   im Weiss — so hoch wie der Knopf darin und ohne erkennbare Absicht.

   Der Newsletter steht hier mit, obwohl er auf der Seite, die den Fehler zeigte, in der Darstellung
   „none" (durchsichtig) laeuft und deshalb nicht auffiel. Drei seiner vier Darstellungen bringen
   aber sehr wohl einen Hintergrund mit (`--accent`, `--dark`, `--light`) — ein Umschalten der
   Darstellung im Editor haette denselben Balken erzeugt, auf einer anderen Site oder in einem
   halben Jahr. Die Regel folgt jetzt dem Merkmal, nicht der Beobachtung.

   Als Karte statt als randlosem Band: dieselbe Formensprache wie die uebrigen Flaechen der Seite. */
.site-data :is(.nsite-cta,
               .nsite-newsletter--accent, .nsite-newsletter--dark, .nsite-newsletter--light) {
    padding-block: clamp(2rem, 4vw, 3rem);
    padding-inline: clamp(1.5rem, 3vw, 2.5rem);
    border-radius: var(--rund);
}
.site-data .nsite-section:not(.nsite-contact) { padding-inline: 0; padding-block: var(--takt-klein); }

/* Das `:not(.nsite-contact)` an den beiden Regeln darueber ist dieselbe Unterscheidung wie beim
   Handlungsaufruf und beim Newsletter, nur an einer Stelle, die man ihr nicht ansieht: Das
   Kontaktformular traegt ZWEI Klassen — `nsite-section nsite-contact`. Als `nsite-section` ist es
   ein Container und faellt unter „Container im Container braucht keinen eigenen Rand"; als
   `nsite-contact` ist es aber eine KARTE mit weissem Grund, Rahmen, Radius und Schatten.

   Die Container-Regel gewann ueber die Spezifitaet (0,3,0 gegen 0,2,0) — nicht ueber die
   Reihenfolge, weshalb das Verschieben der Kartenregel nichts geholfen haette. Gemessen auf UAT:
   Karte von 525 bis 1229, Eingabefelder von 526 bis 1228. Ein Pixel Luft an einer Kante, die
   41,6px oben und unten hat.

   Merksatz, jetzt zum dritten Mal: Eine Flaeche behaelt ihren Innenabstand. Dass sie nebenbei eine
   Container-Klasse traegt, macht sie nicht zum Container. */

/* ─── Karten ─────────────────────────────────────────────────────────────────────────────────────
   Weiche Kanten, kaum sichtbarer Schatten, spürbare Reaktion beim Zeigen. Vorher waren es flache
   Kästen mit hartem Rand. */

.site-data .nsite-card,
.site-data .nsite-feature,
.site-data .bos-card {
    background: var(--bg, #fff);
    border: 1px solid var(--line, #eceef2);
    border-radius: var(--rund);
    padding: clamp(1.4rem, 2.5vw, 2rem);
    box-shadow: var(--schatten);
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
/* Nur wo die Karte selbst ein Ziel ist — sonst wackelt Text beim Vorbeifahren. */
.site-data a.nsite-card:hover,
.site-data .nsite-card:has(a):hover,
.site-data .nsite-feature:has(a):hover {
    transform: translateY(-2px);
    box-shadow: var(--schatten-hoch);
    border-color: color-mix(in srgb, var(--brand, #e8590c) 28%, var(--line, #eceef2));
}

/* Raster mit gleichmäßigem Abstand; `auto-fit` bricht von selbst um, statt an festen Punkten. */
.site-data .nsite-cardgrid,
.site-data .nsite-features {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: clamp(1rem, 2vw, 1.6rem);
}

/* ─── Bedienelemente ─────────────────────────────────────────────────────────────────────────────
   Knöpfe mit ruhiger Reaktion: leicht anheben, Farbe vertiefen. Kein Aufblitzen, kein Springen. */

.site-data .nsite-btn,
.site-data .nsite-nav__cta,
.site-data .nsite-newsletter__form button,
.site-data .nsite-contact__form button {
    border-radius: 999px;
    padding: .8rem 1.5rem;
    font-weight: 600;
    letter-spacing: .01em;
    border: 1px solid transparent;
    transition: transform .16s ease, box-shadow .16s ease, filter .16s ease;
}
.site-data .nsite-btn:hover,
.site-data .nsite-nav__cta:hover,
.site-data .nsite-newsletter__form button:hover,
.site-data .nsite-contact__form button:hover {
    transform: translateY(-1px);
    filter: saturate(1.06) brightness(.96);
    box-shadow: var(--schatten-hoch);
}
.site-data :is(.nsite-btn, .nsite-nav__cta, button, a):focus-visible {
    outline: 2px solid var(--brand, #e8590c);
    outline-offset: 3px;
    border-radius: var(--rund-klein);
}

/* Eingabefelder: dieselbe Formensprache wie die Karten, sichtbarer Fokus. */
.site-data input[type="text"],
.site-data input[type="email"],
.site-data textarea {
    border-radius: var(--rund-klein);
    border: 1px solid var(--line, #dfe3ea);
    padding: .8rem 1rem;
    font: inherit;
    background: var(--bg, #fff);
    transition: border-color .16s ease, box-shadow .16s ease;
}
.site-data input[type="text"]:focus,
.site-data input[type="email"]:focus,
.site-data textarea:focus {
    outline: none;
    border-color: var(--brand, #e8590c);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand, #e8590c) 18%, transparent);
}

/* ─── Formular-Bausteine als eigene Fläche ───────────────────────────────────────────────────────
   Newsletter und Kontakt standen bisher offen im Fluss und gingen zwischen den Textabschnitten
   unter. Als abgesetzte Karte sind sie erkennbar das, was sie sind: eine Aufforderung zu handeln. */

.site-data .nsite-newsletter__inner,
.site-data .nsite-contact {
    background: var(--bg, #fff);
    border: 1px solid var(--line, #eceef2);
    border-radius: var(--rund);
    padding: clamp(1.6rem, 3.5vw, 2.6rem);
    box-shadow: var(--schatten);
}
/* Auf abgesetztem Grund wirkt eine weitere helle Fläche flach — dort trägt der Rand die Trennung. */
.site-data .bos-section--tone-light :is(.nsite-newsletter__inner, .nsite-contact) {
    box-shadow: none;
    border-color: color-mix(in srgb, var(--ink, #1f2937) 10%, transparent);
}

/* ─── Bild und Text ──────────────────────────────────────────────────────────────────────────────
   Gleichgewicht statt starrer Hälften: das Bild bekommt etwas weniger Platz als der Text, damit die
   Textspalte lesbar bleibt. Bild mit weichen Ecken, passend zu den Karten. */

.site-data .nsite-mediatext__inner {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: clamp(1.6rem, 4vw, 3.5rem);
    align-items: center;
}
.site-data .nsite-mediatext__media img {
    border-radius: var(--rund);
    box-shadow: var(--schatten);
    width: 100%;
    height: auto;
    display: block;
}
.site-data .nsite-mediatext__body > * + * { margin-top: 1rem; }

@media (max-width: 820px) {
    .site-data .nsite-mediatext__inner { grid-template-columns: 1fr; }
}

/* ─── Kopfzeile ──────────────────────────────────────────────────────────────────────────────────
   Beim Scrollen bekommt die Leiste eine feine Kante und einen Hauch Unschärfe dahinter, damit sich
   Inhalt sichtbar darunter schiebt, statt hart durchzuscheinen. */

/* ─── Hero mit Bild: das Motiv ganz zeigen, die Raender fuellen ─────────────────────────────────
   Gemessen bei starkestraining: Das Bild ist 950x1020 (Hochformat), der Hero auf einem breiten
   Schirm 2300x640. Mit `background-size: cover` wird das Bild dafuer **2,42-fach hochskaliert** und
   auf ein Viertel seiner Hoehe beschnitten — ein 950px-Foto, auf 2300px aufgeblasen. Genau das
   sieht man ihm an.

   Statt das Motiv aufzublasen, steht es jetzt in seiner Groesse da, und die Flaeche daneben traegt
   dasselbe Bild als weichgezeichneten Grund. Drei Ebenen, ohne ein einziges zusaetzliches Element:

     1. der Hero selbst   das Bild formatfuellend (`cover`) — der ROHE Grund
     2. ::after           `backdrop-filter` zeichnet Ebene 1 weich, und die EIGENE Flaeche derselben
                          Regel malt das Bild scharf und vollstaendig (`contain`) darueber
     3. ::before          die vorhandene Abdunklung, danach der Text

   Der Kniff steckt in Ebene 2: `backdrop-filter` wirkt auf das, was HINTER dem Element liegt; der
   eigene Hintergrund wird anschliessend unveraendert darueber gemalt. Ein Element, zwei Wirkungen —
   sonst braeuchte es ein viertes, und `::before` ist von der Abdunklung belegt.

   `background-image: inherit` holt die Datei vom Hero. Sie steht dort als Inline-Stil am Baustein
   und ist im Stylesheet nicht bekannt — anders waere sie hier gar nicht erreichbar.

   Wo ohne `backdrop-filter` gerendert wird, bleibt Ebene 1 sichtbar: dasselbe Bild wie bisher,
   nur mit dem scharfen Motiv darueber. Kein Bruch, nur weniger schoen. */
.site-data .nsite-hero--image::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;

    /* Die scharfe Ebene: ganz zu sehen, nichts abgeschnitten, nichts hochskaliert. */
    background-image: inherit;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;

    /* Die weiche Ebene: gilt fuer alles dahinter, also fuer den formatfuellenden Grund.

       Kraeftig dosiert, und das aus einem Grund: Bei schwacher Unschaerfe blieb hinter dem Motiv ein
       riesiges, klar erkennbares zweites Gesicht stehen — daneben las sich die Kante zwischen scharf
       und weich wie zwei aneinandergeklebte Bilder. Erst wenn der Grund zur FARBFLAECHE wird, traegt
       er das Motiv, statt mit ihm zu konkurrieren. */
    backdrop-filter: blur(64px) saturate(.85) brightness(.55);
    -webkit-backdrop-filter: blur(64px) saturate(.85) brightness(.55);
}

/* Steht der Text links, gehoert das Motiv nach rechts — sonst liegen beide uebereinander. Buendig
   an der Kante, nicht mit Abstand davor: Ein Streifen Grund rechts daneben liesse das Motiv wie ein
   eingesetztes Panel wirken; an der Kante laeuft es aus dem Bild und hat nur EINE sichtbare Naht. */
.site-data .nsite-hero--left.nsite-hero--image::after { background-position: right center; }

/* Abdunklung und Text ueber beide Bildebenen. `::before` traegt bisher keinen Stapelwert; ohne ihn
   laege es unter dem `::after` und wuerde nur den weichen Grund abdunkeln, nicht das Motiv. */
.site-data .nsite-hero--image::before { z-index: 1; }
.site-data .nsite-hero--image .nsite-hero__inner { z-index: 2; }

/* Auf schmalen Schirmen ist die Flaeche neben dem Motiv kaum noch da — dort darf das Bild wieder
   formatfuellend stehen, sonst schrumpft es auf einen Streifen in der Mitte. */
@media (max-width: 700px) {
    /* `.nsite-hero--left` mitgeschrieben, obwohl es hier nichts auswaehlt: Ohne die Klasse haette
       diese Regel 0,2,0 und die Ausrichtungsregel darueber 0,3,0 — die Medienabfrage aendert an der
       Spezifitaet NICHTS. Das Bild waere auf dem Telefon rechts ausgerichtet geblieben und haette
       das Gesicht angeschnitten. */
    .site-data .nsite-hero--image::after,
    .site-data .nsite-hero--left.nsite-hero--image::after {
        background-size: cover;
        background-position: center;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
}

/* ─── Marke: Logo und Wortmarke ──────────────────────────────────────────────────────────────────
   Anordnung als Einstellung je Site (`SiteMarkenlayout`), nicht als Nebenwirkung. Vorher war
   `.nsite-brand` ein `display: block` und das Logo ein `display: block` — der Text stand damit
   ZWANGSLAEUFIG darunter, die Marke war 130px hoch und trieb den Kopf auf einem Telefon auf 237px.

   Flex mit `align-items: center` stellt beides nebeneinander auf eine gemeinsame Mittelachse; die
   Modifier-Klasse dreht die Richtung. Mehr braucht die Unterscheidung nicht. */
.site-data .nsite-brand {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    line-height: 1.15;
}
.site-data .nsite-brand--stack {
    flex-direction: column;
    align-items: flex-start;
    gap: .35rem;
}
/* Im Kopf darf die Wortmarke nicht umbrechen, solange Platz ist — sonst waechst der Kopf mit dem
   Namen statt mit dem Fenster. Auf sehr schmalen Schirmen greift die Regel weiter unten. */
.site-data .nsite-brand__name { white-space: nowrap; }

/* ─── Menue auf schmalen Schirmen ────────────────────────────────────────────────────────────────
   Gemessen bei starkestraining, 9 Links: bei 390px stand der Kopf 237px hoch — 28 % des Schirms,
   die Navigation auf DREI Zeilen. Ein Kopf, der ein Viertel der Seite verbraucht, bevor der Inhalt
   anfaengt, ist kein Kopf mehr, sondern eine Seite fuer sich.

   Der Schalter ist ein Kontrollkaestchen, kein Skript: Die oeffentlichen Seiten rendern
   serverseitig, und ein Menue, das erst nach `blazor.web.js` funktioniert, waere auf einem
   langsamen Telefon genau dann tot, wenn man es braucht.

   WANN umgeschaltet wird, haengt an der Anzahl der Links — und die ist je Site verschieden.
   Gemessen: Neun Links passen erst ab ~1150px in eine Zeile, vier schon ab ~700px. Ein fester
   Umschaltpunkt waere fuer die eine Site zu frueh und fuer die andere zu spaet. Das Markup traegt
   deshalb `nsite-nav--viele`, sobald es mehr als sechs Links sind, und die schalten frueher um.

   Umgesetzt ueber Variablen statt zweier vollstaendiger Regelsaetze: Nur die WERTE stehen doppelt,
   die Regeln daneben genau einmal. */
.site-data .nsite-nav {
    --nav-burger: none;
    --nav-links: flex;
    --nav-links-richtung: row;
    --nav-links-basis: auto;
    --nav-links-abstand: 1.4rem;
    --nav-links-oben: 0;
    --nav-links-linie: 0;
    /* `align-items` bedeutet je nach Richtung etwas anderes: in der Zeile senkrecht mittig, in der
       Spalte waagerecht. Die Basisregel in site.css setzt `center` — aufgeklappt standen die Links
       dadurch zentriert statt an einer Kante, jeder mit einer anderen Zeilenbreite. */
    --nav-links-quer: center;
}
@media (max-width: 900px) {
    .site-data .nsite-nav {
        --nav-burger: flex; --nav-links: none; --nav-links-richtung: column;
        --nav-links-basis: 100%; --nav-links-abstand: 0; --nav-links-oben: .5rem; --nav-links-linie: 1px;
        --nav-links-quer: stretch;
    }
}
@media (max-width: 1200px) {
    .site-data .nsite-nav--viele {
        --nav-burger: flex; --nav-links: none; --nav-links-richtung: column;
        --nav-links-basis: 100%; --nav-links-abstand: 0; --nav-links-oben: .5rem; --nav-links-linie: 1px;
        --nav-links-quer: stretch;
    }
}

/* Das Kaestchen traegt nur den Zustand — weggeblendet, aber MIT Tastatur erreichbar. `display:none`
   waere hier falsch: der Schalter waere dann fuer die Tastatur verschwunden. */
.site-data .nsite-nav__switch {
    position: absolute;
    width: 1px; height: 1px;
    margin: 0; padding: 0; border: 0;
    clip-path: inset(50%);
    overflow: hidden;
}

/* Umbruch erlauben: Marke und Schalter in der ersten Zeile, die Navigation als volle zweite. */
.site-data.nsite-app > .nsite-nav { flex-wrap: wrap; row-gap: 0; }

.site-data .nsite-nav__burger {
    display: var(--nav-burger);
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    /* `border-box`, sonst kommen die 10px Innenabstand auf die 44px OBEN DRAUF und der Schalter
       misst 64x64 — dieselbe Falle wie bei den Eingabefeldern der Kontaktkarte. */
    box-sizing: border-box;
    flex: 0 0 auto;
    width: 44px; height: 44px;        /* 44px: die uebliche Mindestgroesse fuer einen Finger */
    margin-left: auto;
    padding: 10px;
    border-radius: var(--rund-klein);
    cursor: pointer;
}
.site-data .nsite-nav__burger span {
    display: block;
    height: 2px;
    background: var(--ink, #1f2937);
    border-radius: 2px;
    transition: transform .2s ease, opacity .2s ease;
}

/* Zugeklappt ist der Normalfall — auf dem grossen Schirm steht `--nav-links` auf `flex`. */
.site-data .nsite-nav__links {
    display: var(--nav-links);
    flex-basis: var(--nav-links-basis);
    flex-direction: var(--nav-links-richtung);
    gap: var(--nav-links-abstand);
    align-items: var(--nav-links-quer);
    margin-top: var(--nav-links-oben);
    border-top: var(--nav-links-linie) solid var(--line, #eceef2);
}
/* Aufgeklappt gewinnt ueber die Variable (0,3,0 gegen 0,2,0). */
.site-data .nsite-nav__switch:checked ~ .nsite-nav__links { display: flex; }

/* Die Marke darf schrumpfen und umbrechen, der Schalter nicht.

   Basis 0, NICHT `auto`: Bei `flex-wrap` wird umgebrochen, BEVOR geschrumpft wird. Mit
   `flex-basis: auto` fordert die Marke ihre volle Inhaltsbreite an (gemessen 298px), der Schalter
   passt daneben nicht mehr und rutscht in eine zweite Zeile — der Kopf wuchs dadurch von 74 auf
   112px. Mit Basis 0 nimmt die Marke, was nach dem Schalter uebrig ist, und ihr Text bricht darin
   um. Gilt nur, wenn der Schalter sichtbar ist. */
@media (max-width: 1200px) {
    .site-data .nsite-nav--viele .nsite-brand { min-width: 0; flex: 1 1 0; }
    .site-data .nsite-nav--viele .nsite-brand__name { white-space: normal; }
}
@media (max-width: 900px) {
    .site-data .nsite-brand { min-width: 0; flex: 1 1 0; }
    .site-data .nsite-brand__name { white-space: normal; }
}

/* Aufgeklappt: hohe Trefferflaechen statt enger Textzeilen. */
.site-data .nsite-nav__switch:checked ~ .nsite-nav__links a {
    padding: .85rem .25rem;
    border-bottom: 1px solid var(--line, #eceef2);
}
.site-data .nsite-nav__switch:checked ~ .nsite-nav__links a:last-child { border-bottom: 0; }

/* Aufgeklappt wird aus den drei Strichen ein Kreuz — der Schalter zeigt, was er tut. */
.site-data .nsite-nav__switch:checked ~ .nsite-nav__burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.site-data .nsite-nav__switch:checked ~ .nsite-nav__burger span:nth-child(2) { opacity: 0; }
.site-data .nsite-nav__switch:checked ~ .nsite-nav__burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Sichtbarer Fokus fuer die Tastatur: Das Kaestchen selbst ist weggeblendet, also muss die
   Beschriftung den Fokus zeigen. Ohne das waere der Schalter per Tastatur unsichtbar. */
.site-data .nsite-nav__switch:focus-visible ~ .nsite-nav__burger {
    outline: 2px solid var(--brand, #e8590c);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .site-data .nsite-nav__burger span { transition: none; }
}

.site-data.nsite-app > .nsite-nav { flex-wrap: wrap; row-gap: 0; }

/* Der Knopf im Kopf gehoert neben die Marke, nicht in eine eigene Zeile — sobald das Menue
   eingeklappt ist. */
@media (max-width: 1200px) {
    .site-data .nsite-nav--viele .nsite-nav__cta { order: -1; margin-left: auto; }
}
@media (max-width: 900px) {
    .site-data .nsite-nav__cta { order: -1; margin-left: auto; }
}

.site-data.nsite-app > .nsite-nav {
    background: color-mix(in srgb, var(--bg, #fff) 88%, transparent);
    backdrop-filter: saturate(1.4) blur(10px);
    border-bottom: 1px solid color-mix(in srgb, var(--ink, #1f2937) 8%, transparent);
    padding-block: .85rem;
}
.site-data .nsite-nav__links a {
    position: relative;
    padding-block: .3rem;
    font-weight: 500;
}
/* Unterstrich wächst aus der Mitte — ruhiger als ein Farbwechsel des ganzen Wortes. */
.site-data .nsite-nav__links a::after {
    content: "";
    position: absolute;
    left: 50%;
    right: 50%;
    bottom: 0;
    height: 2px;
    border-radius: 2px;
    background: var(--brand, #e8590c);
    transition: left .18s ease, right .18s ease;
}
.site-data .nsite-nav__links a:hover::after { left: 0; right: 0; }

/* ─── Fußzeile ───────────────────────────────────────────────────────────────────────────────────
   Mehr Luft, klarere Trennung der Bereiche. */

.site-data .nsite-footer { padding-block: var(--takt-klein); }
.site-data .nsite-footer__inner { gap: 1rem; }

/* ─── Bewegung nur, wenn sie gewünscht ist ───────────────────────────────────────────────────────
   Wer im Betriebssystem „weniger Bewegung" eingestellt hat, bekommt keine. Das ist keine Kür: Für
   manche Menschen lösen bewegte Oberflächen Übelkeit aus. */

@media (prefers-reduced-motion: reduce) {
    .site-data *,
    .site-data *::before,
    .site-data *::after {
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
    }
    .site-data .nsite-btn:hover,
    .site-data .nsite-card:hover { transform: none; }
}
