﻿/* ── Neotec-Website (zweites BusinessOS-Produkt, Plattform-Beweis) ──────────────────────────
   Eigenes, GA-unabhängiges Chrome + Marketing-Baustein-Styles (nsite-*). */

.nsite-app {
    --ns-ink: #14213d;
    --ns-accent: #2b59ff;
    --ns-bg: #f6f8fc;
    --ns-line: #e4e8f2;
    min-height: 100vh; display: flex; flex-direction: column;
    background: var(--ns-bg); color: var(--ns-ink);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Nav */
.nsite-nav {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: 1rem 2rem; background: #fff; border-bottom: 1px solid var(--ns-line);
    position: sticky; top: 0; z-index: 10;
}
.nsite-brand { font-weight: 800; font-size: 1.25rem; color: var(--ns-ink); text-decoration: none; letter-spacing: -.01em; }
.nsite-brand span { color: var(--ns-accent); }
.nsite-nav__links { display: flex; gap: 1.4rem; align-items: center; }
.nsite-nav__links a { color: var(--ns-ink); text-decoration: none; font-weight: 500; }
.nsite-nav__links a:hover { color: var(--ns-accent); }
.nsite-nav__ext { color: var(--ns-accent) !important; }

.nsite-main { flex: 1; }

/* Hero */
.nsite-hero {
    background: linear-gradient(135deg, #14213d 0%, #2b59ff 100%); color: #fff;
    padding: 5rem 2rem; text-align: center;
}
.nsite-hero__inner { max-width: 820px; margin: 0 auto; }
/* Vorzeile, Ausrichtung und Hintergrundbild (mit der ersten Kunden-Migration dazugekommen).
   Das Bild kommt als Inline-Style vom Baustein; hier liegen nur Abdunklung und Schriftfarbe. */
.nsite-hero__eyebrow { display: block; margin-bottom: .6rem; font-size: .85rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; opacity: .85; }
.nsite-hero--left { text-align: left; justify-content: flex-start; }
.nsite-hero--left .nsite-hero__inner { margin: 0; }
/* Mindesthoehe (Feld „Höhe" am Baustein). Ohne sie waechst der Hero nur mit seinem Inhalt — bei einem
   Hintergrundbild mit `cover` entscheidet die Hoehe aber, wie viel vom Motiv zu sehen ist: derselbe
   Hero war bei der ersten Uebernahme 359px statt 679px hoch und schnitt das Gesicht an. Nur wirksam,
   wenn eine Stufe gewaehlt ist — ohne Klasse bleibt alles wie bisher (Website und GA unveraendert).
   Erst mit der Stufe wird der Hero zum Flex-Container, damit der Inhalt vertikal mittig steht. */
.nsite-hero--h-sm, .nsite-hero--h-md, .nsite-hero--h-full {
    display: flex; align-items: center; justify-content: center;
}
.nsite-hero--h-sm .nsite-hero__inner,
.nsite-hero--h-md .nsite-hero__inner,
.nsite-hero--h-full .nsite-hero__inner { width: 100%; }
.nsite-hero--h-sm { min-height: 40vh; }
.nsite-hero--h-md { min-height: 60vh; }
.nsite-hero--h-full { min-height: 100vh; }
.nsite-hero--image { position: relative; background-size: cover; background-position: center; }

/* Ein Hero MIT Hintergrundbild braucht eine Mindesthoehe — sonst bestimmt die Textlaenge, wie viel
   vom Motiv zu sehen ist, und nicht das Motiv selbst.

   Gemessen bei der Kundenseite (Bild 950x1020, Hochformat): der Hero wurde 351px hoch, davon waren
   26 % des Bildes sichtbar — genau der Streifen mit Mund und Kinn. Das Gesicht war abgeschnitten.
   Mit Mindesthoehe sind es rund zwei Drittel, und das Motiv steht.

   Nur wenn KEINE Stufe gewaehlt ist: „sm/md/full" bleiben unangetastet, und ein Hero ohne Bild
   waechst weiter mit seinem Inhalt (Vorgabe „auto" bleibt fuer ihn richtig). `clamp` statt 60vh,
   damit der Hero auf einem kurzen Fenster nicht die ganze Seite einnimmt. */
.nsite-hero--image:not(.nsite-hero--h-sm):not(.nsite-hero--h-md):not(.nsite-hero--h-full) {
    display: flex;
    align-items: center;
    min-height: clamp(360px, 56vh, 640px);
}
.nsite-hero--image:not(.nsite-hero--h-sm):not(.nsite-hero--h-md):not(.nsite-hero--h-full) .nsite-hero__inner {
    width: 100%;
}
.nsite-hero--image .nsite-hero__inner { position: relative; z-index: 1; }
/* Abdunklung als eigene Ebene, damit sie den Text NICHT mit einfärbt. */
.nsite-hero--image::before { content: ""; position: absolute; inset: 0; background: rgba(10, 20, 26, .45); }
.nsite-hero--overlay-none::before { background: none; }
.nsite-hero--overlay-light::before { background: rgba(10, 20, 26, .25); }
.nsite-hero--overlay-strong::before { background: rgba(10, 20, 26, .62); }
.nsite-hero--light { color: #fff; }
.nsite-hero--light .nsite-hero__title, .nsite-hero--light .nsite-hero__sub { color: #fff; }

/* Dunkle Schrift braucht einen hellen Grund — sonst steht sie auf dem dunkelblauen Standard-Verlauf
   des Heros und ist unlesbar. Gemessen auf der uebernommenen Kundenseite: Titel #1f2937 auf #14213d,
   Kontrast rund 1,2:1 (lesbar waeren 4,5:1); die Ueberschrift war praktisch unsichtbar.

   Das ist KEIN Import-Fehler: In neoCms beschreibt `variant` das ganze Design, nicht nur die Schrift
   — `.cms-hero--light` setzt dort `background: var(--cms-bg-alt)` UND `color: var(--cms-ink)`. Der
   Import uebertraegt die Schriftfarbe richtig, nur den zugehoerigen hellen Grund gab es hier nie.
   Dieselben Token sind laengst da (`--bg-alt` traegt bei der Kundenseite bereits #fff7f1 aus der
   Uebernahme) — sie wurden nur nicht benutzt.

   Nur OHNE Hintergrundbild: mit Bild bestimmt das Bild den Grund, und die Abdunklung liegt darueber. */
.nsite-hero--dark:not(.nsite-hero--image) {
    background: var(--bg-alt, #f6f7fb);
    color: var(--ink, #0a1124);
}

.nsite-hero__title { font-size: 2.8rem; font-weight: 800; margin: 0 0 1rem; letter-spacing: -.02em; line-height: 1.1; }
.nsite-hero__sub { font-size: 1.2rem; opacity: .92; margin: 0 0 1.6rem; }

/* `color: inherit` ist Pflicht, keine Kosmetik — dieselbe Falle wie beim Newsletter-Band: ga-theme.css
   wird auf jedem Host geladen und faerbt h1..h4 per ELEMENT-Selektor auf --ga-ink. Geerbtes Weiss
   verliert dagegen, die Ueberschrift stuende dunkel auf dunklem Grund. Klassen-Spezifitaet gewinnt.
   Damit folgt der Titel IMMER der Hero-Farbe, statt fuer jede Variante eine eigene Regel zu brauchen. */
.nsite-hero__title, .nsite-hero__sub { color: inherit; }

/* Sections */
.nsite-section { max-width: 1040px; margin: 0 auto; padding: 3.5rem 2rem; }
.nsite-section__h { font-size: 1.9rem; font-weight: 700; margin: 0 0 1.4rem; text-align: center; letter-spacing: -.01em; }
.nsite-prose { max-width: 720px; margin: 0 auto; font-size: 1.05rem; line-height: 1.7; }
.nsite-prose p { margin: 0 0 1rem; }

/* Feature grid */
.nsite-features { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.2rem; }
.nsite-feature {
    background: #fff; border: 1px solid var(--ns-line); border-radius: 14px; padding: 1.6rem;
    text-align: center; box-shadow: 0 1px 3px rgba(20,33,61,.05);
}
.nsite-feature__icon { font-size: 2.2rem; line-height: 1; margin-bottom: .6rem; }
.nsite-feature__title { font-weight: 700; font-size: 1.1rem; margin-bottom: .35rem; }
.nsite-feature__text { color: #5a6478; font-size: .95rem; line-height: 1.5; }

/* Bild & Text — zweispaltig, per Modifier gespiegelt; stapelt auf schmalen Viewports (Text zuerst). */
.nsite-mediatext { padding: 3rem 2rem; }
.nsite-mediatext__inner {
    max-width: 1040px; margin: 0 auto; display: grid; grid-template-columns: 1fr 1fr;
    gap: 2.4rem; align-items: center;
}
.nsite-mediatext--img-left .nsite-mediatext__media { order: -1; }
.nsite-mediatext__media img { width: 100%; height: auto; border-radius: 14px; display: block; box-shadow: 0 4px 20px rgba(20,33,61,.1); }
.nsite-mediatext__h { font-size: 1.7rem; font-weight: 700; margin: 0 0 .8rem; letter-spacing: -.01em; }
.nsite-mediatext__body p { margin: 0 0 1rem; line-height: 1.65; color: #33405c; }
.nsite-mediatext__body .nsite-btn { margin-top: .4rem; }
@media (max-width: 720px) {
    .nsite-mediatext__inner { grid-template-columns: 1fr; gap: 1.4rem; }
    .nsite-mediatext--img-left .nsite-mediatext__media,
    .nsite-mediatext__media { order: 0; }   /* gestapelt immer Text zuerst */
    .nsite-mediatext__body { order: -1; }
}

/* Newsletter — Anmeldeband, Formular inline (E-Mail + Button), Consent darunter.
   Die Farben stehen NICHT fest, sondern kommen aus den Tokens der Site (--brand/--ink/--bg-alt/--line,
   Rückfall auf die generischen --ns-*). Sonst trägt das Band auf jeder Site das Blau der ersten.
   Welche der vier Darstellungen greift, wählt der Redakteur am Baustein (Config „tone");
   ohne Auswahl ist es „none" — kein eigener Hintergrund, der Baustein sieht aus wie die Seite. */
.nsite-newsletter { padding: 3.5rem 2rem; }
.nsite-newsletter__inner { max-width: 720px; margin: 0 auto; text-align: center; }
.nsite-newsletter__label { text-transform: uppercase; letter-spacing: .08em; font-size: .8rem; font-weight: 700; opacity: .85; }
/* `color: inherit` ist Pflicht, keine Kosmetik: ga-theme.css wird auf jedem Host geladen und setzt
   h1..h4 per ELEMENT-Selektor auf --ga-ink. Geerbtes Weiß verliert dagegen — die Überschrift stünde
   sonst dunkel auf dem dunklen Band. Klassen-Spezifität gewinnt. */
.nsite-newsletter__h { font-size: 1.8rem; font-weight: 700; margin: .3rem 0 .6rem; color: inherit; }
.nsite-newsletter__intro { opacity: .9; margin: 0 auto 1.4rem; max-width: 560px; }
/* Raster statt zentriertem Flex: Eingabefeld | Knopf, die Einwilligung darunter über beide Spalten.
   Vorher zentrierte sich die Einwilligungszeile über die volle Breite für sich und das Feld-plus-Knopf-Paar
   für sich — zwei unabhängige Zentrierungen ergeben nie dieselbe Kante, der Haken stand knapp neben dem
   Eingabefeld. Im Raster teilen sich beide die linke Spaltenkante, und `margin:auto` hält die Gruppe mittig.
   Feste Maximalbreite statt `fit-content`: die Einwilligung überspannt beide Spalten, ihre Textlänge würde
   die Spalten sonst mit aufblasen — der Knopf rutschte weit nach rechts. */
.nsite-newsletter__form {
    display: grid; grid-template-columns: 1fr auto; gap: .6rem;
    align-items: end; max-width: 520px; margin: 0 auto;
}
@media (max-width: 560px) {
    .nsite-newsletter__form { grid-template-columns: 1fr; }
}
.nsite-newsletter__field { display: flex; flex-direction: column; gap: .3rem; text-align: left; min-width: 0; }
.nsite-newsletter__field span { font-size: .82rem; font-weight: 600; opacity: .9; }
.nsite-newsletter__field input {
    padding: .75rem 1rem; border: 1px solid transparent; border-radius: var(--radius-btn, 999px);
    font: inherit; font-size: 1rem; width: 100%; background: #fff; color: var(--ink, var(--ns-ink, #14213d));
}
.nsite-newsletter__consent { grid-column: 1 / -1; display: flex; gap: .5rem; align-items: flex-start; justify-content: flex-start; font-size: .85rem; opacity: .9; margin-top: .3rem; }
.nsite-newsletter__consent span { text-align: left; }
/* Der Haken sitzt auf der Kante des Eingabefelds — nicht auf der Textkante. Ohne das eigene margin
   käme je nach Browser noch ein Standardabstand dazu. */
.nsite-newsletter__consent input { margin: .15rem 0 0; flex-shrink: 0; }
.nsite-newsletter__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.nsite-newsletter__ok { border-radius: 12px; padding: 1rem 1.2rem; font-weight: 600; }
.nsite-newsletter__err { font-weight: 600; margin-bottom: .8rem; }

/* Darstellung „accent": Verlauf von der Textfarbe zur Markenfarbe der Site. */
.nsite-newsletter--accent {
    background: linear-gradient(135deg, var(--ink, var(--ns-ink, #14213d)) 0%, var(--brand, var(--ns-accent, #2b59ff)) 100%);
    color: #fff;
}
/* „dark": ruhiges dunkles Band — nimmt den Dunkelverlauf des Themes, wenn es einen hat. */
.nsite-newsletter--dark { background: var(--bg-dark-grad, var(--ns-ink, #14213d)); color: #fff; }

.nsite-newsletter--accent .nsite-newsletter__ok,
.nsite-newsletter--dark .nsite-newsletter__ok { background: rgba(255,255,255,.14); }
.nsite-newsletter--accent .nsite-newsletter__err,
.nsite-newsletter--dark .nsite-newsletter__err { color: #ffd7d7; }

/* „none" (Vorgabe): gar kein eigener Hintergrund — der Baustein sitzt auf der Fläche der Seite und
   erbt deren Schrift. „light": dieselbe Sache, nur leicht abgesetzt. Beide stehen auf hellem Grund,
   teilen sich also alles Weitere: Marken-Vorzeile, kräftige Überschrift, Eingabefeld mit sichtbarer
   Kante (auf den farbigen Bändern braucht es die nicht, dort trägt schon der Kontrast). */
.nsite-newsletter--none { background: transparent; color: inherit; }
.nsite-newsletter--light {
    background: var(--bg-alt, var(--ns-bg, #f6f8fc));
    color: var(--ink-soft, var(--ns-ink, #14213d));
}
.nsite-newsletter--none .nsite-newsletter__label,
.nsite-newsletter--light .nsite-newsletter__label { color: var(--brand, var(--ns-accent, #2b59ff)); opacity: 1; }
/* Die Fläche trägt den weichen Fließtext-Ton — die Überschrift muss die kräftige Textfarbe holen,
   sonst steht sie grau statt schwarz da (auf den farbigen Bändern ist beides weiß). */
.nsite-newsletter--none .nsite-newsletter__h,
.nsite-newsletter--light .nsite-newsletter__h { color: var(--ink, var(--ns-ink, #14213d)); }
.nsite-newsletter--none .nsite-newsletter__field input,
.nsite-newsletter--light .nsite-newsletter__field input { border-color: var(--line-strong, var(--ns-line, #e4e8f2)); }
.nsite-newsletter--none .nsite-newsletter__ok,
.nsite-newsletter--light .nsite-newsletter__ok {
    background: #fff; border: 1px solid var(--line, var(--ns-line, #e4e8f2)); color: #1f7a3a;
}
.nsite-newsletter--none .nsite-newsletter__err,
.nsite-newsletter--light .nsite-newsletter__err { color: #c0392b; }

/* Sektions-Überschrift */
.nsite-secthead { max-width: 720px; margin: 0 auto; padding: 2.4rem 2rem 0; }
.nsite-secthead--center { text-align: center; }
.nsite-secthead--left { text-align: left; margin: 0; }
.nsite-secthead__label { text-transform: uppercase; letter-spacing: .08em; font-size: .8rem; font-weight: 700; color: var(--ns-accent); }
.nsite-secthead__h { font-size: 1.9rem; font-weight: 700; margin: .3rem 0 .5rem; letter-spacing: -.01em; }
.nsite-secthead__lead { color: #5a6478; font-size: 1.05rem; line-height: 1.6; margin: 0; }

/* Kennzahlen */
.nsite-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1.4rem; }
.nsite-stat { text-align: center; }
.nsite-stat__value { font-size: 2.4rem; font-weight: 800; color: var(--ns-accent); letter-spacing: -.02em; }
.nsite-stat__label { color: #5a6478; font-size: .95rem; margin-top: .2rem; }

/* Karten-Grid */
.nsite-cardgrid { display: grid; gap: 1.2rem; }
.nsite-cardgrid--cols-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.nsite-cardgrid--cols-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.nsite-cardgrid--cols-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.nsite-card {
    display: flex; flex-direction: column; background: #fff; border: 1px solid var(--ns-line);
    border-radius: 14px; overflow: hidden; text-decoration: none; color: inherit;
    box-shadow: 0 1px 3px rgba(20,33,61,.05); transition: box-shadow .15s, transform .15s;
}
a.nsite-card:hover { box-shadow: 0 6px 22px rgba(20,33,61,.12); transform: translateY(-2px); }
.nsite-card__img img { width: 100%; height: 170px; object-fit: cover; display: block; }
.nsite-card__body { padding: 1.2rem 1.3rem; display: flex; flex-direction: column; gap: .35rem; }
.nsite-card__icon { font-size: 1.8rem; line-height: 1; }
.nsite-card__title { font-weight: 700; font-size: 1.1rem; }
.nsite-card__text { color: #5a6478; font-size: .95rem; line-height: 1.5; }
.nsite-card__cta { color: var(--ns-accent); font-weight: 600; font-size: .9rem; margin-top: .2rem; }

/* Pills / Tags */
.nsite-pills { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; }
.nsite-pill { background: #fff; border: 1px solid var(--ns-line); border-radius: 999px; padding: .35rem .9rem; font-size: .9rem; font-weight: 500; color: #33405c; }

/* Einzelbild */
.nsite-image { text-align: center; }
.nsite-image img { max-width: 100%; height: auto; border-radius: 14px; box-shadow: 0 4px 20px rgba(20,33,61,.1); }
.nsite-image figcaption { color: #5a6478; font-size: .9rem; margin-top: .6rem; }

/* Abstand */
.nsite-spacer--sm { height: 1.5rem; }
.nsite-spacer--md { height: 3rem; }
.nsite-spacer--lg { height: 5rem; }

/* HTML-Embed */
.nsite-html :where(iframe, video, img) { max-width: 100%; }

/* Kontaktformular — wie beim Newsletter kommen die Farben aus den Tokens der Site (Rückfall auf --ns-*),
   damit das Formular nicht auf jeder Site das Blau und Grau der ersten trägt. */
.nsite-contact { max-width: 640px; }
.nsite-contact__intro { text-align: center; color: var(--muted, #5a6478); margin: 0 auto 1.4rem; }
.nsite-contact__form { display: grid; grid-template-columns: 1fr 1fr; gap: .9rem; }
.nsite-contact__field { display: flex; flex-direction: column; gap: .3rem; text-align: left; }
.nsite-contact__field--full, .nsite-contact__consent, .nsite-contact__form > button { grid-column: 1 / -1; }
.nsite-contact__field span { font-size: .82rem; font-weight: 600; color: var(--ink, #4a5266); }
.nsite-contact__field input, .nsite-contact__field textarea {
    padding: .7rem .9rem; border: 1px solid var(--line-strong, var(--ns-line, #e4e8f2));
    border-radius: var(--radius-btn, 10px); font: inherit; width: 100%; background: #fff;
    color: var(--ink, var(--ns-ink, #14213d));
}
.nsite-contact__field textarea { resize: vertical; }
.nsite-contact__consent { display: flex; gap: .5rem; align-items: flex-start; font-size: .88rem; color: var(--ink-soft, #5a6478); }
.nsite-contact__consent input { margin: .15rem 0 0; flex-shrink: 0; }
.nsite-contact__form > button { justify-self: start; }
.nsite-contact__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.nsite-contact__ok { background: #eaf7ee; border: 1px solid #bfe6c9; border-radius: var(--radius-card, 12px); padding: 1rem 1.2rem; text-align: center; font-weight: 600; color: #1f7a3a; }
.nsite-contact__err { color: #c0392b; font-weight: 600; text-align: center; margin-bottom: .8rem; }
@media (max-width: 560px) { .nsite-contact__form { grid-template-columns: 1fr; } }

/* Leere Felder reservieren keinen Platz. Klingt selbstverstaendlich, ist es im Markup aber nicht:
   Ein leeres `<h2>` hat zwar keine Hoehe, seine Raender gelten trotzdem. Auf der Startseite von
   starkestraining steht die Ueberschrift als eigener Baustein UEBER dem Handlungsaufruf — dessen
   eigene Ueberschrift und Beischrift blieben leer und schoben die dunkle Flaeche um 22px auf,
   fuer nichts. Wer im Editor ein Feld leer laesst, meint „weg", nicht „unsichtbar, aber da". */
.nsite-cta__h:empty, .nsite-cta__t:empty,
.nsite-newsletter__h:empty, .nsite-newsletter__intro:empty, .nsite-newsletter__label:empty {
    display: none;
}

/* CTA band */
.nsite-cta {
    background: var(--ns-ink); color: #fff; text-align: center; padding: 3.5rem 2rem;
}
.nsite-cta__h { font-size: 1.8rem; font-weight: 700; margin: 0 0 .6rem; }
.nsite-cta__t { opacity: .88; margin: 0 0 1.4rem; }

/* Mit der ersten Kunden-Migration dazugekommen: Innenabstand am Bereich, Ausrichtung im Fließtext,
   zurückhaltender Knopf für die Nebenhandlung. */
.bos-section--pad-none { padding-top: 0; padding-bottom: 0; }
.bos-section--pad-sm { padding-top: 1.5rem; padding-bottom: 1.5rem; }
.bos-section--pad-md { padding-top: clamp(2rem, 4vw, 3rem); padding-bottom: clamp(2rem, 4vw, 3rem); }
.bos-section--pad-lg { padding-top: clamp(3rem, 6vw, 5rem); padding-bottom: clamp(3rem, 6vw, 5rem); }
.nsite-section--center { text-align: center; }
.nsite-section--center .nsite-prose { text-align: left; display: inline-block; }
.nsite-btn--ghost { background: transparent; color: inherit; border: 1px solid currentColor; }
.nsite-btn--ghost:hover { background: rgba(255, 255, 255, .12); }

/* Chrome aus den Daten einer Site (DataChrome) — Kopf, Navigation, Fuß, Rechtslinks.
   Bewusst neutral gehalten: Struktur und Abstände hier, die Farben kommen aus den Site-Tokens
   (--brand/--ink/--line, Rückfall auf die generischen --ns-*). Die Erstprodukte bringen ihr eigenes,
   engeres Chrome mit (site-neotec / GA) — das bleibt unberührt. */
.site-data.nsite-app > .nsite-nav { position: sticky; top: 0; z-index: 50; }
.site-data .nsite-brand__logo { height: 40px; width: auto; display: block; }
.site-data .nsite-nav__links { flex-wrap: wrap; }
.site-data .nsite-nav__cta {
    padding: .6rem 1.2rem; border-radius: var(--radius-btn, 999px);
    background: var(--brand, var(--ns-accent, #2b59ff)); color: #fff;
    font-size: .9rem; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.site-data .nsite-footer {
    background: var(--ink, var(--ns-ink, #14213d)); color: rgba(255, 255, 255, .72);
    padding: clamp(2rem, 5vw, 3.5rem) 2rem 1.5rem; font-size: .9rem;
}
.site-data .nsite-footer a { color: rgba(255, 255, 255, .72); text-decoration: none; }
.site-data .nsite-footer a:hover { color: #fff; }
.site-data .nsite-footer__inner {
    max-width: 1080px; margin: 0 auto; display: flex; flex-wrap: wrap; gap: clamp(1.5rem, 4vw, 3rem);
    align-items: flex-start; justify-content: space-between; padding-bottom: 1.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, .1);
}
.site-data .nsite-footer__brand { display: flex; flex-direction: column; gap: .6rem; }
.site-data .nsite-footer__name { font-size: 1.3rem; font-weight: 800; color: #fff; }
.site-data .nsite-footer__tag, .site-data .nsite-footer__addr { margin: 0; color: rgba(255, 255, 255, .55); font-size: .82rem; line-height: 1.6; }
.site-data .nsite-footer__nav { display: flex; flex-direction: column; gap: .5rem; }
/* Rechtslinks stehen für sich: sie müssen von jeder Seite aus auffindbar sein. */
.site-data .nsite-footer__legal { max-width: 1080px; margin: 1rem auto 0; display: flex; flex-wrap: wrap; gap: 1.25rem; font-size: .82rem; }
.site-data .nsite-footer__legal a { color: rgba(255, 255, 255, .55); }
/* Deckkraft .6, nicht .4: Bei .4 mischt sich das Weiss auf dem dunklen Footer zu rgb(127,123,121)
   herunter — Kontrast 3,69 bei geforderten 4,5 fuer 12,5px. Mit .6 sind es 6,46, und auch auf einem
   weniger dunklen Footer einer anderen Kunden-Site bleiben 5,38. Eine Zeile darf zurueckhaltend
   sein, lesbar muss sie trotzdem bleiben. */
.site-data .nsite-footer__copy { max-width: 1080px; margin: 1.5rem auto 0; text-align: center; font-size: .78rem; color: rgba(255, 255, 255, .6); }

/* Buch-Angebot — Cover links, Text und Kauf rechts. Die Farben kommen wie beim Newsletter aus den
   Tokens der Site (--brand/--ink/--bg-alt), nicht aus diesem Baustein: das Cover bringt seine eigene
   Farbigkeit mit, die Seite soll sie rahmen und nicht überstimmen. */
.nsite-book { padding: clamp(2.5rem, 5vw, 4rem) 2rem; }
.nsite-book__inner {
    max-width: 1080px; margin: 0 auto; display: grid; gap: clamp(1.5rem, 4vw, 3rem);
    grid-template-columns: minmax(180px, 300px) 1fr; align-items: start;
}
.nsite-book__cover { margin: 0; }
.nsite-book__cover img {
    display: block; width: 100%; height: auto; border-radius: var(--radius-card, 12px);
    box-shadow: 0 18px 40px rgba(15, 23, 32, .22);
}
.nsite-book__label { text-transform: uppercase; letter-spacing: .08em; font-size: .8rem; font-weight: 700; opacity: .85; }
/* color: inherit wie beim Newsletter: ga-theme.css setzt h1..h4 per Element-Selektor und würde auf den
   farbigen Bändern gewinnen. */
.nsite-book__h { font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 700; margin: .3rem 0 .4rem; color: inherit; line-height: 1.15; }
.nsite-book__sub { font-size: 1.05rem; opacity: .9; margin: 0 0 .6rem; }
.nsite-book__authors { font-weight: 600; margin: 0 0 1.1rem; }
.nsite-book__text p { margin: 0 0 .8rem; line-height: 1.65; opacity: .92; }
.nsite-book__meta { font-size: .85rem; opacity: .75; margin: 1rem 0 0; }
.nsite-book__buy { margin-top: 1.6rem; }
.nsite-book__price { margin: 0; font-size: 1.5rem; font-weight: 700; display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.nsite-book__pricenote { font-size: .85rem; font-weight: 500; opacity: .75; }
.nsite-book__delivery { margin: .35rem 0 0; font-size: .9rem; opacity: .8; }
.nsite-book__form { margin: 1.1rem 0 0; }
.nsite-book__soldout { margin: 1.1rem 0 0; font-weight: 600; }
.nsite-book__err { margin: 0 0 .8rem; font-weight: 600; color: #b23; }
.nsite-book__hint { margin: 1rem 0 0; padding: .6rem .8rem; border-radius: 8px; background: #fff3bf; color: #8a6d00; font-size: .9rem; }
.nsite-book--light { background: var(--bg-alt, #f2f5fa); }
.nsite-book--accent {
    background: linear-gradient(135deg, var(--ink, var(--ns-ink, #14213d)) 0%, var(--brand, var(--ns-accent, #2b59ff)) 100%);
    color: #fff;
}
.nsite-book--dark { background: var(--bg-dark-grad, var(--ns-ink, #14213d)); color: #fff; }
.nsite-book--none { background: transparent; color: inherit; }
.nsite-book--accent .nsite-book__err, .nsite-book--dark .nsite-book__err { color: #ffd7d7; }
@media (max-width: 720px) {
    .nsite-book__inner { grid-template-columns: 1fr; justify-items: center; text-align: center; }
    .nsite-book__cover { max-width: 240px; }
    .nsite-book__price { justify-content: center; }
    .nsite-book__text p { text-align: left; }
}

/* Buttons */
.nsite-btn {
    display: inline-block; padding: .8rem 1.6rem; border-radius: 999px; font-weight: 600;
    background: #fff; color: var(--ns-accent); text-decoration: none; border: 0;
}
.nsite-btn:hover { background: #eef2ff; }
.nsite-btn--light { background: var(--ns-accent); color: #fff; }
.nsite-btn--light:hover { background: #1f47d6; }

/* Suche */
.nsite-search { display: flex; gap: .6rem; max-width: 620px; margin: 0 auto 1.4rem; }
.nsite-search__input {
    flex: 1; padding: .8rem 1rem; border: 1px solid var(--ns-line); border-radius: 999px; font-size: 1rem; background: #fff;
}
.nsite-search__meta { text-align: center; color: #5a6478; font-size: .95rem; margin: 0 auto 1rem; max-width: 720px; }
.nsite-search__meta code { background: #eef2ff; color: var(--ns-accent); padding: .05rem .35rem; border-radius: 5px; font-size: .9em; }
.nsite-search__list { max-width: 620px; margin: 0 auto; list-style: none; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.nsite-search__list li a {
    display: block; padding: .9rem 1.1rem; background: #fff; border: 1px solid var(--ns-line); border-radius: 12px;
    text-decoration: none; color: var(--ns-ink); font-weight: 600;
}
.nsite-search__list li a:hover { border-color: var(--ns-accent); color: var(--ns-accent); }

/* Footer */
.nsite-footer {
    display: flex; flex-direction: column; gap: .25rem; align-items: center; text-align: center;
    padding: 2rem; background: #fff; border-top: 1px solid var(--ns-line);
    color: #5a6478; font-size: .9rem;
}

@media (max-width: 640px) {
    .nsite-hero__title { font-size: 2rem; }
    .nsite-nav { padding: .8rem 1rem; flex-wrap: wrap; }
    .nsite-nav__links { gap: .9rem; font-size: .9rem; }
}

/* ── Page-Builder / CMS (LowCode-Tool) ──────────────────────────────────────── */
.cms { max-width: 1280px; margin: 0 auto; padding: 1.5rem; }
.cms__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: .8rem; }
/* Drei-Spalten-Builder: Baustein-Rail (schmal, links) | Editor | Vorschau. Editor und Vorschau scrollen
   je für sich (statt einer Seiten-Scrollleiste mit sticky Vorschau) und können sich gegenseitig anspringen.
   min-height:0 ist Pflicht, sonst wächst ein Grid-Kind über seine Spur hinaus statt zu scrollen. */
/* Drei echte Spalten: Palette+Seitenbaum | Einstellungen | Vorschau. Die Mitte ist begrenzt, damit
   der gewonnene Platz an die VORSCHAU geht — sie zeigt das Ergebnis und war vorher die schmalste
   Spalte. Hoehe: der Editor sitzt jetzt unter einer schmalen Kopfzeile (EditorChrome), nicht mehr
   unter Seitenleiste + Bar + Seitenkopf. */
.cms__grid {
    display: grid;
    /* Die ersten beiden Spuren sind verstellbar (Griffe, cms-builder.js schreibt die Variablen);
       die dritte bekommt den Rest. Die Werte hier sind nur der Startpunkt. */
    grid-template-columns: var(--cms-col1, 248px) 6px var(--cms-col2, 350px) 6px 1fr;
    gap: .8rem; align-items: stretch; height: calc(100vh - 5.6rem); min-height: 460px;
}
/* Ziehgriff: schmal, aber mit grosszuegiger Trefferflaeche ueber ein Pseudo-Element. */
.cms__griff { position: relative; cursor: col-resize; border-radius: 3px; background: transparent; }
.cms__griff::before { content: ""; position: absolute; inset: 0 -5px; }
.cms__griff::after { content: ""; position: absolute; inset: 30% 2px; border-radius: 3px;
    background: var(--ga-line); transition: background .12s; }
.cms__griff:hover::after, .cms__griff:focus-visible::after { background: var(--ga-accent); }
.cms__griff:focus-visible { outline: 2px solid var(--ga-accent); outline-offset: 1px; }
/* Waehrend des Ziehens nichts markieren und den Cursor halten. */
body.cms-resizing { cursor: col-resize; user-select: none; }
body.cms-resizing iframe { pointer-events: none; }
.cms__editor { display: flex; flex-direction: column; gap: .8rem; overflow-y: auto; min-height: 0; padding-right: .6rem; scroll-behavior: smooth; position: relative; }

/* Baustein-Rail: schmal links geheftet, fährt bei Hover/Fokus als Flyout aus. Der Flyout ist ABSOLUT
   positioniert und überlagert beim Ausfahren den Editor — die Grid-Spur bleibt 56px, es gibt keinen Reflow.
   Collapsed zeigt die Icon-Chips (1. Buchstabe), ausgefahren zusätzlich die vollen Labels. */
.cms__rail { display: flex; flex-direction: column; gap: .6rem; min-height: 0; }
/* Palette oben, Baum unten — beide fuer sich scrollbar, damit der Baum bei langer Palette nicht
   unerreichbar wird. */
.cms__palette { flex: 0 0 auto; max-height: 48%; overflow-y: auto; background: #fff;
    border: 1px solid var(--ga-line); border-radius: 12px; padding: .5rem .55rem; }
.cms__palette-h { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    color: var(--ga-ink); opacity: .55; margin-bottom: .35rem; }
.cms__palette-cat { font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    color: var(--ga-ink); opacity: .38; margin: .45rem 0 .25rem; }
/* Chips statt Zeilen: die Palette war eine Liste mit Icon-Badge je Baustein und brauchte die volle
   Fensterhoehe fuer ~30 Eintraege. */
.cms__palette-chips { display: flex; flex-wrap: wrap; gap: .25rem; }
.cms-chip { font: inherit; font-size: .78rem; line-height: 1.2; padding: .28rem .5rem; cursor: pointer;
    background: var(--ga-bg, #f6f8ff); border: 1px solid var(--ga-line); border-radius: 999px;
    color: var(--ga-ink); }
.cms-chip:hover { background: var(--ga-accent-soft, #eef1ff); border-color: var(--ga-accent); }

/* Seitenbaum */
.cms-tree { flex: 1; min-height: 0; overflow-y: auto; background: #fff;
    border: 1px solid var(--ga-line); border-radius: 12px; padding: .5rem .4rem; }
.cms-tree__h { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    color: var(--ga-ink); opacity: .55; margin: 0 0 .35rem .15rem; }
.cms-tree__leer { font-size: .78rem; color: var(--ga-ink); opacity: .55; margin: .2rem .15rem; }
.cms-tree__list { list-style: none; margin: 0; padding: 0; }
.cms-tree__link { display: flex; align-items: center; gap: .35rem; padding: .22rem .35rem; border-radius: 7px;
    text-decoration: none; color: var(--ga-ink); font-size: .8rem; }
.cms-tree__link:hover { background: var(--ga-accent-soft, #eef1ff); }
.cms-tree__item.is-selected > .cms-tree__link { background: var(--ga-accent-soft, #eef1ff); font-weight: 600; }
.cms-tree__ico { flex: 0 0 auto; width: 1.05rem; height: 1.05rem; display: grid; place-items: center;
    border-radius: 4px; background: var(--ga-line); font-size: .6rem; font-weight: 700; }
.cms-tree__label { flex: 0 0 auto; }
.cms-tree__text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    opacity: .5; font-size: .74rem; }
/* Labels/Überschriften erst beim Ausfahren einblenden (collapsed reine Chip-Leiste). */
.cms-field { display: flex; flex-direction: column; gap: .25rem; font-size: .9rem; }
.cms-field > span { font-weight: 600; color: #4a5266; }
.cms-field--title { background: #fff; border: 1px solid var(--ga-line); border-radius: 10px; padding: .7rem .8rem; }
.cms-input { padding: .5rem .6rem; border: 1px solid var(--ga-line); border-radius: 8px; font: inherit; width: 100%; background: #fff; }
textarea.cms-input { resize: vertical; }

.cms-block { background: #fff; border: 1px solid var(--ga-line); border-radius: 12px; padding: .9rem; display: flex; flex-direction: column; gap: .6rem; }
.cms-block__head { display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--ga-line); padding-bottom: .5rem; }
.cms-block__type { font-weight: 700; font-size: .95rem; margin-right: auto; }

/* Drag&Drop: gezogen wird am Griff, nicht an der Karte — sonst kollidiert das Ziehen mit
   dem Markieren von Text in den Feldern. */
.cms-drag { cursor: grab; color: #a8afc2; font-size: 1.05rem; line-height: 1; padding: .1rem .35rem; user-select: none; border-radius: 6px; }
.cms-drag:hover { color: var(--ga-accent); background: var(--ga-accent-soft); }
.cms-drag:active { cursor: grabbing; }
.cms-block.is-dragging { opacity: .5; outline: 2px dashed var(--ga-accent); }
.cms-block__ops { display: flex; gap: .3rem; }
.cms-iconbtn { border: 1px solid var(--ga-line); background: #fff; border-radius: 7px; width: 30px; height: 30px; cursor: pointer; font-size: .9rem; line-height: 1; }
.cms-iconbtn:hover:not(:disabled) { background: #eef2ff; border-color: var(--ga-accent); }
.cms-iconbtn:disabled { opacity: .35; cursor: default; }
.cms-iconbtn--danger:hover:not(:disabled) { background: #f7ecec; border-color: #e3bfbf; color: #8a2b2b; }

/* Vorschau ↔ Editor: Klick auf einen Baustein in der Vorschau wählt seine Karte links aus.
   Der EditMode-Wrapper .bos-edit-block ist display:contents (kein eigener Kasten) — deshalb
   zeichnen Hover/Auswahl auf seinen Kindern, nicht auf ihm selbst. */
.cms__preview-hint { font-weight: 400; text-transform: none; letter-spacing: 0; color: #8a90a2; }
.cms__preview-frame .bos-edit-block > * { cursor: pointer; transition: box-shadow .12s, outline-color .12s; outline: 2px solid transparent; outline-offset: -2px; }
.cms__preview-frame .bos-edit-block:hover > * { outline-color: #c3cbe0; }
.cms__preview-frame .bos-edit-block.is-selected > * { outline-color: var(--ga-accent); box-shadow: inset 0 0 0 100vmax rgba(98, 122, 254,.05); }

.cms-block.is-selected { border-color: var(--ga-accent); box-shadow: 0 0 0 3px rgba(98, 122, 254,.15); }

/* Repeater: wiederholbare Inhalts-Liste innerhalb eines Bausteins (Kacheln, Logos …). */
.cms-rep { display: flex; flex-direction: column; gap: .5rem; border-left: 3px solid #dfe4f0; padding-left: .7rem; }
.cms-rep__head { display: flex; align-items: baseline; justify-content: space-between; }
.cms-rep__label { font-weight: 600; font-size: .85rem; text-transform: uppercase; letter-spacing: .03em; color: #4a5266; }
.cms-rep__item { background: #fbfcff; border: 1px solid var(--ga-line); border-radius: 10px; padding: .6rem .7rem; display: flex; flex-direction: column; gap: .45rem; }
.cms-rep__item-head { display: flex; align-items: center; justify-content: space-between; }
.cms-rep__item-label { font-size: .8rem; color: #6b7387; }
.cms-rep > .ga-btn { align-self: flex-start; }

/* Slots: benannter Kind-Bereich eines Bausteins — die verschachtelten Baustein-Karten sitzen darin. */
.cms-slot { display: flex; flex-direction: column; gap: .5rem; border-left: 3px solid #cfd8ef; padding-left: .7rem; margin-top: .2rem; }
.cms-slot__head { display: flex; align-items: baseline; justify-content: space-between; }
.cms-slot__label { font-weight: 600; font-size: .78rem; text-transform: uppercase; letter-spacing: .04em; color: #6a72b0; }
.cms-slot__empty { margin: 0; }
/* Zwischenüberschrift im CMS (Site, Inhaltstyp, Formular-Abschnitt). */
.cms-site-h { margin-top: 2rem; font-size: 1.3rem; }
/* Page-Builder: Auswahl der Site, deren Seiten die Liste zeigt (statt aller Sites untereinander).
   margin-right:auto hält sie neben der Überschrift, das Anlege-Formular bleibt rechts. */
.cms-site-pick { margin-right: auto; margin-bottom: 0; }
/* Per-Slot-Palette: kompakte „+"-Chips, die nur die für den Slot erlaubten Bausteine anbieten. */
.cms-slot__add { display: flex; flex-wrap: wrap; gap: .35rem; }
.cms-slot__addbtn { font: inherit; font-size: .74rem; font-weight: 600; color: var(--ga-accent); background: #fff; border: 1px dashed var(--ga-accent); border-radius: 999px; padding: .2rem .55rem; cursor: pointer; }
.cms-slot__addbtn:hover { background: var(--ga-accent-soft, #eef2ff); }
/* Verschachtelte Karte: etwas kompakter/leiser als eine Top-Level-Karte, damit die Ebenen lesbar bleiben. */
.cms-block--nested { background: #fbfcff; padding: .7rem; gap: .5rem; }
.cms-block--nested .cms-block__type { font-size: .88rem; }

/* Speichern bleibt sichtbar. Die Leiste war zwar schon sticky, aber mit halbtransparentem Verlauf
   und ohne eigenen Grund: in der scrollenden Mittelspalte lag sie dadurch je nach Seitenlaenge halb
   hinter dem Inhalt. Jetzt deckt sie ab, umbricht bei schmaler Spalte und hebt sich mit Schatten ab. */
/* Speichern und Veroeffentlichen kleben OBEN an der Spalte. Unten standen sie am Ende eines
   Formulars, das bei einer langen Seite ueber 40.000px scrollt — erreichbar nur nach dem Weg nach
   unten. Oben sind sie immer da und zugleich der erste Submit des Formulars (Enter speichert). */
.cms-save { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; position: sticky; top: 0;
    z-index: 3; background: #fff; border: 1px solid var(--ga-line); border-radius: 12px;
    padding: .5rem .55rem; box-shadow: 0 6px 18px rgba(20,33,61,.10); }
/* In der klebenden Leiste zaehlt jede Zeile: kompakte Knoepfe, schmales Terminfeld. Sie traegt bei
   „veroeffentlicht + Aenderungen offen" bis zu vier Aktionen und brach sonst auf vier Zeilen um. */
.cms-save .ga-btn { padding: .34rem .7rem; font-size: .85rem; }
.cms-save .cms-schedule { display: flex; align-items: center; gap: .25rem; }
.cms-save .cms-schedule .cms-input { width: 9.5rem; padding: .25rem .4rem; font-size: .8rem; }
.cms-save__hinweis { margin: .1rem .1rem .2rem; }

/* Vorlagen-Hinweis: Seite trägt Platzhalter ({{…}}), Vorschau zeigt sie unaufgelöst. */
.cms-tmpl-note { background: #fff8e6; border: 1px solid #f0e2b8; border-radius: 10px; padding: .5rem .75rem; margin-bottom: .6rem; }

/* Feld-/Parameter-Chips: klickbar → fügen {{feld}} an der Cursor-Stelle ins zuletzt fokussierte Textfeld ein. */
.cms-chips { display: flex; flex-wrap: wrap; gap: .3rem; margin-top: .45rem; }
.cms-chip { font: inherit; font-size: .74rem; font-weight: 600; color: var(--ga-accent); background: #fff; border: 1px solid var(--ga-accent); border-radius: 999px; padding: .18rem .5rem; cursor: pointer; }
.cms-chip:hover { background: var(--ga-accent-soft, #eef2ff); }
.cms-chip--new { border-style: dashed; color: #555; border-color: #bbb; }
.cms-chip--flash { animation: cms-chip-flash .5s ease; }
@keyframes cms-chip-flash { from { background: var(--ga-accent, #4f46e5); color: #fff; } }

/* Hinzufügen-Leiste: Inhalt (Text/Bild) prominent, Layout (Bereich/Gruppe/Spalten) sekundär. */
.cms-add { display: flex; flex-direction: column; gap: .5rem; margin: .3rem 0 .2rem; }
.cms-add__group { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }
.cms-add__label { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #8a90a2; margin-right: .2rem; }
.cms-add__btn { display: inline-flex; align-items: center; gap: .35rem; font: inherit; font-size: .82rem; font-weight: 600; color: var(--ga-accent); background: #fff; border: 1px solid var(--ga-accent); border-radius: 8px; padding: .3rem .6rem; cursor: pointer; }
.cms-add__btn:hover { background: var(--ga-accent-soft, #eef2ff); }
.cms-add__btn--layout { font-size: .76rem; color: #555; border-color: #ccc; border-style: dashed; padding: .24rem .5rem; }
.cms-add__ico { display: inline-grid; place-items: center; width: 1.15rem; height: 1.15rem; border-radius: 4px; background: var(--ga-accent-soft, #eef2ff); font-size: .72rem; line-height: 1; }
.cms-add__btn--layout .cms-add__ico { background: #eef0f4; }

/* Draft/Publish: Status-Banner im Builder + Badges in der Übersicht. */
.cms-status { border-radius: 10px; padding: .55rem .8rem; font-size: .9rem; margin: .2rem 0 .6rem; }
.cms-status--draft { background: #fff8e6; border: 1px solid #f0e2b8; }
.cms-status--dirty { background: #eef4ff; border: 1px solid #cdddff; }
.cms-status--live  { background: #eef7ee; border: 1px solid #cbe6cf; }
.cms-status--archived { background: #f2f0f0; border: 1px solid #dcd7d7; color: #555; }
.cms-schedule { display: inline-flex; align-items: center; gap: .35rem; }
.cms-schedule input { width: auto; padding: .4rem .5rem; }
.cms-badge { display: inline-block; font-size: .66rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; border-radius: 999px; padding: .1rem .5rem; margin-left: .5rem; vertical-align: middle; }
.cms-badge--draft { background: #f6e6b8; color: #7a5c00; }
.cms-badge--dirty { background: #cdddff; color: #23409a; }
.cms-badge--live  { background: #cbe6cf; color: #1f7a3a; }
.cms-badge--archived { background: #ddd6d6; color: #555; }
.ga-btn--primary { background: var(--ga-accent, #2b59ff); color: #fff; }
.ga-btn--primary:hover { filter: brightness(1.05); }

.cms__preview { display: flex; flex-direction: column; min-height: 0; }
.cms__preview-h { font-weight: 700; color: #4a5266; margin-bottom: .5rem; font-size: .85rem; text-transform: uppercase; letter-spacing: .03em; flex: none; }
.cms__preview-frame { border: 1px solid var(--ga-line); border-radius: 14px; overflow-y: auto; background: #fff; box-shadow: 0 2px 10px rgba(20,33,61,.06); flex: 1; min-height: 0; scroll-behavior: smooth; }

@media (max-width: 1140px) {
    /* Mittel: die linke Spalte wird schmaler, der Editor enger — die Vorschau behaelt Vorrang. */
    .cms__grid { grid-template-columns: var(--cms-col1, 210px) 6px var(--cms-col2, 320px) 6px 1fr; gap: .6rem; }
}
@media (max-width: 900px) {
    /* Schmal: zurueck zum natuerlichen Seitenfluss. Palette und Baum wandern nach oben; beide duerfen
       dann mitwachsen, statt in ihrer eigenen Spalte zu scrollen. */
    .cms__grid { grid-template-columns: 1fr; height: auto; min-height: 0; }
    .cms__griff { display: none; }
    .cms-save { position: static; box-shadow: none; }
    .cms__editor, .cms__preview-frame { overflow-y: visible; }
    .cms__rail { order: -1; }
    .cms__palette, .cms-tree { max-height: none; overflow-y: visible; }
}

/* ── Atomic-Design-Grundbausteine (bos-*) ──────────────────────────────────────────────────
   Generische Atome + Layout-Primitive, aus denen der Nutzer im Page-Builder eigene Bausteine
   (Organisms) zusammensetzt. Bewusst design-neutral (eigene Tokens), damit sie auf JEDER Site
   funktionieren — nicht an das nsite-/ga-Theme gekoppelt. */
.bos-section { --bos-gap-sm: .5rem; --bos-gap-md: 1rem; --bos-gap-lg: 2rem;
    margin: 0 auto; padding: 2.5rem 1.5rem; }
/* Bildbühne: Bild als Hintergrund, Overlay darüber, Inhalt davor. Das Overlay ist ein eigenes
   Element (statt eines Gradienten), weil nur so die Deckkraft je Platzierung steuerbar bleibt. */
.bos-section--image { position: relative; background-size: cover; background-position: center; }
.bos-section--image > .bos-section__overlay { position: absolute; inset: 0; background: #0a1124; }
.bos-section--image > .bos-section__inner { position: relative; }

.bos-section--normal .bos-section__inner { max-width: 1040px; margin: 0 auto; }
.bos-section--wide .bos-section__inner { max-width: 1320px; margin: 0 auto; }
.bos-section--full .bos-section__inner { max-width: none; }

.bos-stack { display: flex; flex-direction: column; gap: 1rem; }
.bos-stack--gap-sm { gap: .5rem; }
.bos-stack--gap-md { gap: 1rem; }
.bos-stack--gap-lg { gap: 2rem; }
.bos-stack--left { align-items: flex-start; text-align: left; }
.bos-stack--center { align-items: center; text-align: center; }
.bos-stack--right { align-items: flex-end; text-align: right; }
.bos-stack--row { flex-direction: row; flex-wrap: wrap; align-items: center; }

/* Schlagwort-Chips (core.list, Stil „pills"): nebeneinander statt untereinander.
   Hier nur das Fluss-Verhalten; das Aussehen der Chips liefert das Site-Theme. */
.bos-list--pills { display: flex; flex-wrap: wrap; gap: .75rem; list-style: none; padding: 0; }
.bos-list--pills > .bos-list__item { display: inline-flex; align-items: center; }

/* Reiter (core.tabs) — Umschalten OHNE JavaScript: verstecktes Radio je Reiter, Label als Chip,
   Auswahl per Geschwister-Selektor. Reihenfolge im Markup: alle Radios, dann Chips, dann Panels —
   nur so erreichen die ~-Selektoren beides. Hier steht die FUNKTION; das Aussehen liefert das
   jeweilige Site-Theme. */
.bos-tabs__radio { position: absolute; opacity: 0; pointer-events: none; }
.bos-tabs__chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.bos-tabs__chip { cursor: pointer; user-select: none; }
.bos-tabs__panel { display: none; }
.bos-tabs__radio:nth-of-type(1):checked ~ .bos-tabs__panels > .bos-tabs__panel:nth-child(1),
.bos-tabs__radio:nth-of-type(2):checked ~ .bos-tabs__panels > .bos-tabs__panel:nth-child(2),
.bos-tabs__radio:nth-of-type(3):checked ~ .bos-tabs__panels > .bos-tabs__panel:nth-child(3),
.bos-tabs__radio:nth-of-type(4):checked ~ .bos-tabs__panels > .bos-tabs__panel:nth-child(4),
.bos-tabs__radio:nth-of-type(5):checked ~ .bos-tabs__panels > .bos-tabs__panel:nth-child(5),
.bos-tabs__radio:nth-of-type(6):checked ~ .bos-tabs__panels > .bos-tabs__panel:nth-child(6) { display: block; }
/* Tastaturbedienung: der Fokus liegt auf dem unsichtbaren Radio — sichtbar wird der ZUGEHÖRIGE Chip. */
.bos-tabs__radio:nth-of-type(1):focus-visible ~ .bos-tabs__chips > .bos-tabs__chip:nth-child(1),
.bos-tabs__radio:nth-of-type(2):focus-visible ~ .bos-tabs__chips > .bos-tabs__chip:nth-child(2),
.bos-tabs__radio:nth-of-type(3):focus-visible ~ .bos-tabs__chips > .bos-tabs__chip:nth-child(3),
.bos-tabs__radio:nth-of-type(4):focus-visible ~ .bos-tabs__chips > .bos-tabs__chip:nth-child(4),
.bos-tabs__radio:nth-of-type(5):focus-visible ~ .bos-tabs__chips > .bos-tabs__chip:nth-child(5),
.bos-tabs__radio:nth-of-type(6):focus-visible ~ .bos-tabs__chips > .bos-tabs__chip:nth-child(6) {
    outline: 2px solid currentColor; outline-offset: 2px;
}

.bos-grid { display: grid; gap: 1rem; grid-template-columns: repeat(3, 1fr); }
.bos-grid--cols-1 { grid-template-columns: 1fr; }
.bos-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
.bos-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
.bos-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
.bos-grid--gap-sm { gap: .5rem; }
.bos-grid--gap-md { gap: 1rem; }
.bos-grid--gap-lg { gap: 2rem; }
/* Mobil einspaltiger stapeln — cols-1 ausnehmen, sonst überstimmt die spätere Regel die Ein-Spalten-Wahl. */
@media (max-width: 720px) { .bos-grid:not(.bos-grid--cols-1) { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .bos-grid { grid-template-columns: 1fr; } }

.bos-text { margin: 0; }
.bos-text--left { text-align: left; }
.bos-text--center { text-align: center; }
.bos-text--right { text-align: right; }
.bos-text--heading { font-size: 1.9rem; font-weight: 700; letter-spacing: -.01em; }
.bos-text--subheading { font-size: 1.3rem; font-weight: 600; }
.bos-text--body { font-size: 1rem; line-height: 1.6; }

/* ─── Lesbarkeit im einspaltigen Fluss ────────────────────────────────────────────────────────
   Fliesstext, der DIREKT im Abschnitt steht, lief ueber die volle Containerbreite — gemessen
   1104px, also rund 130 Zeichen pro Zeile. Ab etwa 75 Zeichen verliert das Auge beim Ruecksprung
   die Zeile; der Leser rutscht in die falsche und liest zweimal.

   Der Kindselektor ist hier entscheidend: In Karten, Spalten und Rastern bestimmt die SPALTE die
   Breite. Eine Begrenzung dort wuerde den Text nur schmaler machen als seine eigene Karte und
   haesslich umbrechen lassen. Betroffen ist ausschliesslich der Fliesstext im offenen Abschnitt. */
.bos-section__inner > .bos-text--body,
.bos-section__inner > .bos-text--lead,
.bos-section__inner > .bos-stack > .bos-text--body { max-width: 68ch; }

/* Zentrierter Text bleibt zentriert — sonst haengt der begrenzte Block ploetzlich links. */
.bos-section__inner > .bos-text--center { margin-left: auto; margin-right: auto; }

/* Aufzaehlungen folgen derselben Breite; ihr Text ist Fliesstext mit Marker davor. */
.bos-section__inner > ul:not([class]),
.bos-section__inner > .bos-list:not(.bos-list--pills) { max-width: 68ch; }

/* Der Rich-Text-Baustein ist auf den Inhaltsseiten der eigentliche Traeger von Fliesstext — seine
   Absaetze kommen aus dem Editor und haben KEINE Klasse, greifen also von keiner Regel oben.
   Gemessen lief er ueber 880px. Begrenzt wird der Baustein selbst, nicht das einzelne <p>: sonst
   hinge eine Ueberschrift darin auf voller Breite und der Absatz darunter waere schmaler. */
.bos-section__inner > .bos-richtext { max-width: 68ch; }
.bos-section__inner > .bos-richtext.bos-text--center { margin-left: auto; margin-right: auto; }

.bos-text--caption { font-size: .85rem; opacity: .7; }
.bos-text--stat-value { font-size: 2.4rem; font-weight: 800; line-height: 1; letter-spacing: -.02em; }
.bos-text--stat-label { font-size: .95rem; opacity: .75; }

/* Namensfeld für „Als Baustein speichern" */
.cms-field--custom code { background: rgba(0,0,0,.06); padding: 0 .25em; border-radius: 3px; }

/* Datenschicht-UI (Inhaltstypen/Inhalte) */
.cms-subnav { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; margin: .5rem 0 1.25rem; }
.cms-field-add { flex-wrap: wrap; gap: .5rem; margin-top: 1rem; align-items: center; }

/* Bild-Atom */
.bos-image { margin: 0; }
.bos-image img { display: block; width: 100%; height: auto; border-radius: 8px; object-fit: cover; }
.bos-image__cap { font-size: .85rem; opacity: .7; margin-top: .35rem; }

/* Formular-Atome (Eingabefeld/Auswahlliste/Radio/Ankreuzfeld) — design-neutral wie die übrigen bos-*. */
/* `align-self: stretch` gegen die Ausrichtung des Stapels: `bos-stack--left` setzt
   `align-items: flex-start`, und damit schrumpft JEDES Kind auf Inhaltsbreite — auch ein
   Eingabefeld. Das `width: 100%` am Feld selbst bezieht sich dann auf diese Inhaltsbreite und
   aendert nichts. Gemessen auf /olympia: Karte 1120px, Feld 191px.

   Die Ausrichtung meint den INHALT (Text linksbuendig), nicht die Breite der Bedienelemente. Ein
   Formularfeld will die verfuegbare Breite; der Absendeknopf ausdruecklich nicht (er behaelt sein
   eigenes `align-self: flex-start` weiter unten). */
.bos-field { display: flex; flex-direction: column; gap: .35rem; margin: 0; border: 0; padding: 0;
    min-inline-size: 0; align-self: stretch; width: 100%; }
.bos-field__label { font-size: .9rem; font-weight: 600; }
.bos-input, .bos-select { font: inherit; padding: .55rem .7rem; border: 1px solid rgba(20,33,61,.25);
    border-radius: 8px; background: #fff; width: 100%; box-sizing: border-box; }
.bos-input:focus, .bos-select:focus { outline: 2px solid var(--ga-accent, #3b5bdb); outline-offset: 1px; }
.bos-radio { gap: .45rem; }
.bos-radio__item { display: flex; align-items: center; gap: .5rem; font-size: .95rem; cursor: pointer; }
.bos-checkbox { flex-direction: row; align-items: flex-start; gap: .55rem; font-size: .95rem; cursor: pointer; }
.bos-checkbox input { margin-top: .2rem; }

/* Formular-Rahmen (core.form) — der Container, der den Feldern das Absenden gibt. */
.bos-form { display: flex; flex-direction: column; gap: .9rem; }
.bos-form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.bos-form__consent { display: flex; align-items: flex-start; gap: .55rem; font-size: .92rem; cursor: pointer; }
.bos-form__submit { font: inherit; font-weight: 600; align-self: flex-start; cursor: pointer;
    padding: .6rem 1.2rem; border: 0; border-radius: 8px; background: var(--ga-accent, #3b5bdb); color: #fff; }
.bos-form__err { color: #b02a37; font-size: .92rem; margin: 0; }
.bos-form--ok p { margin: 0; font-weight: 600; }

/* Einsendung im CMS-Postfach: Freitext aus frei benannten Feldern, Zeilenumbrüche zählen. */
.bos-lead__body { font: inherit; white-space: pre-wrap; margin: 0; max-width: 46ch; }
/* Aktionsspalte des Postfachs: „Oeffnen" und „Loeschen" untereinander statt in eine Zeile gequetscht —
   die Spalte ist die schmalste der Tabelle, nebeneinander bricht der Text mitten im Wort um. */
.bos-lead__ops { display: flex; flex-direction: column; gap: .35rem; align-items: flex-start; }

/* Palette standardmäßig ausgeklappt (Entdeckbarkeit); Pin klappt sie ein → schmale Icon-Leiste (Hover fährt aus). */
    border-radius: 6px; color: var(--ga-accent); font-size: 1.1rem; line-height: 1; user-select: none;
    opacity: 0; transition: opacity .12s ease; }


/* Baustein-Editor: zwei Spalten (Editor | Vorschau), keine Palette-Rail. */
.cms__grid--twocol { grid-template-columns: minmax(320px, 460px) 1fr; }
.cms-atoms { display: flex; flex-direction: column; gap: .8rem; margin: 1rem 0; }
@media (max-width: 900px) { .cms__grid--twocol { grid-template-columns: 1fr; } }

/* ── CMS-/Admin-Chrome ────────────────────────────────────────────────────────────────────
   Eigene Hülle für den Host, unter dem das CMS läuft. Bewusst ruhiger und dunkler als die
   Site-Chromes: Werkzeug, nicht Schaufenster — so ist auf einen Blick klar, ob man gerade
   eine Site ansieht oder sie bearbeitet. */
/* Seitenleiste links, Inhalt rechts — Muster aus dem neoCms-Account-Layout. Mit Dashboard, Sites,
   Kunden und Statistik wurde die frühere Leiste oben zu breit, und die Gliederung ging darin unter. */
/* ── Page-Builder: eigenes Chrome (EditorChrome) ───────────────────────────────────────────────
   Eine Kopfzeile statt der 232px-Seitenleiste. Der Editor ist die einzige Ansicht, die drei Spalten
   nebeneinander zeigt; die globale Navigation kostete davon ein Fuenftel, ohne beim Bearbeiten
   gebraucht zu werden. */
/* Kopfzeile im Editor: eine Zeile statt Ueberschrift + Zurueck-Link. Beides steht im Chrome. */
.cms__head-title { display: flex; align-items: baseline; gap: .5rem; min-width: 0; }
.cms__head-slug { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .82rem;
    color: var(--ga-accent); background: var(--ga-accent-soft, #eef1ff); padding: .1rem .4rem; border-radius: 6px; }
.cms__head-name { font-weight: 600; font-size: .95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Der Status-Hinweis darf schmal sein — er ist eine Zeile Text, kein Banner. */
.cms-status { padding: .35rem .6rem; font-size: .8rem; }

.bos-editor { min-height: 100vh; display: flex; flex-direction: column; background: var(--ga-bg, #f6f8ff); }
.bos-editor__bar {
    display: flex; align-items: center; gap: 1rem; padding: .55rem 1.1rem;
    background: #14213d; color: #fff; flex-shrink: 0;
}
.bos-editor__back { color: rgba(255,255,255,.82); text-decoration: none; font-size: .86rem; font-weight: 600; }
.bos-editor__back:hover { color: #fff; }
.bos-editor__brand { color: #fff; text-decoration: none; font-weight: 700; font-size: .95rem; letter-spacing: -.01em; }
.bos-editor__brand span { font-weight: 500; opacity: .6; margin-left: .3rem; }
.bos-editor__right { margin-left: auto; display: flex; align-items: center; gap: .8rem; }
.bos-editor__user { font-size: .82rem; color: rgba(255,255,255,.7); }
.bos-editor__account { font-size: .82rem; color: rgba(255,255,255,.85); text-decoration: none; }
.bos-editor__account:hover { color: #fff; }
/* Der Editor bekommt die volle Breite; nur ein schmaler Rand bleibt. Die Grundschrift ist hier
   kleiner als im uebrigen CMS (14px statt 16px) — in drei Spalten zaehlt jede Zeile. */
.bos-editor__main { flex: 1; min-height: 0; padding: .9rem 1.1rem 1.2rem; font-size: 14px; }

.bos-admin { min-height: 100vh; display: flex; background: var(--ga-bg, #f6f8ff); }

.bos-admin__side { width: 232px; flex-shrink: 0; display: flex; flex-direction: column; gap: 1.4rem;
    padding: 1.1rem 1rem; background: var(--ga-ink, #041c2c); color: #fff;
    position: sticky; top: 0; height: 100vh; overflow-y: auto; }

.bos-admin__brand { font-weight: 700; font-size: 1rem; color: #fff; text-decoration: none; letter-spacing: -.01em; }
.bos-admin__brand span { font-weight: 500; opacity: .6; margin-left: .3rem; }

.bos-admin__group { display: block; font-size: .66rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .06em; color: rgba(255,255,255,.35); margin: .9rem 0 .35rem; }
.bos-admin__group:first-child { margin-top: 0; }

.bos-admin__nav { display: flex; flex-direction: column; gap: .12rem; }
.bos-admin__nav a { color: rgba(255,255,255,.72); text-decoration: none; font-size: .9rem; font-weight: 500;
    padding: .4rem .65rem; border-radius: 7px; }
.bos-admin__nav a:hover { color: #fff; background: rgba(255,255,255,.09); }
.bos-admin__nav a.is-active { color: #fff; background: rgba(255,255,255,.16); }

/* Die verwalteten Sites: Ausgänge auf ihre eigenen Hosts, kein Navigationspunkt des CMS. */
.bos-admin__sites { margin-top: auto; display: flex; flex-direction: column; gap: .3rem; }
.bos-admin__site { font-size: .82rem; color: rgba(255,255,255,.8); text-decoration: none;
    border: 1px solid rgba(255,255,255,.22); border-radius: 999px; padding: .25rem .7rem; white-space: nowrap; }
.bos-admin__site:hover { color: #fff; border-color: rgba(255,255,255,.5); background: rgba(255,255,255,.08); }

.bos-admin__body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.bos-admin__bar { display: flex; align-items: center; justify-content: flex-end; gap: 1.1rem;
    padding: .6rem 1.4rem; border-bottom: 1px solid var(--ga-line, #e6e9f2); background: #fff; }
.bos-admin__user { font-size: .88rem; color: #5a6478; }
.bos-admin__account { font-size: .88rem; color: var(--ga-accent, #4b5bdc); text-decoration: none; }
.bos-admin__account:hover { text-decoration: underline; }

.bos-admin__main { flex: 1; padding: 1.6rem 0 3rem; }

/* Kennzahl-Kacheln des Dashboards */
.bos-dash { max-width: 1100px; margin: 0 auto; padding: 0 1.4rem; }
.bos-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin: 1.2rem 0 2.4rem; }
.bos-tile { display: block; background: #fff; border: 1px solid var(--ga-line, #e6e9f2); border-radius: 12px;
    padding: 1.1rem 1.2rem; text-decoration: none; color: inherit; transition: border-color .15s, transform .15s; }
.bos-tile:hover { border-color: var(--ga-accent, #4b5bdc); transform: translateY(-1px); }
.bos-tile__n { display: block; font-size: 2rem; font-weight: 800; line-height: 1; color: var(--ga-ink, #041c2c); }
.bos-tile__l { display: block; margin-top: .45rem; font-weight: 600; font-size: .95rem; }
.bos-tile__s { display: block; margin-top: .3rem; font-size: .8rem; color: #6b7280; }

/* Statistik */
.bos-stats__head { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
.bos-stats__pick { margin-left: auto; }
.bos-stats__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem; }
.bos-stats__num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

.bos-chart { width: 100%; height: auto; overflow: visible; }
.bos-chart polyline { fill: none; stroke-width: 2; vector-effect: non-scaling-stroke;
    stroke-linejoin: round; stroke-linecap: round; }
.bos-chart__views { stroke: var(--ga-accent, #4b5bdc); }
.bos-chart__visitors { stroke: #00b894; stroke-dasharray: 4 3; }
.bos-chart__engaged { stroke: #d9822b; stroke-dasharray: 1 3; }
.bos-chart__key { display: inline-block; width: 14px; height: 3px; border-radius: 2px; vertical-align: middle; }
.bos-chart__key--views { background: var(--ga-accent, #4b5bdc); }
.bos-chart__key--visitors { background: #00b894; }
.bos-chart__key--engaged { background: #d9822b; }
/* Interessierte sind die Teilmenge, die zählt — farblich abgesetzt, damit die Kachel drei Ebenen zeigt. */
.bos-tile__s--engaged { color: #d9822b; font-weight: 600; }

@media (max-width: 860px) {
    .bos-admin { flex-direction: column; }
    .bos-admin__side { width: auto; height: auto; position: static; }
    .bos-admin__nav { flex-direction: row; flex-wrap: wrap; }
    .bos-admin__sites { display: none; }
}

/* GA-Navigation: sichtbare Trennung zwischen Gast- und Vermieter-Bereich. */
.ga-nav__sep { width: 1px; align-self: stretch; margin: .15rem .5rem; background: var(--ga-line, #e6e9f2); }
.ga-nav__group-label { font-size: .66rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: #9aa2b5; margin-right: .1rem; }
@media (max-width: 720px) { .ga-nav__sep, .ga-nav__group-label { display: none; } }

/* ─────────────────────────────────────────────────────────────────────────────────────────────
   CMS-Oberflaeche: Typografie und Seitenaufbau

   Alles hier ist auf `.bos-admin` eingegrenzt. Die oeffentlichen Seiten und das GA-Produkt teilen
   sich zwar die `ga-*`-Atome, sollen aber von einer Aufraeumaktion in der Verwaltung NICHT betroffen
   sein — sonst aendert eine Korrektur an der Kundenliste nebenbei das Aussehen einer Kunden-Website.

   Behoben werden drei gemessene Fehler:

   1. KAPUTTE HIERARCHIE. `h1` und `h2` trugen dieselbe Klasse `ga-head`; gemessen kam heraus:
      h1 = 40px bei Schriftschnitt 300, h2 = 32px bei 500. Der Abschnittstitel war also FETTER als
      der Seitentitel und wirkte dominanter — auf /cms/mail sah „Absender" wichtiger aus als „E-Mail".
   2. ZEILENLAENGE. Erklaerabsaetze liefen ueber 987px. Lesbar sind rund 60–75 Zeichen; darueber
      verliert das Auge beim Ruecksprung die Zeile.
   3. ZWEI CONTAINER. Acht Seiten nutzten `bos-dash` (1100px), fuenf `ga-container ga-detail`
      (980px, anderes Innenmass) — sichtbar als Sprung in Breite und Randabstand beim Wechsel.
   ───────────────────────────────────────────────────────────────────────────────────────────── */

/* Ein Container fuer die ganze Verwaltung. `ga-detail` wird hier neutralisiert, damit die fuenf
   Seiten, die es noch tragen, nicht schmaler laufen als der Rest. */
.bos-admin .bos-dash,
.bos-admin .ga-container { max-width: 1100px; margin: 0 auto; padding: 0 1.4rem; }
.bos-admin .ga-detail { max-width: 1100px; }

/* Seitentitel. 300 war bei dieser Groesse zu duenn — auf hellem Grund franst der Zug aus. */
.bos-admin h1.ga-head {
    font-size: clamp(1.7rem, 2.4vw, 2.1rem);
    font-weight: 500;
    letter-spacing: -.015em;
    margin: 0 0 .2rem;
}

/* Abschnittstitel INNERHALB einer Karte: deutlich kleiner als der Seitentitel, dafuer fester.
   Der Unterschied traegt die Hierarchie, nicht die Groesse allein. */
.bos-admin h2.ga-head {
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: .005em;
    margin: 0 0 .15rem;
}

/* Ein `h2` auf SEITENEBENE (Dashboard: „Sites") gliedert die Seite, nicht den Inhalt einer Karte —
   es steht eine Stufe hoeher und darf das auch zeigen. Ohne diese Unterscheidung war die
   Abschnittsueberschrift genauso gross wie die Beschriftung einer Karte darunter. */
.bos-admin .bos-dash > h2.ga-head,
.bos-admin .ga-container > h2.ga-head {
    font-size: 1.3rem;
    font-weight: 600;
    margin: 1.9rem 0 .7rem;
}

/* Kartenkopf mit Metadaten: Name und Kennzahlen standen in EINER Zeile in derselben Groesse und
   lasen sich als fortlaufender Satz — „Global Appartements 2 Seiten Start /property". Jetzt traegt
   die zweite Zeile die Zahlen, sichtbar untergeordnet. */
.bos-admin .cms-site-h { display: flex; flex-direction: column; gap: .15rem; align-items: flex-start; }
.bos-admin .cms-site-h > span.ga-muted { font-size: .82rem; font-weight: 400; letter-spacing: 0; }

/* Domain-Tabellen fluchten spaltenweise. Vorher richtete `auto`-Layout jede Karte nach IHREN
   Inhalten aus: bei „global-appartements.de" sass die Spalte „Art" 37px weiter rechts als bei
   „neotec.hamburg". Zwei Tabellen mit gleicher Bedeutung sollen gleich aussehen.

   EIGENE Klasse statt `.ga-panel > .ga-leads`: der erste Versuch traf auch die Kundenliste, die
   fuenf Spalten hat — dort presste die 34%-Vorgabe die Domain auf zwei Zeilen
   („global-appartements.d / e"). Feste Spaltenmasse gelten nur fuer die Tabelle, fuer die sie
   gedacht sind. */
.bos-admin .cms-domains { table-layout: fixed; width: 100%; }
.bos-admin .cms-domains th:nth-child(1) { width: 34%; }
.bos-admin .cms-domains th:nth-child(2) { width: 20%; }
.bos-admin .cms-domains th:nth-child(3) { width: 14%; }
.bos-admin .cms-domains td:first-child { overflow-wrap: anywhere; }

/* Was HINZUFUEGT oder EINSTELLT, gehoert sichtbar unter die Liste — nicht als weitere Zeile in sie
   hinein. Die Eingabezeile stand direkt unter der letzten Datenzeile und las sich wie ein Datensatz. */
/* `:not(:first-child)`, weil das Formular auf /cms/medien das ERSTE Element der Karte ist — dort
   trennte die Linie nichts ab und stand einfach als Strich ueber dem Inhalt. */
.bos-admin .ga-panel > form.ga-objekte__new:not(:first-child) {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--ga-line, #e6e9f2);
}
.bos-admin .cms-startpfad { margin-top: .9rem; display: flex; align-items: flex-end; gap: .5rem; flex-wrap: wrap; }
.bos-admin .cms-startpfad label { display: flex; flex-direction: column; gap: .25rem;
    font-size: .82rem; font-weight: 600; color: #4a5266; }
.bos-admin .cms-startpfad select { min-width: 14rem; }

/* Aufklapper. `<details>` bringt ohne Zutun ein schwarzes Dreieck und keinerlei Abstand mit — die
   beiden Zeilen „Kopf & Fuss" und „Farben" sahen aus wie vergessene Debug-Ausgaben. */
.bos-admin .ga-panel > details { margin-top: .55rem; border-top: 1px solid var(--ga-line, #e6e9f2); padding-top: .55rem; }
.bos-admin .ga-panel > details + details { margin-top: 0; }
.bos-admin .ga-panel > details > summary {
    cursor: pointer;
    font-size: .88rem;
    font-weight: 500;
    color: #4a5266;
    padding: .3rem .15rem;
    border-radius: 6px;
    list-style: none;
}
.bos-admin .ga-panel > details > summary::-webkit-details-marker { display: none; }
.bos-admin .ga-panel > details > summary::before {
    content: "›";
    display: inline-block;
    width: 1rem;
    color: #9aa2b5;
    transition: transform .15s;
}
.bos-admin .ga-panel > details[open] > summary::before { transform: rotate(90deg); }
.bos-admin .ga-panel > details > summary:hover { background: var(--ga-accent-soft, #eef1ff); color: #394052; }

/* Luft zwischen Abschnittstitel und erstem Feld. Ohne sie klebte „Absender" direkt auf
   „Absenderadresse" — zwei Zeilen, die zusammengehoeren sollen, aber nicht dieselbe Ebene sind. */
.bos-admin .ga-panel > h2.ga-head { margin-bottom: .9rem; }
.bos-admin .ga-panel > h2.ga-head + p.ga-muted { margin-top: -.6rem; }

/* Erklaertexte INNERHALB einer Karte brauchen dieselbe Lesebreite wie die auf Seitenebene. */
.bos-admin .ga-panel > p.ga-muted { max-width: 68ch; line-height: 1.55; }

/* Kurze Werte bekommen kurze Felder. Ein Port hat vier Ziffern und stand in einem 800px breiten
   Kasten — das Feld versprach eine Eingabe, die es gar nicht gibt, und machte das Formular
   schwerer zu ueberfliegen. */
.bos-admin input[type="number"] { max-width: 9rem; }
.bos-admin input[inputmode="numeric"] { max-width: 9rem; }

/* Erklaertext unter dem Titel: auf Lesebreite begrenzt und leiser als der Inhalt, den er erklaert.
   `ch` statt `px`, damit die Grenze der Schrift folgt und nicht einer geratenen Pixelzahl. */
/* Die Erklaerabsaetze tragen bereits einheitlich `ga-muted` und stehen als DIREKTES Kind des
   Containers — deshalb greift eine Regel statt dreizehn Dateiaenderungen. Der Kindselektor ist hier
   wesentlich: dieselbe Klasse traegt auch Kleingedrucktes IN Karten und Tabellen, das keine
   Lesebreite braucht und durch eine Begrenzung nur umbrechen wuerde. */
.bos-admin .bos-dash > p.ga-muted,
.bos-admin .ga-container > p.ga-muted,
.bos-admin .bos-lead {
    max-width: 68ch;
    color: #5b6377;
    line-height: 1.55;
    margin: 0 0 1.4rem;
}
.bos-admin .bos-lead:last-child { margin-bottom: 0; }
.bos-admin .bos-lead strong { color: #394052; font-weight: 600; }

/* Seitenkopf: Titel links, Aktion (Auswahl, Knopf) rechts — auf JEDER Seite gleich aufgebaut.
   Vorher stand die Aktion mal daneben, mal darunter, mal in einer Reihe mit dem Titel. */
.bos-admin .bos-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 0 0 .35rem;
}
.bos-admin .bos-head__actions { display: flex; align-items: center; gap: .5rem; }

/* Leerer Zustand. Vorher: grauer Satz in einer Karte, der wie ein Fehler aussah. Jetzt eine
   erkennbare Flaeche, die sagt, was als Naechstes zu tun ist. Die Seiten nutzen bereits einheitlich
   `ga-empty` — deshalb greift auch hier eine Regel statt acht Dateiaenderungen. */
.bos-admin .ga-empty,
.bos-admin .bos-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .5rem;
    text-align: center;
    padding: 2.6rem 1.5rem;
    border: 1px dashed #d2d8e6;
    border-radius: 14px;
    background: #fbfcff;
    color: #5b6377;
}
.bos-admin .bos-empty__title { font-weight: 600; color: #394052; font-size: 1rem; }
.bos-admin .ga-empty p,
.bos-admin .bos-empty p { margin: 0; max-width: 52ch; line-height: 1.5; }
/* Der Satz im leeren Zustand nennt oft den naechsten Schritt und verlinkt ihn — der Link soll
   sichtbar sein, nicht in derselben grauen Farbe untergehen wie der Hinweis. */
.bos-admin .ga-empty a { color: var(--ga-accent, #627afe); font-weight: 500; }

/* Datei-Auswahl. Der Browser-Default (grauer Knopf + „Keine ausgewaehlt") brach als einziges
   Bedienelement der Oberflaeche komplett aus dem Erscheinungsbild aus. */
.bos-admin input[type="file"] {
    font: inherit;
    font-size: .92rem;
    color: #5b6377;
    width: 100%;
}
.bos-admin input[type="file"]::file-selector-button {
    font: inherit;
    font-size: .9rem;
    font-weight: 500;
    margin-right: .75rem;
    padding: .45rem .9rem;
    border: 1px solid var(--ga-line, #e6e9f2);
    border-radius: 8px;
    background: #fff;
    color: #394052;
    cursor: pointer;
    transition: background .12s, border-color .12s;
}
.bos-admin input[type="file"]::file-selector-button:hover {
    background: var(--ga-accent-soft, #eef1ff);
    border-color: var(--ga-accent, #627afe);
}

/* Technische Kennungen (UUIDs). Sie muessen kopierbar bleiben, sollen aber keine Tabellenspalte
   sprengen — 36 Zeichen Monospace waren breiter als der Kundenname daneben. */
.bos-admin .bos-id {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .75rem;
    color: #7b8398;
    display: inline-block;
    max-width: 14ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

/* ── Dauerhafter Hinweis je Site (SiteBadge) ────────────────────────────────────────────────
   Klebt in einer unteren Ecke und ist auf jeder Seite der Site da. Bewusst NICHT nach `.site-data`
   oder `.site-neotec` gescopt: Die Komponente haengt in ALLEN drei Chromes, also auch im GA-Chrome.

   Die Farben kommen ueber eine Kette, weil die drei Chromes drei Token-Saetze fuehren: `--brand`
   setzt das Theme einer Kunden-Site (und `.site-neotec` fest), `--ns-*` gilt innerhalb von
   `.nsite-app`, `--ga-*` innerhalb von `.ga-app`. Ohne die Kette faerbte sich der Hinweis auf genau
   einer der drei Site-Arten richtig. */
.bos-badge {
    position: fixed; z-index: 60;   /* ueber dem klebenden Kopf (z-index 50) */
    bottom: 1rem; right: 1rem;
    max-width: 22rem;
}

.bos-badge--links { left: 1rem; right: auto; }

.bos-badge__box {
    display: flex; align-items: center; gap: .75rem;
    padding: .7rem .9rem;
    background: #fff;
    border: 1px solid var(--line, var(--ns-line, var(--ga-line, #e4e8f2)));
    border-radius: var(--radius-card, 14px);
    box-shadow: 0 6px 24px rgb(10 17 36 / .14);
    color: var(--ink, var(--ns-ink, var(--ga-ink, #14213d)));
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

/* Nur die verlinkte Fassung reagiert — ein Aushang ohne Ziel soll nicht so tun, als waere er ein Knopf. */
a.bos-badge__box:hover {
    border-color: var(--brand, var(--ns-accent, var(--ga-accent, #2b59ff)));
    box-shadow: 0 10px 30px rgb(10 17 36 / .18);
    transform: translateY(-1px);
}

a.bos-badge__box:focus-visible {
    outline: 2px solid var(--brand, var(--ns-accent, var(--ga-accent, #2b59ff)));
    outline-offset: 2px;
}

.bos-badge__img {
    flex: 0 0 auto; width: 48px; height: 48px;
    object-fit: contain; border-radius: 8px;
}

.bos-badge__text { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.bos-badge__title { font-weight: 600; font-size: .95rem; line-height: 1.25; }
.bos-badge__desc { font-size: .82rem; line-height: 1.35; color: var(--muted, #6b7280); }

/* Auf dem Telefon bleibt die Ecke, aber der Hinweis darf nie breiter werden als der Schirm. */
@media (max-width: 640px) {
    .bos-badge { bottom: .6rem; right: .6rem; max-width: calc(100vw - 1.2rem); }
    .bos-badge--links { left: .6rem; right: auto; }
    .bos-badge__box { padding: .55rem .7rem; gap: .6rem; }
    .bos-badge__img { width: 40px; height: 40px; }
    .bos-badge__desc { font-size: .78rem; }
}

@media (prefers-reduced-motion: reduce) {
    .bos-badge__box { transition: none; }
    a.bos-badge__box:hover { transform: none; }
}

/* Auf Papier ist nichts „immer sichtbar" — dort verdeckt er nur Inhalt. */
@media print { .bos-badge { display: none; } }

/* ── Formulare in den Site-Einstellungen (Kopf/Fuss, Farben, Hinweis, Profil) ───────────────
   Diese Klassen wurden benutzt, aber nie gestylt: Das Formular war ein `display: block`, die
   <label> darin also INLINE — die Felder flossen nebeneinander wie Text, und `__wide` tat gar
   nichts. Bei kurzen Eingabefeldern fiel das kaum auf; ein Textbereich neben einem Namensfeld
   macht es unuebersehbar. */
.cms-chrome__form {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: .75rem 1rem;
    align-items: start;
    margin-top: .75rem;
}

.cms-chrome__form > label {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    font-size: .9rem;
}

/* Was die ganze Breite braucht: Textbereiche, Feldgruppen, Hinweissaetze — und der Knopf, damit
   er nicht als schmale Spalte neben dem letzten Feld landet. */
.cms-chrome__wide,
.cms-chrome__form > button { grid-column: 1 / -1; }
.cms-chrome__form > button { justify-self: start; }

/* ── Unternehmensprofil: mehrwertige Angaben als einzelne Felder ────────────────────────────
   Je Eintrag ein Feld statt einer Zeile in einem Textbereich. Die Felder heissen alle gleich;
   die Reihenfolge im Formular ist die Reihenfolge der Werte. */
.cms-felder,
.cms-zeiten {
    border: 1px solid var(--ga-line, #e6e9f2);
    border-radius: 10px;
    padding: .75rem .9rem 1rem;
    margin: 0;
}

.cms-felder > legend,
.cms-zeiten > legend { padding: 0 .35rem; font-weight: 600; font-size: .9rem; }

.cms-felder { display: flex; flex-direction: column; gap: .4rem; }

.cms-zeiten__zeile {
    display: grid;
    /* Feste Spalten statt 1fr: Mit 1fr waeren die Spalten so breit wie das Formular (gemessen:
       451px), das Zeitfeld darin aber nur 11rem — zwischen „von" und „bis" klaffte dann eine
       Luecke von ueber 270px. Feste Breiten halten die Zeile zusammen und lassen die sieben Tage
       trotzdem untereinander fluchten. */
    grid-template-columns: 2.5rem 10rem auto 10rem;
    justify-content: start;
    align-items: center;
    gap: .4rem;
    margin-bottom: .35rem;
}

.cms-zeiten__tag { font-weight: 600; font-size: .9rem; }
.cms-zeiten__bis { font-size: .85rem; opacity: .7; }

@media (max-width: 560px) {
    /* Auf dem Telefon teilen sich die beiden Zeitfelder den Platz, statt ihn fest zu belegen. */
    .cms-zeiten__zeile { grid-template-columns: 2.2rem 1fr auto 1fr; gap: .25rem; }
}

/* ── Medienliste im CMS ─────────────────────────────────────────────────────────────────────
   Vorschau links, Name und Adresse rechts. Vorher zeigte die Seite nur die zuletzt hochgeladene
   Datei; die Liste ist der Unterschied zwischen einem Briefkasten und einer Ablage. */
.cms-medien__liste { list-style: none; margin: .75rem 0 0; padding: 0; display: grid; gap: .5rem; }

.cms-medien__eintrag {
    display: grid;
    /* Feste Vorschauspalte, damit Name und Adresse aller Zeilen fluchten — mit `auto` richtete sie
       sich nach dem breitesten Bild und die Liste wackelte. Dritte Spalte: „Entfernen", rechts. */
    grid-template-columns: 72px 1fr auto;
    gap: .75rem;
    align-items: center;
    padding: .5rem;
    border: 1px solid var(--ga-line, #e6e9f2);
    border-radius: 10px;
}

.cms-medien__thumb {
    width: 72px; height: 72px;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden; border-radius: 8px;
    background: var(--ga-bg-alt, #f6f7fb);
}

/* `contain` statt `cover`: Ein Logo darf nicht angeschnitten werden — man soll erkennen, WELCHE
   Datei das ist, nicht ein huebsches Kachelbild sehen.

   width/height statt nur max-*: Mit bloss max-* hat ein noch NICHT geladenes Bild keine eigene
   Groesse und wird 0x0 dargestellt. Zusammen mit loading="lazy" ist das eine Sackgasse — ein
   Element ohne Flaeche kommt nie „in die Naehe des Sichtbereichs", der Browser laedt es also nie,
   und weil es nie laedt, bekommt es auch nie eine Groesse. Gemessen: Rahmen 72x72, Bild 0x0. */
.cms-medien__thumb img { width: 100%; height: 100%; object-fit: contain; }
.cms-medien__thumb--datei { font-weight: 600; font-size: .8rem; text-decoration: none; }

.cms-medien__daten { min-width: 0; display: flex; flex-direction: column; gap: .25rem; }
.cms-medien__name { font-size: .9rem; overflow-wrap: anywhere; }
.cms-medien__url { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .8rem; }

/* Der Loeschknopf steht oben rechts, nicht mittig: Sonst waenderte er mit der Hoehe der Zeile und
   traefe bei einem langen Dateinamen woanders als bei einem kurzen. */
.cms-medien__eintrag > form { align-self: start; }

@media (max-width: 560px) {
    .cms-medien__eintrag { grid-template-columns: 56px 1fr auto; }
    .cms-medien__thumb { width: 56px; height: 56px; }
}

/* ── Seitenbaum: verschieben ────────────────────────────────────────────────────────────────
   Der Baum ist der bessere Ort zum Verschieben — Quelle und Ziel stehen zwei Zeilen auseinander,
   nicht tausend Pixel Formular. */
.cms-tree__item { cursor: grab; }
.cms-tree__item.is-dragging { opacity: .45; cursor: grabbing; }

/* Der leere Slot braucht eine Flaeche, sonst gibt es nichts, worauf man ablegen koennte —
   und genau das will man bei einer frisch angelegten Gruppe. */
.cms-tree__leerslot {
    list-style: none;
    padding: .2rem .45rem .2rem 1.6rem;
    font-size: .72rem;
    opacity: .45;
    font-style: italic;
}

.cms-tree__slot {
    font-size: .68rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    opacity: .55;
    padding: .3rem .45rem .1rem;
}

/* Waehrend eines Zugs bekommt jede Liste eine schwache Kante — sonst raet man, wo das Ziel endet. */
.cms-tree__list { list-style: none; margin: 0; padding: 0; }
.cms-tree:has(.is-dragging) .cms-tree__list {
    outline: 1px dashed rgb(128 128 128 / .35);
    outline-offset: -1px;
    border-radius: 6px;
}

/* ── Passwortgeschützte Seite ───────────────────────────────────────────────────────────────
   Die Sperrseite ist absichtlich karg: Sie soll nichts über den Inhalt verraten, den sie verdeckt. */
.bos-schloss { max-width: 30rem; }
.bos-schloss__form { display: flex; flex-direction: column; gap: .75rem; margin-top: 1rem; align-items: flex-start; }
.bos-schloss__form .bos-field { width: 100%; }
.bos-schloss__fehler { color: #b42318; font-weight: 600; margin: .75rem 0 0; }

/* Der Schalter im CMS. `open` steht nur, wenn ein Schutz gesetzt ist — dann ist es die
   Information, die man sucht; sonst wäre es ein aufgeklappter Kasten ohne Inhalt. */
.cms-schutz > summary { cursor: pointer; }
.cms-schutz--an { color: #1f6b4e; }
.cms-schutz__weg { display: flex; align-items: center; gap: .4rem; font-size: .9rem; margin-top: .4rem; }
